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;
UPDATE
what I did is that I deleted the module info file, deleted all javafx dependances from the POM file, so my POM looks like that now:
<?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>DevicesHistoryCards_Maven</artifactId>
<version>1.0-SNAPSHOT</version>
<name>DevicesHistoryCards_Maven</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.1</junit.version>
</properties>
<dependencies>
<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>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>application.MainLauncher</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</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.MainLauncher
</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>
and when I ran mvn package
I got the following output:
PS C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2> mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------< application:DevicesHistoryCards_Maven >----------------
[INFO] Building DevicesHistoryCards_Maven 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ DevicesHistoryCards_Maven ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 6 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ DevicesHistoryCards_Maven ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ DevicesHistoryCards_Maven ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ DevicesHistoryCards_Maven ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ DevicesHistoryCards_Maven ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ DevicesHistoryCards_Maven ---
[INFO]
[INFO] --- maven-shade-plugin:3.2.4:shade (default) @ DevicesHistoryCards_Maven ---
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2\target\DevicesHistoryCards_Maven-1.0-SNAPSHOT.jar with C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2\target\DevicesHistoryCards_Maven-1.0-SNAPSHOT-shaded.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.692 s
[INFO] Finished at: 2022-02-17T13:40:42+03:00
[INFO] ------------------------------------------------------------------------
but when I ran java -jar DevicesHistoryCards_Maven2.jar
I got the following:
Error: Unable to access jarfile DevicesHistoryCards_Maven.jar
so why cant I access it, and where is it created ?
This answer provides two alternatives for packaging and distributing your application, one (creating a fat jar file) is not recommended, the other (using jlink or jpackage) is recommended.
Related Question
I believe the question is, at its core, a duplicate of:
because, as in the duplicate, you are:
However, I have added an answer to outline specific things you must change in your project to get it to work.
Not Recommended Approach: Fat JAR
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:
Define all of the required JavaFX dependencies for your applicatoin in the pom.xml file.
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
You need to use Maven dependencies not the JavaFX SDK (you can delete the SDK).
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).
Use mvn package
to package your application, do not use the built-in artifact generators in an IDE
The mvn package
step will generate a warning, though it will likely still work:
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.
To run just use the following command and nothing else:
java -jar <yourjar>.jar
This assumes the user has correctly:
java
binary file.The execution step will generate a warning, though it will likely still work:
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @14c24f4c'
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).
You are compiling for Java 17 to Java 17 bytecode (your maven-compiler-plugin source and target are 17)
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: jlink or jpackage
It is recommended instead to build a jlink
image:
mvn javafx:jlink
command
jlinkZipName
parameter for the javafx-maven-plugin.module-info.java
file in your app.module-info.java
file.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.
External Packaging Resources
Further information on packaging is provided in:
FAQ
deleted all javafx dependances from the POM file
Don't do that, include the JavaFX dependencies used by your application in the pom.xml file (and any required 3rd party dependencies).
You don't need to include JavaFX dependencies you don't use
You don't need to explicitly list dependencies which will be imported transitively, such as javafx-base.
where is the
.jar
file created by the commandmvn package
This is listed in your log file when you run the package step:
Replacing C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2\target\DevicesHistoryCards_Maven-1.0-SNAPSHOT.jar with C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2\target\DevicesHistoryCards_Maven-1.0-SNAPSHOT-shaded.jar
It created both shaded and unshaded jars, then replaced the unshaded jar with the shaded jar.
To see the contents of a jar file, you can run:
jar tvf <your-jar-file>.jar
In your example do:
cd C:\Users\aenas\IdeaProjects\demo2\DevicesHistoryCards_Maven2\target
jar tvf DevicesHistoryCards_Maven-1.0-SNAPSHOT.jar
There will be lot of stuff in there. The jar will include your app code, all code from your dependent libraries, all the JavaFX java code and the JavaFX native code (e.g. Windows DLLs) for the classified JavaFX dependencies that you defined in your pom.xml to match your target distribution platforms.
If you use the shade definition from the openjfx fat jar sample pom.xml, it uses a classifier for the shaded jar and outputs it in a separate directory, so the shaded jar does not overwrite the target jar but instead creates a separate jar in a <project directory>/shade
folder.
You don't need to use the classifier for the shaded jar if you don't want to.
For more info see:
By default, the plugin will replace the project's main artifact with the shaded artifact. If both the original and the shaded artifact should be installed/deployed to the repository, one can configure the plugin to attach the shaded artifact as a secondary artifact
Cloning the OpenJFX Sample Project to verify your environment
If you are still having issues clone the openjfx sample project from git and try building it to ensure that you can get the packaging to work correctly in your environment when using a known good project.