4

I'm using Java 8 with JavaFX. When I package my executable JAR with maven, the executable JAR works fine using Java 8. However, if I run the JAR with e.g. Java 13, I get the following error:

Error: Could not find or load main class ApplicationLauncherClient
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application

This is presumably caused by JavaFX not being bundled with the JRE/JDK anymore since Java 11.

My pom.xml build configuration looks as follows:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>ApplicationLauncherClient</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

My goal is to instruct maven to build a JAR which can run on any Java version greater than or equal to 8 by including JavaFX in the executable JAR.

I did not succeed with following the instructions in this answer (by e.g. adding the JavaFX plugin to my pom.xml). Including OpenJFX as dependency also did not work, I still receive the same error.

5
  • 1
    The zenjava javafx maven plugin you linked from your question is outdated, you should use the org.openjfx plugin, as shown in the [run HelloWorld via Maven] post and you don't need to create an assembly using the assembly plugin. Commented Nov 21, 2019 at 12:49
  • Your goal to have a single jar to "My goal is to instruct maven to build a JAR which can run on any Java version greater than or equal to 8 by including JavaFX in the executable JAR." may prove difficult, JavaFX is usually part of the JRE for Java 8 distributions which support it, it is only designed to be a separate library in later releases (e.g 11+). Commented Nov 21, 2019 at 12:52
  • You may wish create a runtime image (which include the JRE) rather than try to create an executable JAR that can work with pre-installed JREs. Commented Nov 21, 2019 at 12:56
  • Oops, missed a link to HelloWorld via Maven in an earlier comment. Commented Nov 21, 2019 at 12:59
  • Another alternative is jpackage, when that is available. Commented Nov 21, 2019 at 13:02

1 Answer 1

1

I use the javafx-maven-plugin and the maven-shade-plugin like so:

    <build>
        <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
          <configuration>
            <release>11</release>
            <target>8</target>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.openjfx</groupId>
          <artifactId>javafx-maven-plugin</artifactId>
          <version>0.0.3</version>
          <configuration>
            <mainClass>Your_main_class</mainClass>
          </configuration>
      </plugin>
                <plugin>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>3.2.1</version>
                    <executions>
                    <execution>
                        <phase>package</phase>
                    <goals>
                    <goal>shade</goal>
                    </goals>
                    <configuration>
                    <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                      <mainClass>Your_main_class_starter</mainClass>
                    </transformer>
                    </transformers>
                    </configuration>
                    </execution>
                    </executions>
                </plugin>              
    </plugins>
</build>

Your_main_class is something like this:

public class App extends Application {

private static Scene scene;

@Override
public void start(Stage stage) throws IOException {
    Parent mainForm = FXMLLoader.load(getClass().getResource("mainForm.fxml"));
    scene = new Scene(mainForm , 425, 275);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch();
}
}

And Your_main_class_starter looks like this:

public class LaunchApp {
public static void main(String[] args) {
    App.main(args);
}

So Your_main_class_starter does nothing else but calling your main class.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.