在模块路径上使用 OpenJFX 11 JMODS 在 JDK 11 上运行 javafx 示例
Posted
技术标签:
【中文标题】在模块路径上使用 OpenJFX 11 JMODS 在 JDK 11 上运行 javafx 示例【英文标题】:Running javafx sample on JDK 11 with OpenJFX 11 JMODS on Module Path 【发布时间】:2019-01-21 09:59:29 【问题描述】:我已经从 OpenJFX 项目下载了 JavaFX Jmod 文件并将它们放在目录G:\openjfx\javafx-jmods-11
中。我正在使用 OpenJDK 11,它在 JAVA_HOME/jmods
中没有 JavaFX jmod,即它不附带 JavaFX 分发。
模块信息文件:
module gui
requires javafx.graphics;
requires javafx.controls;
exports com.test;
我编译如下:
javac -p G:\openjfx\javafx-jmods-11 -d mods --module-source-path src
src\gui\com\test\*.java src\gui\module-info.java
编译成功。但我无法使用以下命令运行编译后的代码:
java -p G:\openjfx\javafx-jmods-11;mods -m gui/com.test.CreateGuiDemo
但我收到以下错误:
Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.graphics not found, required by gui
【问题讨论】:
不完全确定,但我认为您必须指定模块路径(您这样做)和要在编译和运行时路径上添加的模块:--add-modules javafx.controls 需要澄清一下,如果您可以在问题中添加详细信息,1.dir1
是什么? 2. 什么是mods
? 3. 您是否也有机会在 SDK 上进行同样的尝试? ... 肯定有一些与resolving the module at runtime 相关的噪音,实际上可能有用的东西可能是the effective command shared by Stephan here。
@kleopatra 据我了解,仅当您没有 module-info.java 文件时才需要这样做。所以,在这种情况下,它应该是没有必要的。
@Mohamed 我也会听从 nullpointer 的建议,并使用带有 jars 而不是 jmods 的 SDK。
@nullpointer 抱歉,我没时间试一试。我会在一两天内检查一下。由于我的示例应用程序是模块化应用程序,因此我不需要使用 --add-modules
选项。编译没问题,但在运行时命令行选项--module-path
不会占用一个以上的路径元素
【参考方案1】:
我相信您所面临的错误有一个解释:jmods can't be used at run time。
这里有解释:http://openjdk.java.net/jeps/261#Packaging:-JMOD-files:
JMOD 文件可以在编译时和链接时使用,但不能在运行时使用。通常,要在运行时支持它们,我们需要准备好即时提取和链接本机代码库。
感谢answer。
所以我做了一些简单的模块hellofx
:
module hellofx
requires javafx.controls;
exports hellofx;
使用来自here 的HelloFX
示例,并从here 下载适用于我平台的JavaFX 11 的jmod。我还从同一位置下载了 JavaFX 11 SDK(jar)。
编译时间
在编译时,我们可以使用 jmods:
javac -p /path-to/javafx-jmods-11/ -d mods/hellofx $(find src/hellofx -name "*.java")
或使用 SDK:
javac -p /path-to/javafx-sdk-11/lib -d mods/hellofx $(find src/hellofx -name "*.java")
在这两种情况下,结果完全一样,正如预期的那样:编译时不需要本地库。
运行时间
现在我们要运行我们的小模块。
使用 jmods,如 OP 所述,运行:
java -p /path-to/javafx-jmods-11/:mods -m hellofx/hellofx.HelloFX
失败:
Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.controls not found, required by hellofx
但是使用 SDK,可以:
java -p /path-to/javafx-sdk-11/lib/:mods -m hellofx/hellofx.HelloFX
链接时间
正如 JEP-261 所述,jmods 在链接时也能正常工作,因此我们可以在编译时和运行时之间使用jlink
工具。
您可以使用 jlink 工具将一组模块及其依赖项组装和优化为自定义运行时映像。 (source)
让我们开始吧:
jlink -p /path-to/javafx-jmods-11/:mods --add-modules=hellofx --output links
这将生成一个 90.7 MB 的文件夹(在我的 Mac 上)。请注意,lib
文件夹包含 Java 11 和 JavaFX 11 所需的所有本机库,以及一个名为 modules
的 70.5 MB 文件。
运行时间 (2)
我们终于可以做到了:
links/bin/java -m hellofx/hellofx.HelloFX
这会奏效的。
总之,如果我们只想使用 jmods 来编译和运行我们的模块,我们需要使用jlink
提供额外的步骤。否则,对于运行时,我们将需要 JavaFX SDK。
【讨论】:
非常感谢您的详细回答。是的,在运行时 SDK 为我工作。让我也试试 jLink 方法。信息量很大。 为什么要通过 SDK 使用 jmod 文件?【参考方案2】:如果没有自动添加,请尝试在 pom.xml 中使用此设置。请务必更改“!您的主要班级名称!”用main方法向代码的底部添加您的类的名称!如果我的课程是 Example.java,我只想放在那里。
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>!!YOUR MAIN CLASSNAME HERE!!</mainClass>
</configuration>
</plugin>
</plugins>
</build>
JavaFX 不会自动添加为 Java 11 的依赖项。这就是我们需要手动添加的原因。
【讨论】:
我想在 JDK 11 上运行 JavaFX。所以不能切换到 JDK 8。 我编辑了答案。试试看,让我知道它是否有效。以上是关于在模块路径上使用 OpenJFX 11 JMODS 在 JDK 11 上运行 javafx 示例的主要内容,如果未能解决你的问题,请参考以下文章
Gradle OpenJFx11:错误 - 缺少 JavaFx 运行时组件
是啥让 Maven 想要使用 Zulu Java 11 的 openjfx 而不是 Zulu Java 8 用于 Spring Boot 项目?
IDEA通过Maven打包JavaFX工程(OpenJFX11)