Maven project fails to resolve JavaFX dependencies
Asked Answered
I

3

10

I would need some advice on how to troubleshoot this issue I'm having with my project, so there's not going to be a minimal reproducible code example, as it's not about the code itself.

Maven and Java are properly setup and working on all machines and OSes. Project was initially created with IntelliJ on Linux and working on any Linux machine without issues. However, trying to run mvn clean install on Windows or macOS on the project will always result in the following error:

[ERROR] Failed to execute goal on project RNGame: Could not resolve dependencies for project com.ceebee:RNGame:jar:1.0-SNAPSHOT: The following artifacts could not be resolved: org.openjfx:javafx-controls:jar:${javafx.platform}:21.0.3 (absent), org.openjfx:javafx-graphics:jar:${javafx.platform}:21.0.3 (absent), org.openjfx:javafx-base:jar:${javafx.platform}:21.0.3 (absent), org.openjfx:javafx-fxml:jar:${javafx.platform}:21.0.3 (absent), org.openjfx:javafx-media:jar:${javafx.platform}:21.0.3 (absent): Could not find artifact org.openjfx:javafx-controls:jar:${javafx.platform}:21.0.3 in central (https://repo.maven.apache.org/maven2)

This is my current pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ceebee</groupId>
    <artifactId>RNGame</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>RNGame</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.8.2</junit.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx</artifactId>
            <version>21.0.3</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>21.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>21.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>21.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.32</version>
                <scope>provided</scope>
            </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>20</source>
                    <target>20</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.32</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>com.ceebee.rngame/com.ceebee.rngame.RNGame</mainClass>
                            <launcher>RNGame.sh</launcher>
                            <jlinkZipName>RNGame</jlinkZipName>
                            <jlinkImageName>RNGame</jlinkImageName>
                            <stripDebug>true</stripDebug>
                            <stripJavaDebugAttributes>true</stripJavaDebugAttributes>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>copy-external-resources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/res</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>res</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

I'm on both macOS 13.4.1 and Windows 10. Here is the output of mvn --version for mac including all necessary info:

Apache Maven 3.9.7 (8b094c9513efc1b9ce2d952b3b9c8eaedaf8cbf0) Maven home: /usr/local/Cellar/maven/3.9.7/libexec Java version: 21.0.3, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/21.0.3/libexec/openjdk.jdk/Contents/Home Default locale: en_GB, platform encoding: UTF-8 OS name: "mac os x", version: "13.4.1", arch: "x86_64", family: "mac"

Maven version on Linux is 3.9.6. I haven't found much info on this particular issue online. My environments are set up all the same way on every machine. The project can be build just fine on any other Linux machine, but not Windows/macOS. The related JavaFX artifacts are being downloaded and are present in the .m2 directory, yet Maven can't seem to resolve them. There are no specific Maven settings in place. The hint about {javafx.platform} doesn't help me much, as specifying this property as e.g. <classifier>mac</classifier> doesn't help.

All setups are fresh on Windows/macOS with proper environment variables and java and mvn commands being recognised on the command line/terminal. Any pointers on how to go on about this issue would be appreciated.

Infancy answered 28/5 at 8:20 Comment(21)
Based org.openjfx:javafx-controls:jar:${javafx.platform}:21.0.3 it looks there is something wrong in your pom file ... best would be having a pom file..Sanjak
FYI I have provided a pom. Will shorten OP. Any pointers on how to get "a working pom that works on windows" would be appreciated.Infancy
I disagree with some of the previous comments, some of the detail is important IMO, and it is best to provide the pom.xml in the question rather than offsite.Hillel
I notice that your pom.xml includes a dependency of type <groupId>org.openjfx</groupId><artifactId>javafx</artifactId><version>21.0.3</version><type>pom</type>. While it might work, I am not sure what purpose it serves and don't recommend it (other JavaFX projects I have seen don't do that).Hillel
@Hillel If it is a maven project, then shouldn't mvn package work? That would take a lot of the guesswork out of the problem. GenerationLost did you try the getting started That will generate a project with a pom and you should be able to build it with maven. You could modify the pom to have the correct javafx versions. I think you've improved the question by removing some of the information about the linux setups.Equiponderance
@Equiponderance I think maven fails at an earlier stage, so it probably doesn't matter if it's mvn package or mvn install. My project was generated by IntelliJ (an information I have removed from my OP) and I added dependencies to other FX artifacts as I needed them without prior issues. I was always able to build on Linux already. Creating new projects on e.g. macOS will result in the same issue when setting the JavaFX version to >=17. @Hillel removing the part you've mentioned unfortuntalely makes no difference, I've already tried that.Infancy
@Equiponderance yes, mvn package should work. However it doesn't for the asker. I tried using the pom.xml provided to see if I can get mvn package to work for me in environment (intel Mac), and it worked fine. So whatever the issue is, it would seem to be environmental.Hillel
Does the work-around proposed in my answer (explicitly setting classifiers) work for you?Hillel
@Equiponderance both macOS 13.4.1 and Windows 10. Here is the output of mvn --version including all necessary info: Apache Maven 3.9.7 (8b094c9513efc1b9ce2d952b3b9c8eaedaf8cbf0) Maven home: /usr/local/Cellar/maven/3.9.7/libexec Java version: 21.0.3, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/21.0.3/libexec/openjdk.jdk/Contents/Home Default locale: en_GB, platform encoding: UTF-8 OS name: "mac os x", version: "13.4.1", arch: "x86_64", family: "mac". Let me know if you need any more info, will add this to OP.Infancy
@Equiponderance Thanks for checking on your end, jewelsea suggested something similar, I tried this to no avail. What confuses me the most in all this is that it works on both my Linux machines, so the pom itself seems healthy.Infancy
@Equiponderance I tried the default archetype pom with no additions and I get the same error. JAVA_HOME was actually missing from .bash_profile on mac. Adding it as /usr/local/opt/openjdk, but it won't change the issue with maven. On Windows I've manually set up env variables to point to my local JDK and Maven, so that shouldn't be a problem.Infancy
The next step is to use mvn package -X and paste the full output somewhere. Is it possible you're unable to download the required artifacts?Equiponderance
@Equiponderance here's the output of that on pastebin: pastebin.com/4XV6UWDh The artifacts are in fact being pulled into my local .m2 and I can find for example javafx-controls-22.0.1-mac.jar among all other dependencies defined in the pom.Infancy
Can you try again and include the -U to force an update. It says it is not finding the dependencies, but it isn't trying. Is it possible you're not using the .m2 repository?Equiponderance
@Equiponderance I've also tried the -U switch several times. You're right, it does sound like it might not even use the .m2, which is odd since it's actually pulling the artifacts into the .m2 repository even after I remove it. Where and how can I verify this? echo $M2_HOME points to /Users/myusername/.m2 and I don't have a settings.xml in my .m2, so I assume the default settings are used, for which the repository is set to Default: ${user.home}/.m2/repository. This directory does indeed exist and holds the FX artifacts among other dependencies.Infancy
You can just delete the .m2 directory. It is a cache and will be recreated (you can check the contents after you rebuild and you see that it downloaded lots of stuff there). Doesn't sound like it will make much difference, but I guess you could try it in case there is some corrupted artifact or setting somewhere. Also, JavaFX caches some runtime stuff in ~/.openjfx, you could delete it too and it will be recreated, but again probably not your issue as that later cache is used at runtime, not build time.Hillel
@Hillel I am aware and I've also done that to no avail. Seems like I'm running out of options.Infancy
You should try downgrading to maven 3.9.6, that works fine for me on windows, but 3.9.7 fails to build even the helloworld example from javafx.Equiponderance
@Equiponderance Yes, that did indeed work! I just double checked, my Linux distro's repo also didn't upgrade to Maven 3.9.7 and is still on 3.9.6, that's why I had no issues there. Either way, thank you for your help, I appreciate it.Infancy
I haven't got a Maven 3.9.7 setup at the moment, but I guess I could try it later. I am wondering if mvn package -Djavafx.platform=mac (or another appropriate classifier) will work-around this issue, i.e. explicitly set the unresolved property at the command line.Hillel
@Hillel That works for windows with -Djavafx.platform=win of courseEquiponderance
L
13

