我在為我的 JAVAFX 程式創建 .jar 檔案時遇到問題。
重要資訊:
JAVAFX 版本:17
JAVA版本:17
IDE:Intellij
專案使用 Maven
..................................................... ..................................................... ..................................................... ..................................................... ………………………………………………………………………………………………………………………………………………
檔案結構:

模塊檔案:
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 檔案:
<?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>
我創建了一個像這樣的罐子:

當我像這樣運行罐子時:

我收到以下錯誤:
Error: JavaFX runtime components are missing, and are required to run this application
當我使用命令從終端運行它時 java --module-path C:\Users\aenas\Desktop\javafx-sdk-17.0.1 --add-modules javafx.fxml,javafx.graphics,java.sql -jar DevicesInfoCards.jar
我收到以下錯誤
Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.graphics not found
當我嘗試以下命令時:
java --module-path C:\Users\aenas\Desktop\javafx-sdk-17.0.1 -jar DevicesInfoCards.jar
我收到以下錯誤
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
我在這里看過很多教程并閱讀了很多答案,但我沒有得到任何新東西。
解決方案之一是將以下內容添加到 POM 檔案中:
<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 ?
uj5u.com熱心網友回復:
這個答案為打包和分發您的應用程式提供了兩種選擇,一種(創建胖 jar 檔案)不推薦,另一種(使用 jlink 或 jpackage)推薦。
相關問題
我相信這個問題的核心是:
- 缺少 Maven Shade JavaFX 運行時組件
因為,就像在副本中一樣,您是:
- 使用 Maven。
- 使用 JavaFX。
- 希望創建一個可執行的jar。
但是,也許值得添加一個答案來具體概述您必須在專案中更改以使其正常作業的具體內容。
不推薦的方法:Fat JAR
創建 fat jar不是當前支持的打包 JavaFX 應用程式的方法。
openjfx.io 專案提供了一個帶有 JavaFX 的 fat jar 模板。
pom.xml 專案檔案在這里。
如果不清楚以下步驟,請研究有關 JavaFX 的 maven shading 和示例 openjfx.io 專案的鏈接問題。
將您的專案轉換為可以打包為胖罐子的步驟:
在 pom.xml 檔案中為您的應用程式定義所有必需的 JavaFX 依賴項。
- Maven 將傳遞匯入,因此您不需要直接依賴于低級工件,例如 javafx-base,只需要高級工件,例如 javafx-controls 和 javafx-fxml(如果您使用的話)。
它應該是一個非模塊化專案(洗掉你的 module-info.java)
它需要一個單獨的啟動器類(創建一個)
它需要使用 maven shade 插件合并 jars(使用它)
要使其跨平臺,您需要提供分類依賴項(添加它們)
要支持 M1 mac,您需要
- 額外的分類器依賴 mac-aarch64(添加)
- JavaFX 17.0.2 (升級到那個)。
您需要使用 Maven 依賴項而不是 JavaFX SDK(您可以洗掉 SDK)。
- maven 工件與 SDK 中提供的 jars 不同。
- maven 工件包括本機代碼,SDK 中的 jar 不包含本機代碼,本機代碼在 SDK 發行版中單獨的本機庫檔案中提供。
- 通過單獨下載,您可以獲得包含 java 代碼和本機代碼的 jmod 檔案,但這些檔案與 Maven shade 行程不兼容,可用于 jlink 行程(maven 工件也可以)。
使用shade plugin 中的轉換器指定主類,而不是使用 maven-jar-plugin(您應該洗掉 maven-jar-plugin 部分)。
Use
mvn packageto 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.
The
mvn packagestep 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>.jarThis assumes the user has correctly:
- Installed a compatible JRE version.
- Configured the system path to include the directory containing the appropriate
javabinary file. - The user's current directory is the directory containing the shaded jar.
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).
- 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.
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:
- Use the javafx-maven-plugin
mvn javafx:jlinkcommand- Assemble to a zip by setting the
jlinkZipNameparameter for the javafx-maven-plugin. - Ensure you have a completely modular application:
- Define a
module-info.javafile in your app. - Ensure that all of your dependencies also define a
module-info.javafile.
- 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.
External Packaging Resources
Further information on packaging is provided in:
- Stackoverflow JavaFX tag wiki
- openjfx.io Runtime image documentation
- How to create a standalone .exe in Java (that runs without an installer and a JRE)
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
.jarfile 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:
attaching the shaded artifact
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.
uj5u.com熱心網友回復:
嘗試使用呼叫應用程式類的主要方法的主要方法創建一個新類,并將其用作入口點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/427773.html
標籤:java maven intellij-idea javafx 可执行jar
