Issue
I am trying to include JavaFX dependencies for mac OS only, but win are still downloaded. Same goes with linux deps.
pom.xml:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11.0.2</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
<classifier>linux</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11.0.2</version>
<classifier>linux</classifier>
</dependency>
Maven deps:
pom.xml:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11.0.2</version>
<classifier>mac</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
<classifier>mac</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11.0.2</version>
<classifier>mac</classifier>
</dependency>
Maven deps:
How to remove win JavaFX libs or make Maven not do download them?
Same thing happens when i use Ubuntu (Linux). When i classify i want mac libraries, linux libs are downloaded also etc.
Maybe worth noting i am using Eclipse IDE 2021-03 both on Windows and Ubuntu.
Solution
When you use JavaFX via Maven artifacts from Maven Central, you typically add to your pom:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
</dependency>
</dependencies>
and it just works on your platform, no need for classifiers.
Now if you check the dependencies, and you are on Linux for instance, you will find:
$ mvn dependency:tree
[INFO] org.openjfx:javafx-controls:jar:16:compile
[INFO] +- org.openjfx:javafx-controls:jar:linux:16:compile
[INFO] \- org.openjfx:javafx-graphics:jar:16:compile
[INFO] +- org.openjfx:javafx-graphics:jar:linux:16:compile
[INFO] \- org.openjfx:javafx-base:jar:16:compile
[INFO] \- org.openjfx:javafx-base:jar:linux:16:compile
Same if you are on Windows or Mac OS.
You can guess how javafx-controls
gets the traverse dependencies: via its pom. But how does it get the classifier?
Let's check the pom:
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
<parent>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>16</version>
</parent>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
<classifier>${javafx.platform}</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>16</version>
</dependency>
</dependencies>
</project>
As you can see, there is already a classifier applied, based on a ${javafx.platform}
maven property.
That property is resolved via a the parent pom:
<parent>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>16</version>
</parent>
If you check its content:
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>16</version>
<packaging>pom</packaging>
<name>openjfx</name>
<description>OpenJFX JavaFX</description>
<url>https://openjdk.java.net/projects/openjfx/</url>
<properties>
<javafx.version>16</javafx.version>
</properties>
<dependencyManagement></dependencyManagement>
<profiles>
<profile>
<id>linux</id>
<activation>
<os>
<name>linux</name>
</os>
</activation>
<properties>
<javafx.platform>linux</javafx.platform>
</properties>
</profile>
// windows profile
// mac profile
...
So that means that there is a profile that gets activated based on your current platform, and that sets automatically the property ${javafx.platform}
, which in turn set your dependencies classifier.
So what happens if you add a different classifier to your JavaFX dependency (and you are on Linux for instance):
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
<classifier>win</classifier>
</dependency>
</dependencies>
you will get:
$ mvn dependency:tree
[INFO] \- org.openjfx:javafx-controls:jar:win:16:compile
[INFO] +- org.openjfx:javafx-controls:jar:linux:16:compile
[INFO] \- org.openjfx:javafx-graphics:jar:16:compile
[INFO] +- org.openjfx:javafx-graphics:jar:linux:16:compile
[INFO] \- org.openjfx:javafx-base:jar:16:compile
[INFO] \- org.openjfx:javafx-base:jar:linux:16:compile
The dependency is correct, you get the win version first, but then its own pom has a dependency on javafx-controls:${javafx.platform}
, which is resolved based on your platform (i.e. Linux), and that explains why you get the platform artifact as well.
I don't see how this can be avoided, as you can't disable the profile activation inside the dependency's pom.
EDIT
If you keep reading the javafx parent pom, there is this profile:
<profile>
<id>javafx.platform.custom</id>
<activation>
<property>
<name>javafx.platform</name>
</property>
</activation>
<properties>
<javafx.platform>${javafx.platform}</javafx.platform>
</properties>
</profile>
which is a profile that gets activated if javafx.platform
is set, and it overrides previous values of the ${javafx.platform} value.
So I've just tried on Linux (without adding any classifier to the dependency):
$ mvn -Djavafx.platform=win dependency:tree
[INFO] com.gluonhq.samples:hellopi:jar:1.0.0-SNAPSHOT
[INFO] \- org.openjfx:javafx-controls:jar:16:compile
[INFO] +- org.openjfx:javafx-controls:jar:win:16:compile
[INFO] \- org.openjfx:javafx-graphics:jar:16:compile
[INFO] +- org.openjfx:javafx-graphics:jar:win:16:compile
[INFO] \- org.openjfx:javafx-base:jar:16:compile
[INFO] \- org.openjfx:javafx-base:jar:win:16:compile
and that works, no more platform classifiers.
Still, your IDE might show platform dependencies, but as long as you run with that property (like mvn -Djavafx.platform=win javafx:run
) that should work.
Answered By - José Pereda
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)