如何用 JDK 11 打开 JavaFX .jar 文件?

How to open JavaFX .jar file with JDK 11?

我在 IntelliJ 中创建了一个 JavaFX 项目。 我可以 运行 在 IntelliJ 中进行项目。我在配置中添加了以下代码):

--module-path ${PATH_TO_FX} --add-modules=javafx.controls,javafx.fxml

但是项目(使用 Artifects 制作)的输出 .jar 文件没有 运行。我测试了这些命令,但没有得到任何机会:

java  --module-path %PATH_TO_FX% --add-modules javafx.controls,javafx.fxml -jar Timer.jar
java  --module-path %PATH_TO_FX% --add-modules javafx.controls  Timer.jar

命令行的最后一个错误日志:

Error: Could not find or load main class Files\Java\javafx-sdk-11.0.1\lib
Caused by: java.lang.ClassNotFoundException: Files\Java\javafx-sdk-11.0.1\lib

p.s:在 JDK-10

上构建时,我可以 运行 这个项目的 .jar 文件

编辑:

我下载了 JavaFX 并将其 lib 文件夹添加到系统环境。 为了将 JavaFX 添加到项目中,我执行了以下过程: 项目结构 > 库 > 添加 > Java > JavaFxPath/lib

然后我在这个过程中为输出jar文件创建了Artifect: 项目结构 > 工件 > 添加 > JAR > 来自具有依赖关系的模块 > main Class : main.Main.

如果您有一个简单的(非模块化的)JavaFX 11 项目(没有 Maven/Gradle 构建工具),并且您正在使用 IntelliJ,例如 here 中的 HelloFX 示例, 这是从 IntelliJ 创建一个 jar 的方法,可以从控制台运行

可以找到有关如何 运行 项目的完整教程 here, and instructions on how to create a jar are here(请参阅非模块化项目部分),但这些不包括来自 IntelliJ 的 Artifacts

检查来自 IntelliJ 的 HelloFX 项目 运行 是否具有以下 VM 选项:

--module-path ${PATH_TO_FX} --add-modules javafx.controls,javafx.fxml

其中 PATH_TO_FX 已在 File -> Settings -> Appearance & Behavior -> Path Variables 中设置,指向 JavaFX SDK 库。

胖罐

我们可以创建一个仅包含项目中的 classes 和第三方依赖项但不包含 JavaFX 的 Jar。

转到 File -> Project Structure -> Artifacts -> Add -> JAR -> From modules with dependencies,添加您的主要 class,接受。

然后从列表中删除 JavaFX jar,然后接受。

构建项目,它将创建一个非常小的 jar(在本例中为 3 KB)。

现在您应该可以 运行 它像:

java --module-path %PATH_TO_FX% --add-modules javafx.controls,javafx.fxml -jar out\artifacts\HelloFX_jar\HelloFX.jar

(确保 %PATH_TO_FX% 指向有效文件夹,如果包含空格则使用引号。

您可以分发此 jar,并 运行 在其他平台上发布它,前提是这些平台也有 JavaFX SDK。

肥罐

如果您想要一个包含 JavaFX 依赖项的完整 fat jar,您仍然可以使用 Artifacts。

转到 File -> Project Structure -> Artifacts -> Add -> JAR -> From modules with dependencies,添加您的主要 class,接受。

然后保留列表中的 JavaFX jar,然后接受。构建项目。

理论上,你应该可以运行这样:

java -jar out\artifacts\HelloFX_jar\HelloFX.jar

但这行不通。

原因 1:您需要一个启动器 class,如 所述。

所以创建一个启动器class:

public class Launcher {

    public static void main(String[] args) {
        Main.main(args);
    }
}

原因 2:如果您只将 SDK jar 添加到 fat jar,您将缺少本机库,如 所述。

因此编辑工件,select 启动器 class 作为主要 class,并添加本机库(Directory Content -> path-to/JavaFX SDK/bin on Windows):

现在构建项目(现在 jar 大约 33 MB,并且包含不必要的本机库)和 运行:

java -jar out\artifacts\HelloFX_jar\HelloFX.jar

您可以分发此 jar,但仅限于 Windows 平台。

如果下载其他平台的 JavaFX SDK,您可以为其他平台创建类似的 jar,如果将它们全部添加在一起,也可以构建跨平台的 jar,如上面链接的答案中所述。

无论如何,你应该考虑使用 jlink instead.

备注

关于这个错误:

Caused by: java.lang.ClassNotFoundException: Files\Java\javafx-sdk-11.0.1\lib

看起来库路径设置时没有引号并且缺少路径的第一部分 C:\Program Files\...。只需确保使用引号:

set PATH_TO_FX="C:\Program Files\Java\javafx-sdk-11.0.1\lib"

我遇到了类似的问题 exporting/generating 一个使用 JavaFX 的 Jar 和具有 Gradle 的 IntelliJ 非模块化(https://openjfx.io/openjfx-docs/)

我使用 Gradle jar 命令生成的 jar 没有 运行 并抛出错误说它找不到我的 Main Class。当我打开我的罐子时,我能够找到我的主要 class。所以我意识到错误与 Jar Packaging 有关。

我通过将 JavaFX SDK 添加到我在 IntelliJ 中的 Java SDK 解决了这个问题,如下所示。

在此之后,我使用常规 Gradle build Jar 命令生成我的 Jar 文件(如下所示)并且它 运行s 正常。

最简单的方法是使用包含 JavaFX 的 OpenJDK 构建。 Bellsoft 和 Azul 都生产这样的构建。

对于 Azul 的 Zulu 版本的 OpenJDK: https://www.azul.com/downloads/zulu-community/?version=java-11-lts&package=jdk-fx

对于 Bellsoft Liberica JDK: https://bell-sw.com/pages/downloads/#/java-11-lts 并选择“完整 JDK”

这些构建基本上是 OpenJDK 添加了 OpenJFX JavaFX 模块。不过要小心,因为 LibericaFX 可能不支持 JavaFX 的某些方面。参见 https://bell-sw.com/pages/liberica-release-notes-11.0.9.1/

以上答案适用于非modular JavaFX 项目。为了获得 modular JavaFX 项目(具有 modular 依赖项)运行 我使用了 jlink。

https://gluonhq.com/products/javafx/; 中获取 JavaFX SDK 将文件解压缩到一个目录,然后将 shell 变量 JFX_LIB 指向解压缩的 lib/ 目录。

https://gluonhq.com/products/javafx/; 中取出 JavaFX jmods(非 SDK)文件,解压 jmods,它们位于类似于 javafx-jmods-11.0.2/ 的文件夹中。将一个shell变量JMOD_PATH指向解压后的目录javafx-jmods-11.0.2/.

编译,将编译好的类发送到目录mods/:

javac -d mods  --module-source-path src --module-path $JFX_LIB/javafx.graphics.jar:$JFX_LIB/javafx.base.jar:$JFX_LIB/javafx.controls.jar --module com.mymodule

使用 jlink 创建自定义 JRE,引用包含 JavaFX mods 和您自己编译的 mod:

的 module 路径
jlink --module-path $JMOD_PATH:mods --add-modules com.mymodule --output customjre

运行:

customjre/bin/java --module com.mymodule/com.mymodule.Main

(我尝试了很长时间以获得 java -jar 运行 --module-path--add-modules。我总是遇到以下错误:)

Error: Could not find or load main class com.mymodule.Main
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application