java - linux 上的干净部署 - java.lang.ClassNotFoundException: javafx.fxml.FXMLLoader
问题描述
我有一个 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
我使用 gradle 插件构建了一个可执行的 jar。它还构建了一个 zip 和 tar 文件。zip(和 tar)文件包含一个带有运行应用程序脚本的 bin 目录和一个包含大量 jar 文件的 lib 目录。
我有一个以前的问题
Error: JavaFX runtime components are missing, and are required to run this application
我在这里找到了解决方案:
我创建了一个包装类,其中包含一个调用 main(javafx)的 main(非 javafx)。
我目前的问题:
全新安装 Linux Mint - 19.3 Cinnamon Kernal - 5.3.0-53-generic
gradle-6.0.1
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)
如果我使用(爆炸的)zip文件中的脚本:
./MyApp/bin/MyApp config.json
或者只是执行应用程序:
java -jar MyApp.jar config.json
这两个都失败了
使用 ZIP 文件内容,我探索了 gradle 部署的 jar 文件。
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
'*' 文件是代理,只包含一个清单。'linux' jar 包含 JavaFX 类,但没有文件包含:javafx.fxml.FXMLLoader
我的 - 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) }
}
}
任何人都可以看看我做错了什么。这个应用程序需要在一个干净的系统上运行,除了 Java(最好是 OpenJDK)之外没有任何期望。
我还希望它在 Windows 10 平台上运行,所以任何人都可以告诉我如何让 gradle 构建包含“win”等效 jar 文件:
javafx-controls-11-win.jar
javafx-graphics-11-win.jar
javafx-base-11-win.jar
亲切的问候
斯图尔特
解决方案
在 build.gradle 的 javafx 部分中,您需要包含 fxml 模块:
javafx {
version = "11"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
请注意,我在 Linux 上的版本“11”javafx 遇到了一些奇怪的问题,因此您可能希望将其更改为 13 或 14。JavaFX 版本至少需要 JDK 11,因此您可以在不更改 JDK 的情况下升级 JavaFX 版本。
推荐阅读
- android - Android 应用程序可在模拟器上运行,但不能在真实设备上运行,SharePreferences
- javascript - 使用 AJAX 获取 Django 视图数据
- linux - 从字符串“89dde7.rqsnhq34h.fmu8s1vn0i94hl.tgz.tar.gz”中只删除“.tar.gz”
- oracle - 商业智能:数据仓库创建 (ORACLE)
- mysql - 一张表多选
- c# - 找不到类型或命名空间名称 AsyncLocal<>
- r - R 的左侧函数
- ssl - SSL 和 iframe - 相同的证书是否适用于 iframe?
- hyperledger-fabric - 握手失败,出现致命错误 SSL_ERROR_SSL: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
- r - 为什么每次我关闭 RStudio 工作区中的所有内容都会消失?