java使用jdeps、jlink制作不依赖jdk多系统独立运行jar包的方法


文章目录
  • java使用jdeps、jlink制作不依赖jdk多系统独立运行jar包的方法
  • 一、背景
  • 二、环境
  • 三、实现过程
  • 四、使用jdeps产看依赖
  • 五、使用jlink制作精简jre环境
  • 六、制作完的完整目录结构如下
  • 七、使用bat批处理文件调用windows环境下的jar包
  • 八、使用shell脚本调用linux环境下的jar包
  • 总结


一、背景

Java 本身设计为一种跨平台的语言,能够实现"一次编写,到处运行"的理念。尽管它支持在多个操作系统上运行,但要实现这一点,需要满足一些前提条件,例如:必须安装 Java 开发工具包(JDK),并且安装的 JDK 版本需要与编译代码时使用的版本一致等。接下来,我将介绍一种无需部署 JDK 即可独立运行 Java 程序的方法。

二、环境

  • jdk21_x64_win
  • jdk21_x64_linux
  • Win10
  • Linux

三、实现过程

  1. 测试使用一个控制台应用程序,确保自己的应用可以使用 javar -jar xxx.jar 命令运行;
  2. 构建控制台应用程序名为console_test.jar;
  3. 使用jdeps命令(jdk8及以上支持)分析jar包依赖的基础包;
  4. 使用jlink命令(jdk9及以上支持)生产简版jre环境包;
  5. 修改JAVA_HOME环境变量,切换到非本系统JDK目录,这里切换的是jdk21_x64_linux的目录;
  6. 执行3、4步骤制作简化版的linux jre环境包;
  7. 至此windows、linux两个环境jre都已经制作完成,对比原始jdk目录大小,精简后的目录一般会减少100M以上;
  8. 建立批处理文件bat(sh)文件,动态修改JAVA_HOME环境变量值,分别指到对应系统jre目录;
  9. bat文件可以在windows系统上验证,sh文件可以在WSL中验证;

四、使用jdeps产看依赖

  • 用法: jdeps <选项> <路径…>]
  • 其中 <路径> 可以是 .class 文件, 目录, JAR 文件的路径名。
# 查看jar包依赖的模块
jdeps --list-deps console_test.jar
# 查看jar包的依赖,多个模块逗号分隔,输出内容可以用于jlink --add-modules的命令入参
jdeps --print-module-deps console_test.jar
  • 1.
  • 2.
  • 3.
  • 4.

五、使用jlink制作精简jre环境

jdk21的目录300M+,通过jlink可以制作一个精简的jdk依赖包。

--window
jlink --module-path %JAVA_HOME%\jmods --add-modules java.base --output %cd%\jre

--linux
jlink --module-path $JAVA_HOME/jmods --add-modules java.base --output $(pwd)/jre21-linux
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

参数说明:

  • –module-path 指定模块地址,%JAVA_HOME%是本机环境变量名;
  • –add-modules 依赖的模块,为jdeps命令对jar包分析的结果;
  • –output 精简后的依赖模块输出目录;

六、制作完的完整目录结构如下

其中start_by_jre21.bat、start_by_jre21.sh是启动脚本,后边介绍脚本内容。

cd /d D:\test
dir
<DIR>   jre21   --支持windows环境的jre
<DIR>   jre21-linux --支持linux环境的jre
        console_test.jar    
        start_by_jre21.bat  --启动脚本
        start_by_jre21.sh   --启动脚本
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

七、使用bat批处理文件调用windows环境下的jar包

建立start_by_jre21.bat文件,写入以下命名:

@echo off
set JAVA_HOME=%cd%\jre21
set PATH=%JAVA_HOME%\bin
echo ENV:%JAVA_HOME%
java -jar console_test.jar
pause
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

八、使用shell脚本调用linux环境下的jar包

建立start_by_jre21.sh文件,写入以下命名:

#! /bin/bash
export JAVA_HOME=$(pwd)/jre21-linux
export PATH=$JAVA_HOME/bin:$PATH
echo ENV:$JAVA_HOME
java -jar console_test.jar $(pwd)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

总结

通过上述方法,我们基本上满足了在不同环境中运行程序的需求。然而,这种方法并非无可挑剔。主要的问题在于 Java 运行环境(JRE)的体积相对较大。尽管我们的 JAR 文件仅有 30KB,但所需的最小化 JRE 环境,即便经过精简,也至少需要 50MB 来仅输出一个 “Hello World”。对于一个简单的控制台应用程序来说,1MB 的运行环境大小尚可接受。在未来的工作中,我考虑尝试使用 exe4j 进行打包,尽管这种方法牺牲了跨平台的特性。