I am having a problem creating a .jar file for my JAVAFX Program.
important info:
JAVAFX Version: 17
JAVA Version: 17
IDE: Intellij
Project Uses Maven
..................................................................................................................................................................................................................................................
file structure:
module File:
module A_DevicesInfoCardsManager {
requires javafx.controls;
requires javafx.fxml;
requires javafx.graphics;
requires java.sql;
opens application to javafx.graphics, javafx.fxml, javafx.base, javafx.controls,java.sql;
}
POM File:
<?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>application</groupId>
<artifactId>DevicesInfoCards</artifactId>
<version>1.0-SNAPSHOT</version>
<name>DevicesInfoCards</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.1.0</version>
</dependency>
<dependency>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<version>11.3.2</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.synedra</groupId>
<artifactId>validatorfx</artifactId>
<version>0.1.13</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>12.2.0</version>
</dependency>
<dependency>
<groupId>org.kordamp.bootstrapfx</groupId>
<artifactId>bootstrapfx-core</artifactId>
<version>0.4.0</version>
</dependency>
<dependency>
<groupId>eu.hansolo</groupId>
<artifactId>tilesfx</artifactId>
<version>11.48</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</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>application/application.Main
</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I created a jar Like this :
when I ran the jar like this:
I got the following error:
Error: JavaFX runtime components are missing, and are required to run this application
and when I ran it from the terminal using the command java --module-path C:\Users\aenas\Desktop\javafx-sdk-17.0.1 --add-modules javafx.fxml,javafx.graphics,java.sql -jar DevicesInfoCards.jar
I got the following error
Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.graphics not found
and When I tried the following command:
java --module-path C:\Users\aenas\Desktop\javafx-sdk-17.0.1 -jar DevicesInfoCards.jar
I got the following Error
Error: LinkageError occurred while loading main class application.Main
java.lang.UnsupportedClassVersionError: application/Main has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
I have seen many tutorials and read many answers here in SO, but I did not get anything new.
one of the sollutions was to add the following to he POM file:
<packaging>jar </packaging>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>application.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
I could not solve the last error, although I did compile the program using java 11, but the same error occurred.
I did that (adding the code to the POM file) but I also got the following error:
Error: Could not find or load main class application.Main
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
I also tried to create a new class with a main method, and let it call the Main
cless, but this did not work, and I got the following error:
no main manifest attribute, in C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven\out\artifacts\DevicesHistoryCards_Maven_jar\DevicesHistoryCards_Maven.jar
Process finished with exit code 1
although I have changed all <mainclass></mainclass>
tegs in my POM file to the correct new main class, I still getting the same error.
Thank you in advance for your help;
CodePudding user response:
Reopened the question at your request.
I believe the question is, at its core, a duplicate of:
because, as in the duplicate, you are:
- Using Maven.
- Using JavaFX.
- Hoping to create an executable jar.
However, it is perhaps worthwhile adding an answer to specifically outline the specific things you must change in your project to get it to work.
Not Recommended Approach
Creating a fat jar is not a currently supported way to package a JavaFX application.
A template for a fat jar with JavaFX is provided by the openjfx.io project.
The pom.xml project file is here.
If unclear about the steps below, study the linked question on maven shading of JavaFX and the sample openjfx.io project.
Steps to transform your project to one which can be packed as a fat jar:
It should be a non-modular project (delete your module-info.java)
It requires a separate launcher class (create one)
It requires merging of jars using the maven shade plugin (use that)
To make it cross platform you need to provide classified dependencies (add them)
To support M1 macs, you need
- An additional classifier dependency mac-aarch64 (add that)
- JavaFX 17.0.2 (upgrade to that).
You need to use Maven dependencies not the JavaFX SDK (you can delete the SDK).
- The maven artifacts are different from the jars shipped in the SDK.
- The maven artifacts include native code, the jars in the SDK do not, native code is provided in separate native library files in the SDK distribution.
- Through a separate download, you can obtain jmod files that include java code and native code, but those aren't compatible with the Maven shade process, those can be used for the jlink process (as can the maven artifacts).
Specify the main class using a transformer in the shade plugin, not using the maven-jar-plugin (you should remove the maven-jar-plugin section).
To run just use the following command and nothing else:
java -jar <yourjar>.jar
This assumes the user has correctly:
- Installed a compatible JRE version.
- Configured the system path to include the directory containing the appropriate
java
binary file.
Don't specify paths to the JavaFX SDK for anything anymore, it is no longer needed to support this development pipeline.
Don't specify module-paths because you are just running your app and its dependencies off the classpath (which is your jar file).
- only the core JRE is on the modulepath and that is implicit as the core JRE classes are on the JRE module boot path.
You are compiling for Java 17 to Java 17 bytecode (your maven-compiler-plugin source and target are 17)
- so you must run it against a Java 17 version or it won't work, you will get byte code errors.
Use
mvn package
to package your application, do not use the built-in artifact generators in an IDE- Do not use the Idea or Eclipse artifact generation systems.
- The IDE artifact generation systems do not currently support correctly generating executable jars which include JavaFX runtime components, they will generate artifacts, but they will exhibit errors if you try to execute them.
I may have missed a step, but, if I did not, and you do all that, it will work for JRE/JavaFX 17.0.2. The resultant jar can be executed using a compatible pre-installed JRE on a compatible platform.
Recommended Approach
It is recommended instead to build a jlink
image:
- Use the javafx-maven-plugin
mvn javafx:jlink
command- Assemble to a zip by setting the
jlinkZipName
parameter for the javafx-maven-plugin. - Ensure you have a completely modular application:
- Define a
module-info.java
file in your app. - Ensure that all of your dependencies also define a
module-info.java
file.
- Define a
- Assemble to a zip by setting the
- To run, extract the zip and use the jlink created launch script.
OR, you can use jpackage
to create a native installer, see for instance:
JPackageScriptFX for a non-modular app,
OR
the Akman jpackage-maven-plugin for a modular app.
Creating distributions using jlink or jpackage are supported configurations. It is easier and more reliable for a developer to create a jlink image than to create a fat jar.
It is easier and more reliable for users of the application to use the application as they do not need to obtain and install a compatible Java runtime in addition to your application.
Further information on packaging is provided in:
CodePudding user response:
Try to create a new Class with a main method that calls the main Method of your Application class and use it as entry point.