I face the exact same issue when using maven 3.9.7. It still works with maven 3.9.6.

A maven ticket already exists https://issues.apache.org/jira/browse/MNG-8131

Lundberg answered 28/5 at 13:30 Comment(7)
Good call! I was using 3.9.6 and didn't think the version made a difference. I tried 3.9.7 and it fails to compile the basic javafx example.Equiponderance
That is indeed the culprit, thank you so much for this! I had absolutely not noticed that my Linux distro's Maven version remained on 3.9.6, hence it working on my Linux machines. Setting things up fresh on macOS and Windows got me the latest version which apparently has this issue. How would one go on about reporting this, or is there already a known issue filed with Apache?Infancy
You can notify the JavaFX team via the openjfx-dev mailing list. For the Apache Maven team, they have a bug reporting process, which is probably the best way I guess.Hillel
Update: The issue seems to be with OpenFX' pom, they have also been informed in the meantime: mail.openjdk.org/pipermail/openjfx-dev/2024-May/047279.htmlInfancy
The issue with the JavaFX pom has been fixed with JavaFX 23-ea+20 (from Maven Central), and it work with maven 3.9.7 again.Phosphorite
JavaFX 23-ea-20 solves the issue for mvn CLI. But previously with JavaFX 21 IntelliJ IDEA would run, but later is not running anymore. I decided to stick to the CLI.Tunicle
The Maven issue that is linked in the text has been fixed in Maven 3.9.8.Cabrilla
H
7

