以前有寫過接手 JavaFX 專案的筆記。這篇則是從 0 建置 JavaFX 後的筆記紀錄。
我這次使用以下面的指令建立 javaFX 專案(windows 的話要把\改成^):
mvn archetype:generate \
-DarchetypeGroupId=org.openjfx \
-DarchetypeArtifactId=javafx-archetype-simple \
-DarchetypeVersion=0.0.6 \
-DgroupId=com.example \
-DartifactId=jfxsample \
-Dversion=0.0.0-SNAPSHOT \
-Djavafx-version=17.0.14
生出來的專案架構如下:
│ pom.xml
│
└─src
└─main
└─java
│ module-info.java
│
└─com
└─example
App.java
SystemInfo.java
如果我執行 mvn javafx:run,可以啟動專案。
但是 mvn package的話,執行
java -jar target/jfxsample-0.0.0-SNAPSHOT.jar會出現以下錯誤訊息
Error: Unable to access jarfile target/jfxsample-0.0.0-SNAPSHOT.jar
如果你的 jre 是中文版,錯誤訊息則會是
target/jfxsample-0.0.0-SNAPSHOT.jar 中沒有主要資訊清單屬性
解決方法
其實編譯出來的 target/jfxsample-0.0.0-SNAPSHOT.jar 本身可以執行,不過要加上 module-path 、 add-modules,這太過麻煩,我自己也沒試試成功,所以請直接去網路上找。
除此之外,解法有 2 種:
解法 1. 修改編譯方式,使之編譯成可執行的 .jar
首先是 App.java,它內容如下:
package com.example;
// import 省略
public class App extends Application {
@Override
public void start(Stage stage) {
// 中略
}
public static void main(String[] args) {
launch();
}
}
因為有 public static void main(String[] args) method,所以直覺上會以為只要告知生出來的 jar main class 是 com.example.App 就好。
可是com.example.App 是繼承 javafx.application.Application 的 class,根據 AI (Claude Opus 4.5)的說法, JavaFX 會在啟動時檢查模組系統,發現不是從模組化環境啟動就會報錯。
最簡單的解法是另外建立一個 main class,例如
public class Launcher {
public static void main(String[] args) {
App.main(args);
}
}
然後修改 pom,在 build > plugins 加上以下 plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.Launcher</mainClass> <!-- 根據 Launcher class 自行調整 -->
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
解法 2. 使用 mvn javafx:jlink 編譯
第二種方式是修改 javafx plugin,如下:
| 原本的 javafx plugin | 修改後的 |
|---|---|
|
|
修改後,執行 mvn javafx:jlink 後, 執行 target/jfxsample/bin/jfxsample.bat 即可啟動程式
因為我是 windows,所以才是執行這個檔案,如果是 mac / Linux 要另外在自己的環境編譯。
如果要把整個編譯好的程式給別人的話,給他 target/jfxsample 資料夾即可;javafx:jlink 也有將編譯好的程式壓縮,位於 target/jfxsample.zip
如果要用 jpackage 打包成安裝檔,jpackage 指令如下(以下是編譯成 .msi 安裝檔,根據自己的需求自行調整)
jpackage --type msi \
--name JfxSample \
--app-version 1.0.0 \
--vendor "Example Inc." \
--runtime-image target/jfxsample \
--module com.example/com.example.App \
--dest target/installer
如果要將 jpackage 加入至 pom,可參閱先前的筆記的《jpackage》章節。
補充
以下是 javafx:jlink 的各樣參數,來源是javafx-maven-plugin 的 github README,使用 ChatGPT 5.3 翻譯、整理成表格
| 參數 | 數值 | 默認值 | 說明 |
|---|---|---|---|
| stripDebug | false / true | false | 移除除錯資訊(debug information)。 |
| stripJavaDebugAttributes | false / true | false | 移除 Java 除錯屬性(Java 13 之後支援)。 |
| compress | 0 / 1 / 2 | 0 | 設定資源壓縮等級。 |
| noHeaderFiles | false / true | false | 移除產生的 runtime image 中的 includes 目錄。 |
| noManPages | false / true | false | 移除產生的 runtime image 中的 man 目錄。 |
| bindServices | false / true | false | 加入綁定服務(bind services)選項。 |
| ignoreSigningInformation | false / true | false | 忽略簽章資訊(signing information)。 |
| jlinkVerbose | false / true | false | 啟用 verbose 模式輸出詳細資訊。 |
| launcher | 自訂設定 |
編譯好後的執行檔名稱。 例如
如果沒有值,就不會編譯出執行檔出來。 |
|
| jlinkImageName | 自訂字串 | image | 產生的 runtime image 資料夾名稱。 |
| jlinkZipName | 自訂字串 | 若有設定就會將產生的 runtime image 打包為 zip,並以 jlinkZipName 的值作為 .zip 檔的名稱。 | |
| jlinkExecutable | jlink 完整位置或執行檔名稱 | PATH 中的 jlink |
指定 jlink 執行檔位置(若在 PATH 中可只填名稱)。 |
| jmodsPath | 路徑 | 無 | 使用本地 JavaFX SDK 時,指定 JavaFX jmods 的位置。 |
參考資料
Mihalceanu , A. (2023, November 14). Package a JavaFX Application as a Platform Specific Executable. Inside Java. https://inside.java/2023/11/14/package-javafx-native-exec/
Onhhkj. (2024, June 25). 关于jdk9 的模块化及以上启动javafx 不使用--Add-Modules方式,如何使用引导类启动及其原理简单分析及报错缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序 问题解决. CSDN. https://blog.csdn.net/u010022461/article/details/139926021
Step-by-Step Guide: Build Executable JAR with JavaFX 11 from Maven (Fix NoClassDefFoundError). (2025, November 7). JavaThinking.Com. https://www.javathinking.com/blog/build-executable-jar-with-javafx11-from-maven/
參考用 AI
- ChatGPT 5.3
- Claude Opus 4.5
沒有留言:
張貼留言