Jpackage-制作無需預(yù)裝Java環(huán)境的Jar可執(zhí)行程序
JAR 包要在預(yù)裝 JRE 環(huán)境的系統(tǒng)上執(zhí)行。如果沒有預(yù)先安裝 JRE 環(huán)境,又想直接運(yùn)行 Java 程序,該怎么辦呢?
這篇文章我們會(huì)先學(xué)習(xí)如何將 Java 程序打包成一個(gè)可執(zhí)行的 Java JAR 文件。然后演示如何使用這個(gè) JAR 文件生成 Windows、Linux、MacOS 上的可執(zhí)行程序。我們將使用 Java 自帶的 jar 命令行工具來創(chuàng)建 JAR 文件。然后學(xué)會(huì)使用 jpackage 工具創(chuàng)建各個(gè)系統(tǒng)上的可執(zhí)行程序。
注意:jpackage 工具從 Java 14 版本開始提供的,可以用來生成可執(zhí)行程序。
什么是 jar
jar 文件是一個(gè)包含編譯后的 Java Class 文件和其他資源的容器。它基于廣泛使用的 ZIP 文件格式,因此 jar 文件可以使用 ZIP解壓縮工具解壓。一個(gè)可執(zhí)行的 jar 文件需要包含一個(gè) main 類作為程序的入口,并在 MANIFEST.MF 文件中指定
但是為了運(yùn)行 jar 格式的應(yīng)用程序,必須有一個(gè)Java 運(yùn)行時(shí)環(huán)境(JRE)。
jar 命令
Java 的 jar 命令是 Java Archive Tool,它是一個(gè)用于創(chuàng)建、查看和管理 jar 文件的命令行工具。此工具包含在 JDK 中。
詳細(xì)介紹 jar 命令的使用不是本文目的,下面給出 jar 命令的常見用法。
創(chuàng)建一個(gè)輸出 Hello 的Java 類用于測試。
目錄結(jié)構(gòu):
├── Hello.java
└── META-INF
└── MANIFEST.MF
查看文件內(nèi)容然后編譯 Hello.java
public class Hello{
public static void main(String[] args) throws InterruptedException{
System.out.println("Hello");
// 3s 后退出
Thread.sleep(3 * 1000);
}
}
// 編譯:javac Hello.java
配置 MANIFEST.MF 文件,注意,最后一定要有一個(gè)換行,否則可能在 Windows 上運(yùn)行失敗。
Manifest-Version: 1.0
Main-Class: Hello
1. 創(chuàng)建 jar 文件
jar cmf META-INF/MANIFEST.MF hello.jar Hello.class
其中 c 表示創(chuàng)建新的歸檔文件,m 指定清單文件,f 指定生成的 jar 文件的名稱,最后是要添加到 jar 包中的文件列表。
2. 執(zhí)行 jar 文件
java -jar hello.jar
Hello
3. 查看 jar 文件
$ jar tf hello.jar
META-INF/
META-INF/MANIFEST.MF
Hello.class
其中 t 為 list,列出文件。f 指定 jar 文件。
創(chuàng)建 jar 文件有多種方式,比如借助 Maven 或者 Gradle 工具都可以打包 Java 程序?yàn)?jar 文件,而且更加方便。比如 Spring Boot 開發(fā)過程中, mvn package 即可生成 jar 文件。
jpackage 命令
jpackage 命令是從 Java 14 開始提供的,可以幫助我們?yōu)槟K化或非模塊化 Java 應(yīng)用程序生成指定系統(tǒng)平臺(tái)的可執(zhí)行程序,而不用預(yù)先安裝 JRE 環(huán)境。如何做到的呢?
我們知道 Java 程序必須在 JRE環(huán)境才能運(yùn)行, jpackage 其實(shí)是把 JRE 和 JAR 文件以及所有必要依賴項(xiàng)一起打包生成指定平臺(tái)的可執(zhí)行程序。例如 Windows 上的 exe 或 macOS 上的 dmg。每種格式都必須構(gòu)建在其運(yùn)行的平臺(tái)上,沒有跨平臺(tái)支持。工具還提供了常見的自定義操作,如應(yīng)用名,應(yīng)用圖標(biāo)等。
查看 jpackage 幫助:
jpackage --help
用法:jpackage <options>
示例用法:
--------------
生成適合主機(jī)系統(tǒng)的應(yīng)用程序包:
對(duì)于模塊化應(yīng)用程序:
jpackage -n name -p modulePath -m moduleName/className
對(duì)于非模塊化應(yīng)用程序:
jpackage -i inputDir -n name \
--main-class className --main-jar myJar.jar
從預(yù)構(gòu)建的應(yīng)用程序映像:
jpackage -n name --app-image appImageDir
生成應(yīng)用程序映像:
對(duì)于模塊化應(yīng)用程序:
jpackage --type app-image -n name -p modulePath \
-m moduleName/className
對(duì)于非模塊化應(yīng)用程序:
jpackage --type app-image -i inputDir -n name \
--main-class className --main-jar myJar.jar
要為 jlink 提供您自己的選項(xiàng),請(qǐng)單獨(dú)運(yùn)行 jlink:
jlink --output appRuntimeImage -p modulePath \
--add-modules moduleName \
--no-header-files [<additional jlink options>...]
jpackage --type app-image -n name \
-m moduleName/className --runtime-image appRuntimeImage
生成 Java 運(yùn)行時(shí)程序包:
jpackage -n name --runtime-image <runtime-image>
對(duì)預(yù)定義應(yīng)用程序映像進(jìn)行簽名:
jpackage --type app-image --app-image <app-image> \
--mac-sign [<additional signing options>...]
注:此模式下允許的其他選項(xiàng)只有:
一組其他 mac 簽名選項(xiàng)和 --verbose
........
jpackage 創(chuàng)建可執(zhí)行文件
創(chuàng)建可執(zhí)行程序命令格式:
jpackage --input . --name YouAppName --main-jar youfile.jar
現(xiàn)在讓我們使用上面的 hello.jar 來創(chuàng)建一個(gè)可執(zhí)行的JAR文件。hello.jar 直接運(yùn)行會(huì)輸出 Hello 字符。
Windows 平臺(tái)
注意:對(duì)于 Windows,jpackage 需要 WiX 3.0 或更高版本。
Winx3.14 下載:https://github.com/wixtoolset/wix3/releases/tag/wix314rtm
由于 hello.jar 是一個(gè)命令行程序,沒有 UI界面,因此打包時(shí)使用 --win-console 參數(shù)配置以命令行方式啟動(dòng)。
常見的 Windows 下 jpackage 參數(shù)還有:
- ? --type : 指定打包后的格式,如 msi、exe,默認(rèn) exe。
- ? --win-console:使用控制臺(tái)窗口啟動(dòng)我們的應(yīng)用程序
- ? --win-shortcut : 在 Windows 開始菜單中創(chuàng)建快捷方式文件
- ? --win-dir-chooser:讓最終用戶指定自定義目錄來安裝可執(zhí)行文件
打包成 exe 程序。
jpackage --input . --name helloApp1 --win-console --win-shortcut --main-jar hello.jar
打包后可以得到 helloApp1-1.0.exe 文件。
PS C:\Users\Administrator\Desktop\test> jpackage --input . --name helloApp --win-console --win-shortcut --main-jar hello.jar
PS C:\Users\Administrator\Desktop\test> ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2024/3/7 22:14 526 Hello.class
-a---- 2024/3/7 22:14 802 hello.jar
-a---- 2024/3/7 22:13 208 Hello.java
-a---- 2024/3/7 22:17 110145536 helloApp1-1.0.exe
-a---- 2024/3/7 21:58 42 MANIFEST.MF
直接雙擊運(yùn)行安裝。
圖片
安裝 helloApp1-1.0.exe
安裝完成后,桌面上會(huì)出現(xiàn)圖標(biāo),雙擊可以運(yùn)行并輸出 Hello 字符串。
圖片
運(yùn)行 helloApp1
Mac 平臺(tái)
Mac 平臺(tái)運(yùn)行 jpackage 命令會(huì)自動(dòng)生成 dmg 安裝包。
jpackage --input . --name hello --main-jar hello.jar
生成 hello-1.0.dmg 文件,雙擊彈出安裝界面。
圖片
Jpackage 生成 Mac dmg 安裝文件
因?yàn)闇y試程序 hello.jar 是一個(gè)輸出 Hello 字符串的命令行程序,并沒有 UI,因此測試從命令行啟動(dòng)查看輸出。
? ~ /Applications/hello.app/Contents/MacOS/hello
Hello
Linux 平臺(tái)
jpackage --input . --name hello --main-jar hello.jar
我所在 Linux 系統(tǒng)為 Ubuntu22 ,所以生成安裝包 hello_1.0_amd64.deb 。
$ ls -l -h
total 37M
-rw-r--r-- 1 root root 37M Mar 7 16:50 hello_1.0_amd64.deb
-rw-r--r-- 1 root root 401 Mar 6 11:42 Hello.class
-rw-r--r-- 1 root root 1.1K Mar 7 16:42 hello.jar
-rw-r--r-- 1 root root 96 Mar 6 11:41 Hello.java
-rw-r--r-- 1 root root 41 Mar 6 11:42 MANIFEST.MF
安裝 hello_1.0_amd64.deb 。
$ apt install hello_1.0_amd64.deb
安裝后命令位于 /opt 目錄下,運(yùn)行測試:
$ /opt/hello/bin/hello
Hello
總結(jié)
本文介紹了在沒有預(yù)裝 JRE 環(huán)境的系統(tǒng)上運(yùn)行 Java 程序的方法。首先,介紹如何使用 Java 的 jar 命令行工具創(chuàng)建一個(gè)可執(zhí)行的 JAR 文件,這需要編寫 Java 程序,配置 MANIFEST.MF 文件,并使用 jar 命令創(chuàng)建包含主類的 JAR 文件。接著,介紹了 jpackage 工具(從 Java 14 版本開始提供),該工具可以打包 JAR 文件和必要的 JRE 環(huán)境,生成適用于 Windows、Linux、MacOS 的可執(zhí)行程序,使得 Java 應(yīng)用程序能夠在無需預(yù)裝 JRE 的情況下運(yùn)行。
參考
- ? https://docs.oracle.com/en/java/javase/21/jpackage/
- ? https://docs.oracle.com/en/java/javase/21/docs/specs/man/jpackage.html