GraalVM 将 java jar文件打包为可执行二进制文件

GraalVM 将 java jar文件打包为可执行二进制文件

java 运行需要安装jdk,如果需要迁移 jar 到其他机器运行,每台机器均需要安装 jdk 环境。

只需要使用 GraalVM 打包为二进制文件,即可随意迁移无需安装环境

GraalVM 对 jar 的限制主要在 反射的使用,如果只是制作的普通工具,没有大量使用反射功能,那么一次打包即可四处运行

工具环境准备

官网下载

官网下载电脑对应版本工具,将其解压到一个空白目录。然后设置环境变量

以 Linux 环境为例:

f2172323dea9a9531f170538746a400

修改为解压目录

JAVA_HOME 必须使用工具的路径

export JAVA_HOME=/home/admin/software/socks-proxy/graalvm/graalvm-openjdk-22

export  PATH=/home/admin/software/socks-proxy/graalvm/graalvm-openjdk-22/bin:$PATH

工具链在:<路径>/bin 目录 ,必须导出 PATH ,windows 使用设备管理器添加 PATH 环境变量

准备待编译的 jar 文件

假设已经将项目编译为一个 jar 文件,现在即可执行命令生成二进制:

native-image -jar  xxxxx.jar

这种方式编译生成的输出文件虽然是二进制文件,但依旧依赖java环境:/home/admin/software/socks-proxy/graalvm/graalvm-openjdk-22

添加参数可以生成不依赖环境的 二进制文件

native-image -jar xxxxx.jar --no-fallback

添加参数 --no-fallback 生成的文件可不依赖 java 环境,但是无法调用任何反射字段,如果项目用到了反射,那么运行时获取的 Method、Field 等均是 null

如果项目中并未使用任何反射,使用命令 native-image -jar xxxxx.jar --no-fallback 就已经成功生成并可以运行了。

如果需要用到反射,则在项目中要额外添加配置

生成反射需要的配置文件

生成配置的过程就只是简单运行 jar 即可,GraalVM 会自动检测 运行过程使用了哪些 反射字段、方法,并生成配置输出到执行目录。

生成过程中,要尽量运行程序覆盖所有反射字段,如果并未运行该反射代码,将无法被 VM 识别并生成配置

创建输出文件夹:META-INF/native-image

# 执行下面命令会将生成的 json 配置输出到 META-INF/native-image 目录
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image  -jar xxxx.jar

生成的文件如下:

微信截图_20240331101925

拿到配置文件之后,需要重新生成一个 jar,将这些配置放入项目的 META-INF/native-image 目录

项目结构如下:

微信截图_20240331102222

再次生成

现在重新编译生成一个 jar 文件,再拿这个新的 jar 执行命令即可

native-image -jar new-xxxxx.jar --no-fallback

编译的项目依赖Linux glibc,在高版本linux上编译的二进制,无法在低版本机器上运行

ldd --version 查看当前 linux glibc 版本

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://zwc365.com/2024/03/31/graalvm将javajar文件打包为可执行二进制文件

Buy me a cup of coffee ☕.