在模块路径上使用 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 示例的主要内容,如果未能解决你的问题,请参考以下文章

带有模块的 Java 11 Gradle

Gradle OpenJFx11:错误 - 缺少 JavaFx 运行时组件

是啥让 Maven 想要使用 Zulu Java 11 的 openjfx 而不是 Zulu Java 8 用于 Spring Boot 项目?

IDEA通过Maven打包JavaFX工程(OpenJFX11)

IDEA通过Maven打包JavaFX工程(OpenJFX11)

IDEA通过Maven打包JavaFX工程(OpenJFX11)