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

时间:2019-06-05 10:55:49

标签: java javafx javafx-11 openjfx

我正在尝试创建一个自定义运行时映像,该映像不需要在计算机上安装JRE / JDK。我已经按照OpenJFX文档(JavaFX和IntelliJ-使用Maven进行模块化)中介绍的教程进行操作,并且能够运行创建的图像,但是我想在我的应用程序类com.sun.glass.ui.Window中包含它(在javafx模块中) .graphics)。

在自定义图像之前,我将以下内容解析为命令行参数: --add-打开javafx.graphics/com.sun.glass.ui=全部取消命名

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

谢谢, 安德烈(Andrei)

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;
}

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

1 个答案:

答案 0 :(得分:1)

javafx-maven-plugin应该能够执行您尝试执行的操作。但是,到目前为止,它还没有这样做,所以我只提交了以下两个问题:Options for javafx:run are incompatible with javafx:jlinkMissing link vm options parameter

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

编译时间

在修改javafx-maven-plugin之前,您需要允许您的IDE与私有软件包一起使用。您无法从module-info中进行此操作,但可以使用maven-compiler-plugincompilerArgs中轻松进行此操作:

<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 -> 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,则上面的代码将失败:

  

由以下原因引起:java.lang.IllegalAccessError:com.andrei.Main类(在com.andrei模块中)无法访问com.sun.glass.ui.Window类(在javafx.graphics模块中),因为模块javafx.graphics确实可以不会将com.sun.glass.ui导出到模块com.andrei。

如插件readme中所述,您cad添加了将传递给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可以工作,但是在运行时,您将得到与上述相同的错误,因为未导出私有软件包。

但是,您可以在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,它将起作用。