首页 > 解决方案 > Gradle 构建的 JavaFX 项目无法在 Windows 中运行

问题描述

我有一个 JavaFX Gradle 项目,当我在 Linux(Mint 18.3)中执行installDist任务(Gradle 插件的一部分)时运行正常。application

这会生成一个独立的应用程序,其中包含一个 Linux 可执行脚本文件、一个 Windows .bat 文件和一个包含运行应用程序所需的所有 .jar 文件的库,包括一个包含您自己的代码和资源的 .jar 文件。它们被放在“bin”目录的同级目录中,称为“lib”。

运行该可执行文件在 Linux 上运行良好。

但后来我启动到 W10 并尝试运行 .bat 文件。我收到以下错误:

Discovered throwable java.lang.RuntimeException: No toolkit found message No toolkit found

Root cause throwable java.lang.RuntimeException: No toolkit found message No toolkit found

Root cause trace:
[com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
 com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
 com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
 com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
 com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
 com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)]

我的项目有几个方面可能会使事情复杂化

  1. 它使用 Java11(和 JavaFX11)。这意味着 JavaFX 不再与其他软件捆绑在一起。两个操作系统都运行 Java 11。
  2. 它是用 Groovy 编写的:也就是说,应用程序代码,所有应用程序代码,都是用 Groovy 编写的,而不是 Java。
  3. 因为它是用 Groovy 编写的,所以即使在 Linux 中也很难让installDist任务正常工作。最终我不得不创建一个“启动器”类,然后调用Application子类(在这里HelloFx)并让它运行start

    Application.launch(HelloFx, args)- 完整的血腥细节在这里

我知道当您希望可执行文件在这两个不同的操作系统中运行时,build.gradle 文件中存在一些小问题,特别是正确获取文件路径和路径分隔符,即 Linux 的“/”,“\”为 W10。但是我以前在非 JavaFX 项目中已经做到了,而且我似乎已经在这里配置了一些东西。

浏览一下 Linux 中 Gradle 生成的 .bat 文件可能会有所帮助:

...
set CLASSPATH=%APP_HOME%\lib\Organiser-1.0.7-SNAPSHOT.jar;%APP_HOME%\lib\javafx-fxml-11.0.2-linux.jar;%APP_HOME%\lib\javafx-controls-11.0.2-linux.jar;%APP_HOME%\lib\javafx-controls-11.0.2.jar;%APP_HOME%\lib\javafx-graphics-11.0.2-linux.jar;%APP_HOME%\lib\javafx-graphics-11.0.2.jar;%APP_HOME%\lib\javafx-base-11.0.2-linux.jar;%APP_HOME%\lib\javafx-base-11.0.2.jar;%APP_HOME%\lib\groovy-2.5.11.jar;%APP_HOME%\lib\logback-classic-1.2.3.jar;%APP_HOME%\lib\logback-core-1.2.3.jar;%APP_HOME%\lib\slf4j-api-1.7.25.jar

@rem Execute Organiser
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %ORGANISER_OPTS%  -classpath "%CLASSPATH%" core.Launcher %CMD_LINE_ARGS%
...

从上面看来,JavaFX 文件肯定包含在类路径中。JavaFX 模块的设置,因为它是在 build.gradle 中配置的,所以大概发生在我的代码的 .jar 文件中......不知何故?

标签: javagradlejavafxgroovycross-platform

解决方案


来自https://docs.oracle.com/javafx/2/deployment/self-contained-packaging.htm上的文档

在第 6.2 节中它指出

每个目标平台的包 自包含应用程序包是特定于平台的,只能为您构建的同一系统生成。如果您想在 Windows、Linux 和 Mac 上交付自包含的应用程序包,您必须在所有三个平台上构建您的项目。

正如您从 .bat 摘录中看到的那样,JavaFX 模块是特定于平台的,表示“linux”

我从来没有亲自利用 gradle 构建多个平台,但我相信这里有一些答案,检查一下我很快找到的这个https://stackoverflow.com/a/53760018/3625077

如果没有在 Windows 原生或通过 VM 中构建,您可以打开一个新问题并发布您的 build.gradle 文件,社区可以帮助您解决这个问题


推荐阅读