Update: Markus Friedli notes in his answer that the issue is resolved by downgrading from Maven 3.9.7 to 3.9.6

Some of the info in this answer was written before this was known.


This is (currently) not a true answer to your question, but it does provide some background info, and a potential workaround (explicitly setting the classifier to a correct value) which may work for you.

Work-around: Explicitly set classifiers on the pom.xml

Unfortunately this proposed work-around did not work for the asker.

You could work around it by explicitly setting the classifier to an appropriate one for your system from the menu of classifiers I provided above. If you do that, you must choose a classifier that matches your system (e.g. darwin is not a valid classifier, and mac is only for Intel macs, not M1 macs, etc).

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>21.0.3</version>
    <classifier>mac-aarch64</classifier>
</dependency>

Recommendation: Remove the org.openjfx:javafx::pom artifact

Unfortunately this recommendation does not solve the asker's issue, but it is still recommended nonetheless.

I notice that your pom.xml includes a dependency of type pom:

<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>21.0.3</version>
<type>pom</type>. 

While it didn't cause any issues in my environment I don't recommend having that dependency. Other JavaFX projects I have seen don't do that. That pom is supposed to be the parent project for other JavaFX modules, it is what allows the JavaFX modules to by default choose the correct classifier for themselves when you include them. You don't need it as a dependency in your project.

Background Info

The purpose of this info is to explain ${javafx.platform}.

${javafx.platform} is trying to set a classifier.

Classifiers can be used by different projects for different purposes.

JavaFX uses them to provide Maven coordinates to artifact versions for particular platforms, e.g. intel macs, vs m series macs, vs windows x64, etc.

You can find the classifiers by looking at the Maven repository for JavaFX:

There you can see that the classifiers used are:

  • sources -> source code
  • javadoc -> documentation
  • win -> windows x64
  • linux -> linux x64
  • linux-aarch64 -> linux arm (64 bit)
  • mac -> intel Mac
  • mac-aarch64 -> M series Mac
  • no classifier -> empty shell jar

All of the code (both Java and native) is actually in the classified artifacts, not the unclassified empty shell jar. JavaFX Maven artifacts are a bit weird in this way because most projects put their Java code in the unclassified jar. JavaFX doesn't do that, because there is different Java and native code in each of the classified Jars. For example, in the Mac Jars there is both native and Java code to support the Mac system menu which isn't needed in any other jar.

When the Maven artifacts are used by a running JavaFX app, it will extract the native components out of the artifacts at runtime and put them in a local cache directory. That is different than when you use the JavaFX SDK, where the SDK jars don't include the native components, and the native components are loaded from the SDK lib directory.

Normally, you don't need to specify the classifier when you add the dependency (unless you want to get dependencies for platforms different than your development system).

If you look at the pom.xml for a JavaFX dependency.

You can see it adds a ${javafx.platform} classifier:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.openjfx</groupId>
  <artifactId>javafx-graphics</artifactId>
  <version>22.0.1</version>
  <parent>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx</artifactId>
    <version>22.0.1</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-graphics</artifactId>
      <version>22.0.1</version>
      <classifier>${javafx.platform}</classifier>
    </dependency>
    <dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-base</artifactId>
      <version>22.0.1</version>
    </dependency>
  </dependencies>
</project>

Normally, Maven can resolve the ${javafx.platform} property and set it to the appropriate classifier to use for the machine you are building on.

