1

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

José Pereda
  • 44,311
  • 7
  • 104
  • 132
AndreiD
  • 113
  • 1
  • 11

1 Answers1

2

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.

ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • I will follow the status of your requests on GitHub for further updates regarding this topics. Thank you again! – AndreiD Jun 06 '19 at 10:07
  • 1
    @AndreiD I've just filed a PR that should fix both issues. If you want to test it in advance, clone and install the plugin from [here](https://github.com/jperedadnr/javafx-maven-plugin) with `mvn clean install`, and then use in your project with version `0.0.3-SNAPSHOT`. Your feedback is welcome. – José Pereda Jun 07 '19 at 11:09
  • I have tried to clone, but I get: The POM for org.openjfx:javafx-maven-plugin:jar:0.0.3-SNAPSHOT is missing, no dependency information available. – AndreiD Jul 19 '19 at 07:32
  • also I have one more question. Is it possible to to attach a remote debugger? using -agentlib – AndreiD Jul 19 '19 at 07:34
  • 1
    For debugging see [this](https://stackoverflow.com/a/56207033/3956070). – José Pereda Jul 19 '19 at 08:39
  • After cloning from github the project. should I insert in pom.xml file the following: ... C:\Users\andrei\Documents\javafx-maven-plugin-master ... ? – AndreiD Jul 24 '19 at 07:34
  • org.apache.maven.plugins maven-compiler-plugin 3.8.0 --add-exports javafx.graphics/com.sun.glass.ui=com.andrei – AndreiD Jul 24 '19 at 07:37
  • 12 12 12 com.andrei.App – AndreiD Jul 24 '19 at 07:39
  • [ERROR] Failed to execute goal org.openjfx:javafx-maven-plugin:0.0.2:jlink (default-cli) on project javafx-maven-setup: Error: Command execution failed. Process exited with an error: 2 (Exit value: 2) -> [Help 1] – AndreiD Jul 24 '19 at 07:41
  • Clone the plugin, set JDK 11, and run `mvn clean install`, then you can use `0.0.3-SNAPSHOT` in plugin's version of your end project's pom. That's it. – José Pereda Jul 24 '19 at 08:55