简体   繁体   English

在 linux - java.lang.ClassNotFoundException 上进行干净部署:javafx.fxml.FXMLLoader

[英]clean deployment on linux - java.lang.ClassNotFoundException: javafx.fxml.FXMLLoader

I have a Java (JavaFX) application that has been built using Gradle on Laptop A. When I deploy it to Laptop B it fails to run throwing the following Exception:我有一个 Java (JavaFX) 应用程序,它是在笔记本电脑 A 上使用 Gradle 构建的。当我将它部署到笔记本电脑 B 时,它无法运行并抛出以下异常:

Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NoClassDefFoundError: javafx/fxml/FXMLLoader
    at main.Main.start(Main.java:85)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: javafx.fxml.FXMLLoader
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    ... 10 more

I used the gradle pluggin to build an executable jar.我使用 gradle 插件构建了一个可执行的 jar。 It also built a zip and tar file.它还构建了一个 zip 和 tar 文件。 The zip (and tar) file contains a bin directory with a script to run the application and a lib directory containing loads of jar files. zip(和 tar)文件包含一个带有运行应用程序的脚本的 bin 目录和一个包含大量 jar 文件的 lib 目录。

I had a previous issue我有一个以前的问题

Error: JavaFX runtime components are missing, and are required to run this application

I found a solution here:我在这里找到了解决方案:

Maven Shade JavaFX runtime components are missing 缺少 Maven 灯罩 JavaFX 运行时组件

I created a wrapper class with a main (non javafx) that calls the main (javafx).我创建了一个包装器 class ,其中有一个调用主程序(javafx)的主程序(非 javafx)。

My current problem:我目前的问题:

Clean install of Linux Mint - 19.3 Cinnamon Kernal - 5.3.0-53-generic干净安装 Linux Mint - 19.3 Cinnamon Kernal - 5.3.0-53-generic

gradle-6.0.1 gradle-6.0.1

Java version - Java版-

openjdk 11.0.7 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu218.04)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-2ubuntu218.04, mixed mode, sharing)

If I use the script from the (exploded) zip file:如果我使用(分解的)zip 文件中的脚本:

./MyApp/bin/MyApp config.json

Or just execute the app:或者只是执行应用程序:

java -jar MyApp.jar config.json

These both fail这两个都失败了

Using the ZIP file content I explored the jar files gradle deployed.使用 ZIP 文件内容,我探索了 jar 文件 gradle 部署。

MyApp.jar
* javafx-graphics-11.jar
* javafx-base-11.jar
javafx-controls-11-linux.jar 
javafx-graphics-11-linux.jar
javafx-base-11-linux.jar
joda-time-2.10.5.jar

The '*' files are proxies and only contain a MANIFEST. '*' 文件是代理,只包含一个清单。 The 'linux' jars contain the JavaFX classes however NONE of the files contain: javafx.fxml.FXMLLoader 'linux' jars 包含 JavaFX 类,但是没有文件包含: javafx.fxml.FXMLLoader

My - build.gradle我的-build.gradle

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.8'
}
javafx {
    version = "11"
    modules = [ 'javafx.controls' ]
}
repositories {
    mavenLocal()
    mavenCentral()
}
sourceCompatibility = '11'

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

if (!hasProperty('mainClass')) {
    ext.mainClass = 'Main'
}
mainClassName = "Main"
run {
    args 'config.json'
}
dependencies {
    compile "joda-time:joda-time:2.10.5"
    testCompile "junit:junit:4.12"
}
jar {
    manifest {
        attributes 'Main-Class': 'Main'
    }
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

Can any one please see what I am doing wrong.任何人都可以看看我做错了什么。 This application needs to run on a clean system with no expectetaions other than Java (preferably OpenJDK).这个应用程序需要在一个干净的系统上运行,除了 Java(最好是 OpenJDK)之外没有任何期望。

I would also like it to run on a Windows 10 platform so can anyone tell me how to get the gradle build to include the 'win' equivilant jar files:我还希望它在 Windows 10 平台上运行,所以任何人都可以告诉我如何获得 gradle 构建以包含“win”等效 jar 文件:

javafx-controls-11-win.jar 
javafx-graphics-11-win.jar
javafx-base-11-win.jar

Kind Regards亲切的问候

Stuart斯图尔特

In your javafx section of your build.gradle you need to include fxml module:在 build.gradle 的 javafx 部分中,您需要包含 fxml 模块:

javafx {
    version = "11"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

Note that I have had some odd problems with version "11" javafx on Linux so you may want to change that to 13 or 14. JavaFX version requires at least JDK 11 so you can bump up JavaFX version without changing your JDK. Note that I have had some odd problems with version "11" javafx on Linux so you may want to change that to 13 or 14. JavaFX version requires at least JDK 11 so you can bump up JavaFX version without changing your JDK.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM