maven-jlink-plugin入门

一、背景

JDK 9 引入了 模块系统(JPMS),把庞大的 JDK 拆成了上百个模块。
这样我们就可以:

  • 只引入应用需要的模块;

  • jlink 工具生成一个定制化 runtime 镜像

  • 从“依赖系统 JRE” 到 “自带专属 JRE”。

总结:

它是 Maven 对 JDK 自带工具 jlink 的封装,让模块化构建、镜像生成、依赖分析自动化。


二、原理:它到底做了什么

从执行流程看,它本质上完成这三件事:

(1)分析模块依赖树

它会解析:

  • 你的 module-info.java

  • 依赖的模块(无论是 JDK 模块还是第三方模块);

  • 并根据 Maven 依赖生成一棵 模块依赖树

例如:

com.example.app
 ├─ java.base
 ├─ java.sql
 └─ org.apache.logging.log4j

(2)调用 jlink 进行镜像生成

maven-jlink-plugin 会在目标目录下执行等价于:

jlink \
  --module-path target/classes:target/dependency \
  --add-modules com.example.app \
  --launcher app=com.example.app/com.example.app.Main \
  --output target/runtime \
  --strip-debug \
  --compress=2 \
  --no-header-files \
  --no-man-pages

结果是:

target/runtime/
├─ bin/app
├─ conf/
├─ lib/
└─ release

这个 runtime 就是一个独立可执行的、定制 JRE 镜像。

(3)支持与 jpackage 链接

maven-jlink-plugin 生成的 runtime 可直接喂给 maven-jpackage-plugin,后者能打成 .exe.deb.pkg 安装包或 Docker 基镜像。


三、核心配置详解

下面是官方参数的“全家桶级别”解释。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jlink-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <goals>
        <goal>jlink</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <output>${project.build.directory}/runtime</output>
    <modulePaths>
      <modulePath>${project.build.outputDirectory}</modulePath>
      <modulePath>${project.build.directory}/dependency</modulePath>
    </modulePaths>
    <addModules>
      <addModule>com.example.app</addModule>
    </addModules>
    <launcher>app=com.example.app/com.example.app.Main</launcher>

    <stripDebug>true</stripDebug>
    <compress>2</compress>
    <noHeaderFiles>true</noHeaderFiles>
    <noManPages>true</noManPages>
    <jlinkExecutable>${java.home}/bin/jlink</jlinkExecutable>
  </configuration>
</plugin>

主要参数说明:

参数名说明
output输出路径。生成的 runtime 镜像目录。
modulePathsjlink 搜索模块的路径。通常包括:编译输出 + 依赖目录。
addModules指定要加入镜像的模块(可以是 app 模块 + JDK 模块)。
launcher创建一个启动器脚本:别名=模块名/主类
stripDebug去除 .class 中的调试信息,减小体积。
compress压缩级别(0 无压缩、1 常规、2 最大压缩)。
noHeaderFiles移除头文件(减少体积)。
noManPages移除 man 手册页(减少体积)。
jlinkExecutable指定 jlink 可执行文件路径,通常不需改。

四、生命周期集成

maven-jlink-plugin 通常绑定在 package 阶段之后执行。
常见执行链:

mvn clean package jlink:jlink

如果要自动化,可以配置到 lifecycle:

<execution>
  <id>create-runtime</id>
  <phase>package</phase>
  <goals><goal>jlink</goal></goals>
</execution>

五、典型优化组合

构建极小运行时镜像(常用于容器):

<configuration>
  <stripDebug>true</stripDebug>
  <compress>2</compress>
  <noHeaderFiles>true</noHeaderFiles>
  <noManPages>true</noManPages>
  <ignoreSigningInformation>true</ignoreSigningInformation>
  <stripNativeCommands>true</stripNativeCommands>
  <verbose>true</verbose>
</configuration>

这种配置生成的 runtime 通常只有 30–60MB,且完全自包含。


六、Docker 示例

FROM scratch
COPY target/runtime /opt/runtime
WORKDIR /opt/runtime
ENTRYPOINT ["./bin/app"]

这是真正意义上的 零依赖 Java 容器,比传统 openjdk:17-jdk-slim 小几十 MB。


七、注意事项

  1. 必须是模块化项目
    需要 module-info.java,否则无法分析模块依赖。

  2. 第三方库未模块化
    对未显式声明模块的 jar,jlink 会自动生成 automatic module,但可能导致命名冲突。

  3. jlink 只适用于 Java 9+
    若你使用 JDK 8 或更早版本,无法使用。

  4. 多平台兼容性
    runtime 镜像与构建平台绑定,例如在 macOS 构建的 runtime 无法在 Linux 运行。


八、实践建议

  • 在 CI/CD 流程中,把 maven-jlink-plugin 放到独立 stage,生成 runtime 后缓存;

  • 对 Spring Boot 3+ 模块化项目,建议结合 spring-boot-jarmode-tools

  • 若要发布安装包,直接串联 maven-jpackage-plugin


九、总结

maven-jlink-plugin = Maven 模块化构建 + jlink Runtime 构建自动化
它是 Java 模块化应用走向云原生、自包含、轻量运行时的关键工具。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fire-flyer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值