【问题标题】:OpenJFX Custom runtime image using Maven and jlink - Module exports or command line arguments?使用 Maven 和 jlink 的 OpenJFX 自定义运行时映像 - 模块导出或命令行参数?
【发布时间】:2019-10-20 21:09:42
【问题描述】:

我正在尝试创建一个不需要在计算机上安装 JRE/JDK 的自定义运行时映像。我已按照 OpenJFX 文档(JavaFX 和 IntelliJ - 使用 Maven 的模块化)上介绍的教程进行操作,并且能够运行创建的图像,但我想为我的应用程序类 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 模块.info.java

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

“包“com.sun.glass.ui”在模块“javafx.graphics”中声明,不导出到模块“com.andrei””

【问题讨论】:

    标签: java javafx javafx-11 openjfx


    【解决方案1】:

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

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

    编译时间

    在修改 javafx-maven-plugin 之前,您需要允许您的 IDE 使用私有包。您无法从模块信息中执行此操作,但您可以使用 compilerArgsmaven-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 窗口 Lifecycle -&gt; cleanLifecycle -&gt; 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,上面的代码就会失败:

    原因:java.lang.IllegalAccessError:com.andrei.Main 类(com.andrei 模块中)无法访问 com.sun.glass.ui.Window 类(javafx.graphics 模块中),因为 javafx.graphics 模块可以访问不将 com.sun.glass.ui 导出到模块 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,这将失败,因为&lt;options&gt;中的内容不被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 可以工作了,但是运行时你会得到和上面一样的错误,因为私有包没有被导出。

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

    #!/bin/sh
    JLINK_VM_OPTIONS=
    DIR=`dirname $0`
    $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 $0`
    $DIR/java $JLINK_VM_OPTIONS -m fx/org.openjfx.MainApp $@
    

    保存并运行:target/image/bin/launcher,它将起作用。

    【讨论】:

    • 我将关注您在 GitHub 上的请求状态,以获取有关此主题的进一步更新。再次感谢您!
    • @AndreiD 我刚刚提交了一份 PR,应该可以解决这两个问题。如果您想提前测试它,请从heremvn clean install 克隆并安装插件,然后在您的项目中使用版本0.0.3-SNAPSHOT。欢迎您的反馈。
    • 我试图克隆,但我得到:org.openjfx:javafx-maven-plugin:jar:0.0.3-SNAPSHOT 的 POM 丢失,没有可用的依赖信息。
    • 我还有一个问题。是否可以附加远程调试器?使用-agentlib
    • 调试见this
    猜你喜欢
    • 2019-04-13
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多