857 字
约 2 分钟
7
S06-A02 · 构建可复现与制品治理
适用读者:被"同一份代码两次打包不一样"折腾过的人。
前置:S06-J01、S01-J08。
覆盖旧文:—(E 驱动)
覆盖扩展:E-S06-013(可复现四要素)。
上一篇:S06-A01 · 组件选型治理:JDK / Guava / Hutool / Lombok 的边界
下一篇:S06-X01 · 卡片登记。
1. 一句话结论
"可复现"指:同一 commit + 同一环境 = 同一产物(逐字节)。做不到的四类原因:时间戳、依赖浮动、插件版本、构建环境差异。
| 原因 | 表现 | 对策 |
|---|---|---|
| 时间戳 | jar 内 MANIFEST/文件时间不同 |
project.build.outputTimestamp |
| 依赖浮动 | 同一坐标解析出不同版本 | 锁版本 + mvnw(S01-B03) |
| 插件版本 | 插件默认版本随 Maven 变 | 显式 <version> |
| 环境差异 | JDK/OS/编码不同 | 容器构建 + 固定 JDK |
2. 实测:两次构建的差异点在哪
本系列的实测经验(S01-B03 / S06-B01):
| 观察 | 结论 |
|---|---|
-DskipTests 导致编译失败 |
构建行为受"开关"影响 → 必须写进 CI 脚本而非记忆 |
缺 maven-compiler-plugin 版本 → Source option 5 |
插件默认版本会变 → 必须锁 |
多模块 -pl 缺 -am 失败 |
构建命令也是"可复现"的一部分 |
四要素(E-S06-013):
① JDK 版本(release 设置)
② 插件版本(compiler/surefire/jar…)
③ 依赖版本(BOM + 锁文件)
④ 时间戳(outputTimestamp)
3. 可复现的最小配置
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputTimestamp>2026-01-01T00:00:00Z</project.build.outputTimestamp>
</properties>
<build><plugins>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.13.0</version></plugin>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.4.1</version></plugin>
</plugins></build>
| 配置 | 作用 |
|---|---|
outputTimestamp |
固定 jar 内时间戳 |
插件 <version> |
避免默认版本漂移 |
release |
同时约束语言特性与 API |
mvnw |
固定 Maven 版本 |
验证方式:
mvn -q clean package && sha256sum target/*.jar
mvn -q clean package && sha256sum target/*.jar # 两次应一致
4. 制品治理(与 S01-J08/A02 分工)
| 层 | 内容 | 在哪讲 |
|---|---|---|
| 构建 | 可复现四要素 | 本篇 |
| 发布 | GPG 签名、中央仓库要求 | S01-J08 |
| 治理 | 私服、SBOM、晋升、不可变 | S01-A02 |
本篇只强调一条:"能重建"是可复现的前提,"能证明一致"是它的验收。
5. 五个误区
| 误区 | 真相 |
|---|---|
| "同一份代码打包肯定一样" | 时间戳/插件版本会让字节不同 |
| "锁了依赖就够了" | 插件版本同样会漂 |
| "在本地能跑就行" | 容器/CI 环境不同也会变 |
| "可复现等于功能一致" | 是产物一致,更强 |
| "验证一次就够" | 每次发布都该校验(尤其升级工具链后) |
6. 自检(架构师版)
- 不可复现的四类原因?
outputTimestamp解决什么?- 为什么插件版本也要锁?
- 怎么验证"可复现"(具体命令)?
- 构建可复现与制品治理的分工边界?
7. 下一篇
S06-X01 · 开源项目精选与卡片登记
最后一篇是附录:两张非知识性卡片的登记,以及本系列的收尾。
本篇属于系列《S06 · Java 工程化与组件》。扩展点 E-S06-013。
S06-A02 · 构建可复现与制品治理
https://www.clxhxhhr.top/posts/5266/ 评论
0 条
还没有评论,先写一条吧。