Задать вопрос
TechnoDis
@TechnoDis
Знаю всё и ничего.

Почему проект с JavaFx не запускается на другом компьютере?

Пытаюсь собрать проект на 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 не экспортирует важный класс - это баг?
Уже третий день чиню, хотелось бы хоть как-то сдвинуться.
  • Вопрос задан
  • 163 просмотра
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы