T
T
TechnoDis2021-04-14 12:44:38
Java
TechnoDis, 2021-04-14 12:44:38

Why doesn't a project with JavaFx run on another machine?

I'm trying to build a javafx project into a jar file. Everything works for me, but on another computer it crashes at startup.
What I just did not try, I constantly get the same exception:

pickup

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



I found on the Internet that you need to add --add-exports to VM Options. But I have gradle so the paths are ambiguous. I coded this in 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(" ")
}



Over the past 3 days, I tried so many different things, I can’t remember everything right off the bat. I have java 15, on another computer, too, java 15.

I tried with module-info.java, and without it (then instead of ALL-UNNAMED you need to write the name of the module, I know, but I also left ALL-UNNAMED). With module-info.java, the properties files also fall off. It's also not clear why.

Is it just me, or is the fact that javafx doesn't export an important class a bug?
I've been fixing it for the third day, I would like to somehow move.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question