JavaFX 17 Maven artifacts currently fail to compile modular JavaFX application.
The non-modular application still work.
To explain what's going on, let have a look at JavaFX and its Maven
distribution since version 11:
1. JavaFX is distributed in non-platform (empty) and platform specific artifacts
2. These artifacts along with the JavaFX plugins have helped developers to use
JavaFX in platform agnostic way
3. Platform jars have the `module-info.java` file, whereas,
`Automatic-Module-Name` was present in the empty jar's MANIFEST.MF.
4. However, using `maven-jlink-plugin` with a JavaFX application fails since
Automatic modules are not supported in JLink [1]
5. After a brief discussion, it was decided to remove the Automatic Module Name
from non-platform jars [2]
The EA releases were working perfectly after the change was made. However, with
recent JavaFX 17, modular applications are failing to compile with Maven.
The reason behind this lies in the `plexus-java` library used by
`maven-compiler-plugin`:
1. `plexus-java` doesn't allow duplicate entries with same module-name on
module-path
2. For 17, `plexus-java` resolves both empty and platform jar to have the same
module-name
3. However, with `-ea+xx`, `plexus-java` resolves the module name for empty jar
as null and we never discovered the bug until 17 was released
17
---
/home/.m2/repository/org/openjfx/javafx-controls/17/javafx-controls-17.jar
Module Name: javafx.controls
/home/.m2/repository/org/openjfx/javafx-controls/17/javafx-controls-17-linux.jar
Module Name: javafx.controls
17-ea+18
--------
/home/.m2/repository/org/openjfx/javafx-controls/17-ea+18/javafx-controls-17-ea+18.jar
Module Name: null
/home/.m2/repository/org/openjfx/javafx-controls/17-ea+18/javafx-controls-17-ea+18-linux.jar
Module Name: javafx.controls
----X----
This whole experience has made us realised we need to rethink how we package
JavaFX Maven artifacts.
We are still discussing about the approach and naming, and would like to gather
feedback:
1. Instead of 1 module per component, we will have 2 modules (javafx.base.api
and javafx.base.platform)
2. The `javafx.base.api`, unlike empty jar, will contain all generic Java code
3. The `javafx.base.platform` will contain platform-specific native + Java code
4. Current application declare their module-descriptor as:
```
module app {
requires javafx.base;
}
```
5. In future this may be changed depending on how we end up wiring these
modules together:
```
module app {
requires javafx.base [.api or .platform];
}
```
[1] https://www.mail-archive.com/[email protected]/msg123978.html
[2] https://bugs.openjdk.java.net/browse/JDK-8264998