启动使用 jpackage 部署并安装的 JavaFx 应用程序时找不到 JVM

问题描述

我已经用 jpackage 打包了一个 JavaFx (14) 项目,以便在 .exe 安装程序中进行部署。

项目依赖是:

  • Java 14.0.2
  • JavaFx 14.0.2.1
  • JRE 1.8.0_271(删除

所以,在我在多台机器(大约 6 台)上部署期间,它在几台机器上成功,但在其他机器上我有这个错误

JVM can not launch

尽管所有依赖项都已正确安装在这些机器上,并且定义了良好的环境变量。

有人可以帮我吗


经过一些修复(由 @Slaw@mipa 提及)后,我生成一个新包,安装它。但是当我运行该软件 (myApp.exe) 时,我有这个错误

Failed to lunch JVM

经过一番研究,解决方案是使用 java 命令创建一个批处理文件,该文件将运行位于 C:\Program Files\ software 文件夹中的 .jar 文件

cd "C:\Program Files\software\app"
java --module-path "C:\Program Files\Java\javafx-sdk-14.0.2.1\lib" --add-modules=ALL-module-path --add-exports javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED -jar software.jar

我已经做到了,它运行软件非常好,但是有没有其他优化的解决方案可以在没有批处理文件的情况下直接运行软件?

因为在某些计算机上,批处理没有运行软件,返回同样的错误午餐 JVM 失败

请帮忙

解决方法

如果您必须使用 --module-path--add-modules 手动启动应用程序,那么您在打包应用程序时未能包含 JavaFX,或者至少未能正确包含 JavaFX。请记住,JavaFX 是模块化的,即使您的代码不是。因此,当您打包应用程序时,您应该告诉 jpackage 将 JavaFX 视为模块。

首先,您应该获得 JavaFX JMOD 文件。您可以通过至少两种方式之一获取它们:

  1. 从 Gluon(您下载 JavaFX SDK 的同一位置)下载 JMOD 文件。
  2. 安装并使用包含 JavaFX 的 JDK(例如来自 Zulu Community、BellSoft Liberica 等)。
    • 使用此选项,您无需开始使用 JavaFX SDK。

您需要 JMOD 文件,因为它们将本机代码(以及其他内容,例如许可证)与 Java 代码打包在一起。这允许 jlink(由 jpackage 在幕后使用)优雅地将本机代码包含在自定义运行时映像中。另外,不要忘记 JavaFX(以及扩展的 JMOD 文件)是特定于平台的。并且 jpackage 只能为调用它的操作系统创建应用程序。

获得 JMOD 文件后,您需要打包您的应用程序。假设您的代码不是模块化的(您在问题中使用 -jar)并且您已将代码打包到 JAR 文件中。以下命令应该是您使用 jpackage 所需的最少命令:

jpackage --type app-image --module-path <path-to-jmods> --add-modules <needed-modules> 
         --input <dir-containing-your-jar-file> --main-jar <your-jar-file>
         --main-class <your-main-class> --dest <your-output-location>

一些注意事项:

  • 如果您安装并使用包含 JavaFX 的 JDK,那么您将不需要 --module-path。至少不适用于 JavaFX。

  • 我不确定您的应用程序需要哪些模块(对于 --add-modules 选项)。您使用 ALL-MODULE-PATH,但我怀疑您需要一切

  • 不是肯定的,但我相信如果您的 JAR 文件清单中有 Main-Class 属性,则不需要 --main-class

  • 如果您确实需要 --add-exports 参数,则可以使用:

    --java-options="--add-exports javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED"
    
  • 如果您使代码模块化,您还可以去掉 --add-modules 参数。相反,您将您的模块(以及任何不在 JDK 中的模块)放在 --module-path 上,并将 --input--main-jar--main-class 替换为 --module-path--module

    • 在这种情况下,--input 似乎不再必要。但是,如果您的应用程序需要其他文件(例如安全策略文件),那么您可能仍然需要 --input

有关详细信息,请参阅 JPackage User Guide。指南中描述的自定义应用程序的方法有很多,但本答案中未提及。

如果所有这些仍然不能解决每台计算机上的“无法启动 JVM”错误,那么您将需要进行进一步的调试。您想要做的第一件事是知道导致问题的实际错误。我至少可以想到两种方法来做到这一点:

  1. 向您的应用程序添加日志记录。登录到文件。
  2. 配置 jpackage 以使您的应用程序基于控制台。然后从控制台启动应用程序以查看任何输出。如果您在查看输出时遇到问题,则可以将标准/错误流重定向到文件或使用告诉控制台不要打开新窗口的选项。