It does this because each of the JavaFX pom.xml files uses a common parent pom that activates a profile that sets the ${javafx.platform} property depending on your architecture. This is a simplified version of the pom.xml to demonstrate how it does that:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx</artifactId>
    <version>22.0.1</version>
    <packaging>pom</packaging>
    <name>openjfx</name>
    <description>OpenJFX JavaFX</description>
    <properties>
        <javafx.version>22.0.1</javafx.version>
    </properties>
    <profiles>
        <profile>
            <id>linux-x86_64</id>
            <activation>
                <os>
                    <name>linux</name>
                    <arch>amd64</arch>
                </os>
            </activation>
            <properties>
                <javafx.platform>linux</javafx.platform>
            </properties>
        </profile>
        <profile>
            <id>linux-aarch64</id>
            <activation>
                <os>
                    <name>linux</name>
                    <arch>aarch64</arch>
                </os>
            </activation>
            <properties>
                <javafx.platform>linux-aarch64</javafx.platform>
            </properties>
        </profile>
        <profile>
            <id>macosx-x86_64</id>
            <activation>
                <os>
                    <name>mac os x</name>
                    <arch>x86_64</arch>
                </os>
            </activation>
            <properties>
                <javafx.platform>mac</javafx.platform>
            </properties>
         </profile>
         <profile>
            <id>macosx-aarch64</id>
            <activation>
                <os>
                    <name>mac os x</name>
                    <arch>aarch64</arch>
                </os>
            </activation>
            <properties>
                <javafx.platform>mac-aarch64</javafx.platform>
            </properties>
         </profile>
        <profile>
            <id>windows-x86_64</id>
            <activation>
                <os>
                    <family>windows</family>
                    <arch>amd64</arch>
                </os>
            </activation>
            <properties>
                <javafx.platform>win</javafx.platform>
            </properties>
        </profile>
        <profile>
            <id>javafx.platform.custom</id>
            <activation>
                <property>
                    <name>javafx.platform</name>
                </property>
            </activation>
            <properties>
                <javafx.platform>${javafx.platform}</javafx.platform>
            </properties>
        </profile>
    </profiles>
</project>

For whatever reason (again I don't know what), that mechanism for replacing the ${javafx.platform} with the classifier for your system did not work.

Hillel answered 28/5 at 8:53 Comment(1)
Thanks a lot for the insight in this, this information is really appreciated. I was also expecting the platform to be inferred by maven on it's own. However, even providing a classifier myself in the pom doesn't help. In my case that would be <classifier>mac</classifier> as I am indeed on an Intel mac.Infancy
A
4

The discussion was very helpful.

I moved to Maven 3.9.7 several days ago and all my projects with OpenJFX 22.0.1 failed to build.

I created tiny project with one only file pom.xml (see below) and tested it on Windows 11 and Ubuntu 24.04 with Oracle JDK 22.0.1 and different version of Maven and OpenJFX.

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.olexyarm</groupId>
        <artifactId>TestMaven</artifactId>
        <version>1.0.0</version>
        <packaging>jar</packaging>
        <name>TestMaven</name>
        <properties>
            <javafx.version>22.0.1</javafx.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-controls</artifactId>
                <version>${javafx.version}</version>
            </dependency>
        </dependencies>
    </project>

Build with Maven 3.9.7 and OpenJFX 22, 22.0.1, 22.0.2 failed all the time with error below:

[ERROR] Failed to execute goal on project TestMaven: Could not resolve dependencies for project com.olexyarm:TestMaven:jar:1.0.0: The following artifacts could not be resolved: org.openjfx:javafx-cont
rols:jar:${javafx.platform}:22.0.1 (absent), org.openjfx:javafx-graphics:jar:${javafx.platform}:22.0.1 (absent), org.openjfx:javafx-base:jar:${javafx.platform}:22.0.1 (absent): Could not find artifact
 org.openjfx:javafx-controls:jar:${javafx.platform}:22.0.1 in central (https://repo.maven.apache.org/maven2) -> [Help 1]

Build with Maven 3.9.6 and OpenJFX 22, 22.0.1, 22.0.2 was successful all the time.

Build with Maven 3.9.7 and OpenJFX 23-ea+22 was successful.

Arceliaarceneaux answered 17/6 at 23:3 Comment(1)
Maven 3.9.9 with OpenJFX 22.0.2 or 21.0.4 works.Styliform

© 2022 - 2024 — McMap. All rights reserved.