jlink是java 9+构建最小运行时镜像最有效方式,通过精准裁剪未用jdk模块(如剔除java.desktop),结合jdeps分析依赖、--compress压缩及docker多阶段构建,可将镜像体积压至50–80mb。

Java 使用 jlink 打包最小运行时镜像,核心是只包含应用实际依赖的模块,剔除 JDK 中未使用的类库和工具,从而显著减小体积(常可压缩到 30–50MB)。关键前提是你的应用必须基于 Java 9+ 模块系统(或至少能被 jlink 识别为模块化应用),且使用 --add-modules 显式声明所需模块。
确认应用满足模块化前提
jlink 不处理传统 classpath 启动方式下的“隐式依赖”。如果你的应用没定义 module-info.java,仍可打包,但需手动指定所有用到的模块(如 java.base、java.sql、java.xml 等);否则会报错“no modules specified”或运行时报 NoClassDefFoundError。
- 有
module-info.java:编译后生成模块描述,jlink 可自动推导依赖(配合--add-modules或--include-services补充 SPI) - 无
module-info.java:必须用--add-modules java.base,java.desktop,...列出全部显式需要的模块(可用jdeps --list-deps your-app.jar辅助分析) - 第三方库(如 Jackson、Log4j)若非模块化,会被视为“自动模块”,名字默认为 JAR 文件名(如
com.fasterxml.jackson.core.jackson-databind),需在--add-modules中写对
基础 jlink 命令与常用参数
以 JDK 自带的 jlink 工具(位于 $JAVA_HOME/bin/jlink)执行,输出为独立目录,内含精简 JRE + 启动脚本。
-
--module-path:指定模块所在路径(如mods/目录,含你编译好的模块和第三方模块 JAR) -
--add-modules:必填,列出主模块名(如mymodule)或 JDK 模块(如java.sql) -
--output:指定输出目录(如myapp-runtime),不能已存在 -
--strip-debug:移除调试信息,减小体积 -
--compress=2:启用 ZIP 压缩(1=方法常量池,2=全部字节码),推荐使用 -
--no-header-files和--no-man-pages:去掉头文件和手册页(通常不需要)
示例命令:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
处理反射、JNI 和资源等常见陷阱
最小镜像不包含反射元数据、本地库或未声明的资源,运行时易抛 InaccessibleObjectException、UnsatisfiedLinkError 或找不到配置文件。
- 反射访问私有成员:加
--add-opens java.base/java.lang=ALL-UNNAMED(或指定模块名),多个用逗号分隔 - JNI 本地库(如 SQLite JDBC 的 .so/.dll):jlink 不打包 native 库,需手动复制到输出目录的
bin/或lib/下,并确保java.library.path包含该路径 - 配置文件、模板、静态资源:jlink 不扫描 classpath 资源,需在构建阶段将它们一并复制进
myapp-runtime/,并在代码中用相对路径或System.getProperty("java.home")定位 - 服务加载(如 JDBC 驱动):加
--include-services,让 jlink 自动包含META-INF/services/声明的服务提供者
验证与启动最小镜像
生成后不要直接运行,先检查内容是否完整:
- 进入
myapp-runtime/bin/,执行./java -version确认运行时有效 - 运行
./java --list-modules查看实际包含哪些模块,确认无遗漏 - 用
./java -m myapp/com.example.Main启动(模块化应用)或./java -cp app.jar com.example.Main(非模块化,需确保app.jar在当前目录) - 若报
ClassNotFoundException,回到jdeps分析依赖,补全--add-modules;若报IllegalAccessError,补--add-opens
最终镜像可直接打包分发,无需用户安装 JDK,双击 bin/java(Linux/macOS)或 bin\java.exe(Windows)即可运行。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










