jar_pack
一个基于 Golang embed 打包自定义的 JRE 和 JAR 文件的跨平台打包工具,方便打包 JAR 程序进行二进制分发。
系统架构
graph TD; A[jar_pack 工具] --> B[准备 JRE] A --> C[准备 JAR] A --> D[编译] B --> E[JRE 目录] C --> F[JAR 文件] D --> G[输出二进制文件] E --> H[嵌入 JRE] F --> H[嵌入 JAR] G --> H[生成可执行文件]
使用示例(Java 8 版本环境打包到 Linux x86 下运行)
步骤 1: 准备指定版本以及系统的 JRE
从 Azul 下载并解压到 /jre
目录下。
步骤 2: 准备需要打包的 JAR
将 JAR 重命名为 app.jar
。
mv your-app.jar app.jar
步骤 3: 打包 Java 程序依赖的本地库
将本地库文件解压到 /lib
目录下。(可选)
mv xxx.dll lib/
mv xxx.so lib/
步骤 4: 编译
GOOS=linux GOARCH=amd64 go build -o app
运行
运行 ./app
或者指定 JVM 参数运行 ./app --spring.config.location=./application.yml
。
Windows 系统特殊说明
使用 rsrc 工具嵌入图标
- 查找并保存
favicon.ico
图标到程序同级目录。 - 新建程序描述文件
app.manifest
,写入以下内容:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
- 生成资源嵌入文件
rsrc.syso
:
rsrc -manifest app.manifest -o rsrc.syso -ico favicon.ico
- 编译时隐藏黑窗口:
go build -ldflags "-s -w -H=windowsgui"
- 双击 exe 文件即可运行。
剪裁 JRE
Java 9 引入的一项功能,用于创建自定义的 JRE。这个自定义 JRE 只包含应用程序运行所需的模块,从而减少了体积。
分析依赖
使用 jdeps
工具分析 JAR 文件,确定需要的模块。假设你的应用程序 JAR 文件名为 app.jar
:
jdeps --list-deps app.jar
创建自定义 JRE
根据 jdeps
的输出,使用 jlink
创建自定义 JRE。例如,假设你的应用程序需要以下模块:
jlink --module-path $JAVA_HOME/jmods --add-modules java.base,java.logging --output custom-jre
运行原理
$JAVAW||$JAVA -Djava.library.path=$LIB -jar $JAR $ARGS...
工作流程
sequenceDiagram participant U as 用户 participant J as jar_pack participant F as 文件系统 U->>J: 准备 JRE J->>F: 解压 JRE 到 /jre 目录 U->>J: 准备 JAR 文件 J->>F: 移动 JAR 文件到 /app.jar U->>J: 准备本地库 J->>F: 移动本地库到 /lib 目录 U->>J: 编译项目 J->>F: 生成可执行文件 app U->>J: 运行 app J->>J: 嵌入 JRE 和 JAR J->>F: 输出可执行文件