【问题标题】:How to open JavaFX .jar file with JDK 11?如何使用 JDK 11 打开 JavaFX .jar 文件?
【发布时间】:2019-05-01 04:33:06
【问题描述】:

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

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

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

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.Main.

【问题讨论】:

  • 是的。我有主班。使用 IntelliJ 选项中的构建工件
  • 如果你运行java -jar Timer.jar --module-path %PATH_TO_FX% --add-modules javafx.controls ,输出是什么?当你运行java --module-path .../javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml -classpath "<path to Timer.jar>" sample.Main ?
  • 这个错误给出: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
  • 第二种方法的错误:Error occurred during initialization of boot layer java.lang.module.FindException: Module javafx.controls not found
  • 由于在模块路径中明确指定了相同的模块。您可以使用help of --show-module-resolution 进一步调试查找已解析的模块。

标签: java javafx java-11 openjfx


【解决方案1】:

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

关于如何运行项目的完整教程可以在here 找到,关于如何创建 jar 的说明是 here(请参阅非模块化项目部分),但这些不包括来自 Artifacts IntelliJ。

使用以下 VM 选项检查 HelloFX 项目是否从 IntelliJ 运行:

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

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

肥罐

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

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

然后从列表中删除 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 依赖项的完整 jar,您仍然可以使用 Artifacts。

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

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

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

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

但这行不通。

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

所以创建一个启动器类:

public class Launcher {

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

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

所以编辑工件,选择 Launcher 类作为主类,并添加原生库(Windows 上为Directory Content -> path-to/JavaFX SDK/bin):

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

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

您可以分发此 jar,但只能分发到 Windows 平台。

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

无论如何,你应该考虑使用jlinkinstead

注意

关于这个错误:

原因: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"

【讨论】:

  • 非常感谢。这解决了这个问题:set PATH_TO_FX="C:\Program Files\Java\javafx-sdk-11.0.1\lib"
  • 是的,我从你的问题中猜到了这一点,但借此机会解释了如何使用 Artifacts 来做(半)胖罐子以及你在这个过程中可能会发现的问题。
  • 是的。你做了一个完整的有用的指南。正如你所说,我必须尝试jlink。我认为这是 Java 世界中一个新的好特性。再次感谢何塞
  • 非常感谢。我花了最后两个小时尝试在可执行 jar 中构建我的 JavaFX 应用程序,但我错过了 Launcher 类步骤。
  • 我从这里得到的 jfx-sdk 中没有看到原生库:gluonhq.com/products/javafx 如何使用这个 SDK 制作 fat jar?
【解决方案2】:

我在使用 JavaFX 和 IntelliJ Non-modular with Gradle 导出/生成 Jar 时遇到了类似问题 (https://openjfx.io/openjfx-docs/)

我使用 Gradle jar 命令生成的 jar 没有运行并抛出错误,说它找不到我的主类。当我打开我的罐子时,我能够找到我的主要课程。所以我意识到这个错误与罐子包装有关。

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

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

【讨论】:

    【解决方案3】:

    最简单的方法是使用包含 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”

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

    【讨论】:

      【解决方案4】:

      以上答案适用于非模块化 JavaFX 项目。为了让模块化 JavaFX 项目(具有模块化依赖项)运行,我使用了 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 mod 和您自己编译的 mod 的模块路径:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-20
        • 2019-03-05
        • 2020-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多