Пытаюсь собрать проект на javafx в файл jar. У меня все работает, но на другом компьютере валится при старте.
Чего я только не перепробовал, постоянно получаю один и тот-же эксепшн:
эксепшн
javafx.fxml.LoadException:
file:/home/username/Documents/MyProject-0.8.jar!/fxml/nodes/integerIncDec.fxml:16
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707)
at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1025)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:756)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2517)
at com.mhprojects.attendancerecord.view.nodes.IntegerIncDecNode.<init>(IntegerIncDecNode.java:43)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350)
at java.base/java.lang.Class.newInstance(Class.java:645)
at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1021)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:756)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2517)
at com.myprojects.myproject.view.ViewUtils.setFxmlToRoot(ViewUtils.java:55)
at com.myprojects.myproject.view.nodes.SetDateNode.<init>(SetDateNode.java:44)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350)
at java.base/java.lang.Class.newInstance(Class.java:645)
at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1021)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:756)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2532)
at com.mhprojects.attendancerecord.view.SceneView.load(SceneView.java:22)
at com.mhprojects.attendancerecord.view.SceneView.<init>(SceneView.java:15)
at com.mhprojects.attendancerecord.view.ViewManager.<init>(ViewManager.java:23)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:802)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.IllegalAccessException: class javafx.fxml.FXMLLoader$InstanceDeclarationElement (in module javafx.fxml) cannot access class com.sun.javafx.scene.control.IntegerField (in module javafx.controls) because module javafx.controls does not export com.sun.javafx.scene.control to module javafx.fxml
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:693)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:490)
at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350)
at java.base/java.lang.Class.newInstance(Class.java:645)
at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1021)
... 50 more
В интернете нашел, что нужно добавить --add-exports к VM Options. Но у меня gradle, поэтому пути неоднозначные. Я накодил в build.gradle вот это:
build.gradle
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.9'
}
group 'org.myprojects'
version '0.8'
mainClassName = 'com.myprojects.myproject.Main'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
implementation 'org.postgresql:postgresql:42.2.18'
}
test {
useJUnitPlatform()
}
application {
mainModule.set 'com.myprojects.myproject'
mainClass.set 'com.myprojects.myproject.Main'
}
jar {
manifest {
attributes 'Main-Class': 'com.myprojects.myproject.Main'
}
from {
// from странный, да, но я и стандартный пробовал, и проверку на линукс и на не линукс делал
configurations.runtimeClasspath.filter {
if (it.name.endsWith(".jar") && it.name.contains("javafx") && !it.name.contains("linux"))
return false
return true
}.collect { it.isDirectory() ? it : zipTree(it) }
}
}
javafx {
version = "16" // сперва стояла 15, тоже не работала.
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
class PathBuilder {
StringBuilder paths = new StringBuilder()
StringBuilder modules = new StringBuilder()
}
PathBuilder getJarPaths() {
PathBuilder pathBuilder = new PathBuilder()
configurations.runtimeClasspath
.each {
String path = it.getAbsolutePath()
println path
// в этом условии я много чего перепробовал. Узнать бы какой именно файл выбирать надо.
if (path.contains("javafx") && path.contains("linux")) {
if (pathBuilder.paths.size() != 0) {
pathBuilder.paths.append(':')
pathBuilder.modules.append(',')
}
pathBuilder.paths.append(it.getParent())
String[] moduleParts = it.getName().split("-")
pathBuilder.modules.append(moduleParts[0] + "." + moduleParts[1])
}
}
return pathBuilder
}
tasks.withType(JavaCompile) {
PathBuilder pathBuilder = getJarPaths()
String paths = pathBuilder.paths.toString()
String modules = pathBuilder.modules.toString()
println "path: " + paths
println "modules: " + modules
options.compilerArgs += [
"--module-path",
paths,
"--add-modules",
modules,
"--add-exports",
"javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED,javafx.fxml",
]
println options.compilerArgs.join(" ")
}
За последние 3 дня я попробовал столько самого разного, сходу все и не вспомню. У меня java 15, на другом компе тоже java 15.
Я и с module-info.java пробовал, и без него (тогда вместо ALL-UNNAMED надо написать название модуля, я знаю, но и ALL-UNNAMED я оставлял). С module-info.java еще и файлы properties отваливаются. Тоже непонятно почему.
Мне кажется, или факт того, что javafx не экспортирует важный класс - это баг?
Уже третий день чиню, хотелось бы хоть как-то сдвинуться.