Search code examples
javamavenintellij-ideajavafxjava-8

JavaFX Maven Assembly plugin keeps packaging to wrong JDK version


I created an app in IntelliJ that allows me to read epubs without being to noticable when someone passes by my mac at work (iBook tends to stand out).. it's basically just an undecorated JavaFX window with a label that get fed a single paragraph tag in the epub at a time, controlled by the arrow keys to move forward and backwards.. The app compiles and packages great on my pc (JDK21) but when I try to build it for 1.8 (the java version at work) it keeps complaining that the app has been compiled in a newer version (55) than the version on the mac (52)..

it cleans, builds, packages without errors.. but when I try with the command line "java -jar readerfx.jar" it throws the error..

My guess is some version in the dependencies of the POM file is overriding the compiler version but I'm not sure what..

this is my POM.xml:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.reader</groupId>
    <artifactId>readerfx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>13</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>13</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.parsers</groupId>
            <artifactId>jaxp-api</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>xml-apis</groupId>
            <artifactId>xml-apis</artifactId>
            <version>1.0.b2</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.reader.Launcher</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                         <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

What I tried so far:

  • downloaded, extracted and set my HOME and path variables to a 1.8 version of JAVA (openlogic-openjdk-8u402-b06-windows-64)
  • inside my IntelliJ settings, under Project, set my "SDK" to 1.8
  • inside my IntelliJ settings, under Project, set my "Language level" to 8
  • inside my IntelliJ settings, under Modules, set "Module SDK" to "Project SDK 1.8"
  • created a Launcher app that launches the main app
  • in my POM.xml file changed the "source" and "target" variables inside my maven-compiler-plugin configuration to 1.8
  • tried removing the depedency for "javafx-controls" and "javafx-fxml" since java 1.8 still had JavaFX in it's library but then it couldn't find the class javaFX.Application.application so I put them back in..
  • found somewhere online I could add a "version" and "target" to the configuration of the maven-assembly-plugin but when I add them IntelliJ says "Element source is not allowed here"

Solution

  • You are trying to run your application on an incompatible JDK

    As noted by James_D in the comments, JavaFX 13 is incompatible with JDK 8.

    Gluon provides a handy table of the minimum Java runtime version required to support each major JavaFX release.

    Summary:

    • min JRE required for JavaFX 11-19 -> JRE 11.
    • min JRE required for JavaFX 20-23 -> JRE 17.

    JDK 8 includes JavaFX in some distributions (e.g. older Oracle distributions), but not in others (many JDK 8 OpenJDK distributions).

    Because you tried this and it did not work:

    tried removing the depedency for "javafx-controls" and "javafx-fxml" since java 1.8 still had JavaFX in it's library but then it couldn't find the class javafx.application.Application

    (I changed the class not found capitalization in this quote from your original as I assume you just mistyped).

    This means the JDK you are using does not include JavaFX. For Windows (as far as I know), there is no way to add JavaFX to a version of JDK 8 that was not built to include JavaFX from the start (which is your case).

    Recommended solution

    I recommend you create a runtime distribution of your application using jlink.

    That way you don't rely on a pre-installed Java version.

    Instructions for doing that are in the "Runtime Images" section of the JavaFX getting started documentation. You can use the openjfx javafx-maven-plugin (instead of the maven-assembly-plugin) to build a zip distribution of the jlink image. Then all you do is unzip the jlink image on your target machine and run it via the included shell script that jlink created.