【发布时间】:2020-01-06 02:47:43
【问题描述】:
我有以下错误,其中 json.org 依赖项未包含在最终的 .jar 文件中。
Exception in thread "Thread-2" java.lang.NoClassDefFoundError: org/json/JSONTokener
at gui.Main.lambda$awake$0(Main.java:91)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.ClassNotFoundException: org.json.JSONTokener
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 2 more
然后我了解到您可以将 json.org jar 文件添加为“提取目录”,从而解决了我的问题。这样做之后,我想我会尝试对 JavaFX 做同样的事情。在尝试将其添加为“提取目录”时,我注意到它已经列在那里(如下图所示)。
但是,如果我尝试使用 java -jar [filename].jar 运行 jar 文件,我会得到 Error: JavaFX runtime components are missing, and are required to run this application。我可以使用java -jar --module-path /usr/local/javafx-sdk-11.0.2/lib --add-modules javafx.controls,javafx.fxml [filename].jar 运行它,但理论上这不是必需的。我想知道是否有人知道为什么这不起作用?谢谢。
注意:打包 JavaFX 将非常有用,因为这意味着我可以只发送 .jar 文件,它可以开箱即用,用户无需设置额外的依赖项。
【问题讨论】:
-
你考虑过java packager吗?
-
当 JavaFX 库位于类路径(就像打包在胖 JAR 中时一样)而不是模块路径时,主类不得是 @ 的子类型987654330@。创建一个单独的“启动器”类,其主要方法只是调用
Application.launch(YourAppClass.class, args)。 -
"注意:打包 JavaFX 将非常有用,因为这意味着我可以只发送 .jar 文件,它可以开箱即用,用户无需设置额外的依赖项" – 请记住 JavaFX 包含特定于平台的本机代码;例如,包含 Windows 版本的 JavaFX 的胖 JAR 将无法在 Linux 上运行。我相信,您可以通过将 JavaFX 的每个平台版本打包到一个 JAR 文件中来解决这个问题。
-
另外,除了@Abra 的建议(我相信
javapackager在Java 11 中已被删除),您可能需要考虑使用jpackage。该工具可通过early-access versions of Java 14 获得。
标签: java intellij-idea javafx packaging