使用 Maven 和 jlink 的 OpenJFX 自定义运行时图像 - 模块导出或命令行参数?

OpenJFX Custom runtime image using Maven and jlink - Module exports or command line arguments?

我正在尝试创建不需要在计算机上安装 JRE/JDK 的自定义 运行time 图像。我遵循了 OpenJFX 文档(JavaFX 和 IntelliJ - 模块化与 Maven)上的教程,我能够 运行 创建的图像,但我想在我的应用程序中包含 class com.sun.glass.ui.Window (在模块 javafx.graphics 中)。

在自定义图像之前,我将以下内容解析为命令行参数: --add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED

我想在 运行 时间包含它,所以我应该修改 Maven 的 pom 以包含 javafx-maven-plugin a(不成功)还是应该编辑项目module.info 从 javafx.graphics 导出请求的包。

谢谢, 安德烈

Pom.xml module.info.java

module com.andrei {
    requires javafx.controls;
    requires javafx.graphics;
    exports com.andrei;
    exports com.sun.glass.ui to com.andrei;
}

"Package "com.sun.glass.ui" 在模块 "javafx.graphics" 中声明,它不会导出到模块 "com.andrei" "

javafx-maven-plugin 应该能够做你想做的事。但是,到目前为止还没有这样做,所以我刚刚提交了这两个问题:Options for javafx:run are incompatible with javafx:jlink and Missing link vm options parameter.

虽然这个问题得到解决并发布了新版本,但有一个简单的(但手动)修复:

编译时间

在修改 javafx-maven-plugin 之前,您需要允许您的 IDE 使用私有包。您无法从 module-info 执行此操作,但您可以使用 compilerArgs:

maven-compiler-plugin 轻松执行此操作
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <compilerArgs>
            <arg>--add-exports</arg>
            <arg>javafx.graphics/com.sun.glass.ui=com.andrei</arg>
        </compilerArgs>
    </configuration>
</plugin>

现在您可以在您的代码中使用该私有包,IntelliJ 不会抱怨。

从 Maven 运行ning window Lifecycle -> cleanLifecycle -> compile 之后,编辑器中允许这样的事情:

@Override
public void start(Stage stage) throws Exception {
    ...
    stage.setScene(scene);
    stage.show();

    com.sun.glass.ui.Window.getWindows().forEach(System.out::println);
}

运行时间

但是,如果您这样做 mvn clean compile javafx:run,上面的代码将失败:

Caused by: java.lang.IllegalAccessError: class com.andrei.Main (in module com.andrei) cannot access class com.sun.glass.ui.Window (in module javafx.graphics) because module javafx.graphics does not export com.sun.glass.ui to module com.andrei.

如插件 readme 中所述,您可以添加将传递给 java 工具的 VM 选项:

<plugin>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>0.0.2</version>
    <configuration>
        <options>
            <option>--add-opens</option>
            <option>javafx.graphics/com.sun.glass.ui=com.andrei</option>
        </options>
        ...
</configuration>
</plugin>

现在您可以 运行: mvn clean compile javafx:run,这样就可以了,您将打印出当前阶段的信息。

运行时图像

最后,如果你运行: mvn clean compile javafx:jlink,这会失败,因为<options>中的内容不被jlink识别(第一个问题提交),所以你必须把它注释掉:

<plugin>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>0.0.2</version>
    <configuration>
        <!--<options>-->
          <!--<option>--add-opens</option>-->
          <!--<option>javafx.graphics/com.sun.glass.ui=com.andrei</option>-->
        <!--</options>-->
        <launcher>launcher</launcher>
        <mainClass>com.andrei/com.andrei.Main</mainClass>
    ...
</configuration>
</plugin>

现在mvn clean compile javafx:jlink就可以了,但是当运行ning你会得到和上面一样的错误,因为私有包没有导出。

但是,您可以编辑 target/image/bin/launcher 下的启动器文件:

#!/bin/sh
JLINK_VM_OPTIONS=
DIR=`dirname [=14=]`
$DIR/java $JLINK_VM_OPTIONS -m com.andrei/com.andrei.Main $@

如您所见,有一个空的 JLINK_VM_OPTIONS 变量可以用您的 vm 选项填充。

在提交的第二个问题解决之前,只需修改该行:

#!/bin/sh
JLINK_VM_OPTIONS="--add-opens javafx.graphics/com.sun.glass.ui=com.andrei"
DIR=`dirname [=15=]`
$DIR/java $JLINK_VM_OPTIONS -m fx/org.openjfx.MainApp $@

保存,然后运行:target/image/bin/launcher,它会起作用。