-
Notifications
You must be signed in to change notification settings - Fork 741
JavaFX and JavaCPP
JavaCPP presets and JavaFX use similar methods to bundle native libraries in jar files.
Both have one native maven artifacts for each platform and one or two java maven artifacts common to all platforms.
Both also use a maven property, javafx.platform
or javacpp.platform
, to control the platform-specific dependencies.
However they differ in what each artifact contains. Here are two examples: javafx-graphics
and opencv
:
Common artifact | Platform artifact | |
---|---|---|
Name | javafx-graphics-17.0.2.jar |
javafx-graphics-17.0.2-linux.jar |
Content | Nothing | Java classes and native libraries |
JPMS module |
javafx.graphicsEmpty (automatic module) |
javafx.graphics |
Common artifact 1 | Common artifact 2 | Platform artifact | |
---|---|---|---|
Name | opencv-platform-4.5.3-1.5.6.jar |
opencv-4.5.3-1.5.6.jar |
opencv-4.5.3-1.5.6-linux-x86_64-gpu.jar |
Content | Nothing | Java classes | Native libraries |
JPMS module | org.bytedeco.opencv.platform |
org.bytedeco.opencv |
org.bytedeco.opencv.linux.x86_64.gpu |
They also differ in that javafx.platform
defaults to the host platform, while javacpp.platform
defaults to all available platforms.
Let's consider a modular application using both JavaFX and OpenCV.
Running such application is not a problem. We can either use the run
goal
of the JavaFX Maven plugin, the java
goal of the Exec Maven plugin, or manually launch java
with a module path computed
from Maven dependencies and option --add-modules ALL-MODULE-PATH
.
Building a JLink image is a bit more tricky.
One option is to follow the JavaCPP way, as explained here:
use Apache Maven JLink plugin that by default builds jlink module path (--module-path
option) AND the
jlink module graph (--add-modules
option) using all Maven dependencies.
However, since the maven dependencies of our application include the JavaFX common artifact which is
an automatic module, JLink fails.
This could be solved if the Apache JLink Maven filtered out the automatic module
but that's not currently the case (see this issue).
or if JavaFX common artifacts were true named modules.
Another option is to use the JavaFX Maven plugin and its jlink
goal.
Unlike the Apache plugin, this plugin only adds the application module as the root of the module graph,
and relies on module descriptors to bring other required modules in the graph.
This work well for JavaFX, since the automatic module, which is
not required, will be skipped and not included in the image. But not for JavaCPP, since
the platform artifacts won't be included in the image. There is currently no way with this plugin
to generate other --add-modules
argument for jlink. Some attempts have been made to
add the necessary features to JavaFX Maven Plugin (see this PR),
but they have not been finalized.
At the end of the day, there is no good solution for building a JLink image with both JavaCPP and JavaFX maven artifacts. We suggest instead to download a JDK including JavaFX from Gluon or Azul, remove the JavaFX maven dependencies from your POM, and use the Apache JLink Maven plugin.