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

爱⌒轻易说出口 提交于 2021-01-01 07:06:57

问题


I'm trying to create a custom runtime image that will not require installed JRE/JDK on the computer. I have followed the tutorial presented on OpenJFX Documentation (JavaFX and IntelliJ - Modular with Maven) and I am able to run the created image, but I want to include for my application class com.sun.glass.ui.Window (in module javafx.graphics).

Before custom images, I was parsing as command line arguments the following: --add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED

I want to include this in runtime, so should I modify the pom from Maven to include for javafx-maven-plugin a (not successful) or should I edit the project module.info to export the requested package from javafx.graphics.

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

"Package "com.sun.glass.ui" is declared in module "javafx.graphics", which does not export to module "com.andrei" "


回答1:


The javafx-maven-plugin should be able to do what you are trying to do. However, it doesn't do it so far, so I've just filed these two issues: Options for javafx:run are incompatible with javafx:jlink and Missing link vm options parameter.

While this gets resolved and a new version is published, there is an easy (but manual) fix:

Compilation time

Before modifying the javafx-maven-plugin, you need to allow your IDE to work with the private package. You can't do it from the module-info, but you can easily do that from the maven-compiler-plugin using compilerArgs:

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

Now in your code you can make use of that private package, and IntelliJ won't complain.

After running from the Maven window Lifecycle -> clean, and Lifecycle -> compile, something like this is allowed in the editor:

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

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

Runtime

However, if you do mvn clean compile javafx:run, the code above will fail:

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.

As explained in the plugin readme, you cad add VM options that will be passed to the java tool:

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

Now you can run: mvn clean compile javafx:run, and that will work, and you will get information for the current stage printed out.

Runtime image

Finally, if you run: mvn clean compile javafx:jlink, this will fail, because the content in <options> is not recognized by jlink (first issue filed), so you have to comment it out:

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

Now mvn clean compile javafx:jlink will work, but when running you will get the same error as above because the private package is not exported.

However, you can edit the launcher file under target/image/bin/launcher:

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

As you can see, there is an empty JLINK_VM_OPTIONS variable that can be filled with your vm options.

Until the second issue filed is solved, just modify that line:

#!/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 $@

save, and run: target/image/bin/launcher, and it will work.



来源:https://stackoverflow.com/questions/56459093/openjfx-custom-runtime-image-using-maven-and-jlink-module-exports-or-command-l

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!