Open abhinayagarwal opened 3 years ago
The maven-jlink-plugin
works in a very different way than this plugin does.
The main problem I have found is the way it discover the modules that will be (by default) added the custom runtime image: "...this is handled automatically by the given dependencies".
This behavior makes it impossible to execute the jlink
command on JavaFX applications since non-platform Maven artifacts are trying to be added add as modules (via the --add-modules
parameter).
Another problem with this plugin is that, by default, the application base module isn`t added as module to the custom image.
JavaFX applications need a plugin that better fit their requirements (like this one) in order to generate custom runtime images.
Because of this, I think that the javafx-maven-plugin
should keep the jlink
functionality.
Hi @betanzos,
Thanks for taking time to comment on this issue. Your feedback is valuable in understanding the right approach to solve this problem.
... discover the modules that will be (by default) added the custom runtime image: "...this is handled automatically by the given dependencies".
If we let go of how JavaFX Maven artifacts are released, don't you think this is the right approach?
This behavior makes it impossible to execute the jlink command on JavaFX applications since non-platform Maven artifacts are trying to be added add as modules (via the --add-modules parameter).
This is a pain that we are trying to solve. JavaFX Maven artifacts needs a better way to be bundled. The current approach of using empty jars isn't the best solution to the problem.
Another problem with this plugin is that, by default, the application base module isn`t added as module to the custom image.
I have tried the plugin earlier this year and didn't face any such issue. Do you have a sample or configuration file I can try out to get a better idea of the issue?
JavaFX applications need a plugin that better fit their requirements (like this one) in order to generate custom runtime images.
If we bring the Automatic-Module-Name
back into the empty jars, then the jlink functionality will stay in the plugin.
If we let go of how JavaFX Maven artifacts are released, don't you think this is the right approach?
Maybe yes but, strangely, the image that maven-jlink-plugin
generates includes more modules than if it is generated with javafx-maven-plugin
, including dependencies with runtime scope (see images below). So for a JavaFX application I think is a better idea to add just the dependent modules based on my app's module descriptor.
javafx-maven-plugin
imagemaven-jlink-plugin
image
JavaFX Maven artifacts needs a better way to be bundled. The current approach of using empty jars isn't the best solution to the problem.
I can agree with this if the modular structure of the framework is not affected, but it is not the case according to this mail.
- Instead of 1 module per component, we will have 2 modules (javafx.base.api and javafx.base.platform)
- The
javafx.base.api
, unlike empty jar, will contain all generic Java code- The
javafx.base.platform
will contain platform-specific native + Java code- Current application declare their module-descriptor as:
module app { requires javafx.base; }
- In future this may be changed depending on how we end up wiring these modules together:
module app { requires javafx.base [.api or .platform]; }
And all this because an external plugin since with the official JavaFX Maven plugin it work fine.
I think a better approach can be using a Parent POM for our JavaFX Maven applications (like in Spring Boot apps). This POM can use the same mechanism in order to detect the current OS and define all JavaFX artifacts as managed dependencies including the classifier
tag. In this way we would only have to specify the needed dependencies in our POM as so far and we could drop out the empty jars.
I have tried the plugin earlier this year and didn't face any such issue. Do you have a sample or configuration file I can try out to get a better idea of the issue?
Of course! I have crated this repository in GitHub called hellofx-modular based in the official example app hellofx.
Over this project you can run the command $ mvn jlink:jlink
in order to create the custom image and then see the included modules (the application module is not there)
If we bring the
Automatic-Module-Name
back into the empty jars, then the jlink functionality will stay in the plugin.
I have tried versions 16 and 17-ea+14 (the last one including the Automatic-Module-Name
entry) and the jlink
command ends with the errors below (all tests over the hellofx-modular
project):
With JavaFX 16 [ERROR] Error: automatic module cannot be used with jlink: javafx.mediaEmpty from file:///D:/tools/maven-repository/org/openjfx/javafx-media/16/javafx-media-16.jar
**With JavaFX 17-ea+18 [ERROR] Error: automatic module cannot be used with jlink: javafx.baseEmpty from file:///D:/tools/maven-repository/org/openjfx/javafx-base/17-ea+14/javafx-base-17-ea+14.jar
And all this because an external plugin since with the official JavaFX Maven plugin it work fine.
I would agree that the change wasn't important but I am happy it lead to rekindle the topic of how JavaFX Maven artifacts are bundled :)
As I understand, empty jars with the Automatic-Module-Name
in them only exist because we didn't want to introduce new modules for native/platform jars. Kevin is correct to say that platform modules are implementation details and JavaFX users shouldn't 'be exposed to them. This is vital to keep JavaFX usage simple.
There is also behavorial issue b/w Maven vs Gradle which plays a role in empty jars existent and this comment has more information on it. There is not much we can do about this.
The end goal should be to make JavaFX Maven artifacts JPMS compliant which can only happen if we remove the empty jars or convert them into modules.
the image that maven-jlink-plugin generates includes more modules than if it is generated with javafx-maven-plugin, including dependencies with runtime scope (see images below)
maven-jlink-plugin
seems to have the correct behaviour here, don't you think? If you want to exclude a dependency from being added to the image, it should be declared as <scope>provided</scope>
.
the image that maven-jlink-plugin generates includes more modules than if it is generated with javafx-maven-plugin, including dependencies with runtime scope (see images below)
maven-jlink-plugin
seems to have the correct behaviour here, don't you think? If you want to exclude a dependency from being added to the image, it should be declared as<scope>provided</scope>
.
Not always. Sometimes I need to have the flexibility to be able to exchange the artifacts I use at runtime.
And all this because an external plugin since with the official JavaFX Maven plugin it work fine.
I would agree that the change wasn't important but I am happy it lead to rekindle the topic of how JavaFX Maven artifacts are bundled :)
As I understand, empty jars with the
Automatic-Module-Name
in them only exist because we didn't want to introduce new modules for native/platform jars. Kevin is correct to say that platform modules are implementation details and JavaFX users shouldn't 'be exposed to them. This is vital to keep JavaFX usage simple.There is also behavorial issue b/w Maven vs Gradle which plays a role in empty jars existent and this comment has more information on it. There is not much we can do about this.
The end goal should be to make JavaFX Maven artifacts JPMS compliant which can only happen if we remove the empty jars or convert them into modules.
I agree 100% with Kevin's point of view, and yours. Keep JavaFX users away from implementation details is the right approach, because of this I disagree to add more modules which change the way we use the framework.
I still think that this plugin (javafx-maven-plugin
) jlink
functionality must be not removed, at least until JavaFX Maven artifacts are compatible maven-jlink-plugin
. However, once this goal is reached, the problem of having to take extra steps to add the application module to the runtime image would persist, and this bothers me a bit.
This plugin builds incorrect jlink image form me. Half of the dependencies are not present and i don't know why. Maven JLink plugin builds correct image, but it doesn't work well because i have to
mvn package
mvn jlink:jlink
Only in this order.Half of the dependencies are not present and i don't know why.
By "dependencies" do you mean Maven dependencies?
It's a multimodule project with many API + Impl modules. I meant Impl modules. I found that all modules are passed to jlink, but manual service binding is impossible. I filled a ticket: https://github.com/openjfx/javafx-maven-plugin/issues/145
I switched to maven jlinker and using this workaround, a bit hacky, but it works:
mvn package -Djavafx.version=17.0.1
<- to compile and package JARsmvn jlink:jlink -Djavafx.version=17
<- to create jlink image from JARs made in step 1Having beaten my head against a brick wall for many days with both plugins,
I am trying to get successful cross build of a JavaFX from windows 10 x64 (build host) to linux aarch64 (target). The application access an H2 database using eclipselink 4.0.1 and H2 JDBC driver. H2 been patched to be modular via moditect.
I find that neither plugin jlink is 100% functional:
Currently, javafx-maven-plugin is much closer to working. If I make a batch file by cribbing it's command line and adding the two service dependencies via --add-module manually, it works.
Apache Maven JLink Plugin is now available. It is the official plugin for jlink support.
jlink functionality in javafx-maven-plugin should be deprecated and users should be encouraged to use the official plugin instead.