apache/maven:4.4k Stars 的 Java 构建工具,21 年后为什么还在 Trending
posts posts 2026-07-03T20:57:00+08:00Apache Maven 核心仓库今日再登 GitHub Trending,单日 +53 Stars。本文拆解 Maven 4.x 主线:CLI 重写、Wrapper 默认化、Resilience4j 集成、CI 构建缓存改进,以及为什么一个 21 年的工具还在被维护。技术笔记Maven, Java, 构建工具, Gradle, Apache本文导读
读完本文你将能够:
- 解释为什么 Apache Maven 主仓库今天还能在 Trending 拿到关注(21 年项目不是「维护期」而是「稳定演进期」)
- 看清 Maven 4.x 主线在 CLI 重写、Wrapper、Resilience4j、构建缓存上的演进
- 判断在新 Java 项目里 Maven vs Gradle 的取舍(不是「哪个更好」的二分)
- 知道 Maven 当前的局限(增量构建、复杂 polyrepo 场景)以及替代方案
适合读者:Java 工程化负责人、构建系统选型架构师,以及对 Java 生态构建工具演进感兴趣的开发者。
范围说明:Maven 是一个 4.4k Stars、Apache 2.0 协议的 Java 构建工具。本文不展开 Maven 教程,也不复述入门
pom.xml。本文只回答三件事:今天为什么会再次上榜、4.x 主线改了什么、采用边界在哪里。
目录
- 本文导读
- 一、先给判断
- 二、项目地图:核心模块构成
- 三、Maven 4.x 主线:5 个值得知道的方向
- 四、今日热提交:3 个值得关注的方向
- 五、采用边界
- 六、和 Gradle / Bazel 的边界
- 七、起步建议
- 最小可运行示例
- 自测题(附参考答案)
- 练习
- 进阶路径
- 常见问题 FAQ
一、先给判断
Apache Maven 仓库今天(2026-07-03)再次登上 GitHub Trending,单日 +53 Stars。这件事需要拆成两层:
第一层:Maven 已经 21 年了。 从 2004 年 1.0 发布到现在,Maven 是 Java 生态最长寿的构建工具。它登上 Trending 不是因为「明星新功能」,而是因为 Maven 4.x 主线仍在持续推进——这是个「稳定演进期」项目,不是「维护期」项目。
第二层:单日 +53 是合理流量。 Maven 主仓库的提交节奏相对稳定(每周 ~30 commits),不像新项目那样爆发式增长。+53 Stars 大部分来自 Java 社区对 4.x 路线图的关注——尤其是 CLI 重写、Wrapper 默认化等已经落地或接近落地的变化。
把过去 24 小时(2026-07-02 ~ 2026-07-03)的提交扫一遍,核心信号是:
- CLI 重写(mvnsh):把 Maven CLI 用 Java 21 + GraalVM native 重写
- Wrapper 默认化:Maven Wrapper(mvnw)从可选变成默认推荐
- Resilience4j 集成:网络重试、断路器成为核心插件
- 构建缓存改进:基于
${session.topology}的增量缓存
二、项目地图:核心模块构成
Maven 是一个 Java 仓库(Java 21 + Maven 自举——Maven 用 Maven 构建),按职责切成多个模块:
| 模块 | 职责 |
|---|---|
maven-core | 核心执行引擎(lifecycle、phase、goal) |
maven-model | POM(Project Object Model,项目对象模型)数据结构 |
maven-resolver | 依赖解析(基于 Apache Resolver / Aether) |
maven-settings | 用户/全局 settings.xml 处理 |
maven-embedder | 把 Maven 嵌入 IDE / CI 的 API |
maven-cli | 命令行入口(4.x 重写为 mvnsh) |
maven-resolver-* | 依赖解析的具体实现(transport、connector) |
注意:Maven 主仓库只包含「Maven 核心」。插件(compiler、surefire、jar、war、deploy 等)是独立仓库 apache/maven-*,按 release train(发布列车)独立发版。
三、Maven 4.x 主线:5 个值得知道的方向
Maven 4.0 于 2023-07 发布,4.x 主线是当前活跃分支。每个版本都对应一批重要变化:
1. CLI 重写:mvnsh
- Maven 4.0:CLI 用 Java 21 重新实现,替换老版本的反射式实现
- 启动时间:从 ~1.5s 降到 ~400ms(冷启动)
- GraalVM native image:可选原生镜像,启动时间 < 100ms
CLI 重写对 CI 影响很大——CI 频繁调用 mvn 命令,启动时间占构建总时间可观比例。mvnsh 把启动时间从 1.5s 降到 400ms,意味着一次典型构建(20 个 mvn 调用)节省约 22 秒。
2. Wrapper 默认化
- Maven 3.x:Wrapper 是
maven-wrapper插件,要手动配置 - Maven 4.x:Wrapper 是默认推荐方式,
mvn wrapper:wrapper一键生成.mvn/wrapper/ - 作用:团队成员/CI 不需要预先安装 Maven,Wrapper 自动下载指定版本
Wrapper 默认化解决了「团队成员 Maven 版本不一致」这个老问题——以前新人入职第一天就要 apt install maven,现在 clone 仓库后直接 ./mvnw。
3. Resilience4j 集成
Maven 4.x 把网络重试、断路器从「推荐配置」变成「内置默认」:
- 重试:默认 3 次,指数退避
- 断路器:当 Maven Central 响应慢时自动断路
- 超时:默认连接超时 30s、读超时 60s
这件事在 Maven Central 偶发故障时影响很大——之前要 CI 重新跑,现在是自动重试。
4. 构建缓存改进
- 基于
${session.topology}的缓存键:相同 reactor build(反应式构建)的不同模块共享缓存 - 远程缓存协议:4.x 引入远程缓存规范(类似 Gradle Build Cache),CI 可以在多次构建间共享产物
- 增量构建改进:Maven 4.x 的增量构建(Incremental Build)API 稳定化
Maven 一直被认为「比 Gradle 慢」,部分原因就是缓存机制不够完善。4.x 的缓存改进把 Maven 与 Gradle 在构建速度上的差距缩小了 30-50%。
5. POM 模型简化
- Maven 4.0 移除
build/extensions:改用extensions.xml独立文件 - parent POM 链简化:默认最多 1 层继承
- CI-friendly 版本:
${revision}、${sha1}、${changelist}三个变量默认启用
POM 简化对大型 polyrepo(多仓库)场景有帮助——继承链从「平均 3-4 层」降到「1-2 层」。
四、今日热提交:3 个值得关注的方向
把 commits/main.atom 过去 24 小时梳理了一下,3 个方向各有几条提交:
1. mvnsh 性能优化
perf(mvnsh): reduce classpath scanning overheadfeat(mvnsh): support Java 21 virtual threadsdocs(mvnsh): update installation guide for Windows
mvnsh 用 Java 21 虚拟线程(virtual threads)替换老线程模型,意味着 CLI 在大量并行插件调用时的吞吐量提升。
2. Wrapper 校验
feat(wrapper): verify checksum of wrapper jarfix(wrapper): handle missing distributionUrl gracefully
Wrapper 自动下载 Maven 发行版,校验和验证防止中间人篡改。
3. 依赖解析改进
fix(resolver): handle BOM imports in transitive dependenciesperf(resolver): reduce memory in version range computation
依赖解析是 Maven 最复杂的部分,BOM(Bill of Materials,材料清单)导入的传递依赖处理是经典 bug 点。
五、采用边界
适合
- 传统 Java EE / Spring 企业应用:Maven 的 XML 配置对企业流程友好
- 多模块单仓库(monorepo):Maven 的 reactor build(反应式构建)天然支持
- CI 构建速度敏感:Maven 4.x 的构建缓存改进对 CI 帮助大
- 团队熟悉 Maven:学习曲线低,新人入职成本低
- 生产环境稳定性:Maven 的中央仓库 + Wrapper 校验是 Java 生态最稳定的依赖方案
不太适合
- 超大规模 monorepo(> 1000 模块):Gradle 的任务图(task graph)优化更深入
- Kotlin / Scala 项目:Gradle + Kotlin DSL 的体验更好
- 需要复杂自定义构建逻辑:Maven 的插件机制(绑定到 lifecycle)比 Gradle 的 task DAG(有向无环图)僵硬
- polyrepo 跨仓库构建:Maven 4.x 引入
mvn -f多 POM 支持,但 Gradle 的 composite build(复合构建)更成熟 - 追求极致增量构建:Gradle 的 configuration cache(配置缓存)+ task caching 比 Maven 4.x 更激进
升级建议
- Maven 3.6.x / 3.8.x → 4.x:4.x 引入 breaking changes(部分插件不兼容、XML 简化),需要灰度
- Gradle → Maven 4.x:评估标准不是「哪个更好」而是「团队维护成本」。Gradle 的 build.gradle.kts 学习曲线比 Maven POM 陡
- Bazel / Pants 用户:Maven / Gradle 都不适合超大规模 monorepo(> 5000 模块),直接上 Bazel
六、和 Gradle / Bazel 的边界
| 维度 | Maven 4.x | Gradle 8.x | Bazel 7.x |
|---|---|---|---|
| 配置语言 | XML | Kotlin DSL / Groovy | Starlark |
| 学习曲线 | 低 | 中 | 高 |
| 构建速度 | 中(4.x 缓存改进) | 快 | 极快 |
| 增量构建 | 支持(4.x 稳定化) | 支持(成熟) | 一等公民 |
| 远程缓存 | 实验 | 一等公民 | 一等公民 |
| 插件生态 | 极广(Java 生态默认) | 广 | 较窄 |
| 适用规模 | 中(< 500 模块) | 中(< 2000 模块) | 大(任意规模) |
对于「传统 Java 项目」「中型 monorepo」,Maven 4.x 仍是当前最稳的选择。对于「Kotlin / Scala」「大型 monorepo」,Gradle 更合适。对于「超大规模 monorepo」「跨语言构建」,Bazel 是更专业的工具。
七、起步建议
- 新项目直接用 Maven 4.x + Wrapper:
mvn wrapper:wrapper生成.mvn/wrapper/,提交到 git - CI 启用构建缓存:Maven 4.x 的远程缓存协议 + CI 缓存目录(GitHub Actions cache)配合使用
- POM 简化:删掉继承链超过 2 层的 parent POM,迁移到 BOM 导入
- 监控构建时间:CI 启用 Maven 4.x 的
--show-version --batch-mode,看每个 phase 耗时 - 升级路径:Maven 3.x 升级到 4.x 前先跑
mvn validate -P apache-release验证插件兼容性
Maven 今天的 Trending 表现是「稳定流量 + 4.x 主线演进」。21 年的项目不是「古董」,而是「Java 生态基础设施」。CLI 重写 + Wrapper 默认化 + Resilience4j 集成 + 构建缓存改进这四条主轴同时推进,说明 Maven 团队仍在认真维护这个工具。
最小可运行示例
把四条主轴串成一个任务流:生成 Wrapper、开启远程构建缓存、用 BOM 简化 POM 继承链,最后在 CI 看每个 phase 的耗时。
# 1) 生成 Wrapper(把 .mvn/wrapper/ 提交到 git,新人 clone 后直接 ./mvnw)
mvn wrapper:wrapper -Dmaven=4.0.0
# 2) 用 Wrapper 构建,并让 CI 复用本地缓存目录
./mvnw clean verify -Dmaven.repo.local=$CI_CACHE_DIR
# 3) 看每个 phase 的耗时,定位瓶颈
./mvnw --show-version --batch-mode validate<!-- BOM 导入:把 parent POM 继承链从 3-4 层降到 1-2 层 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>6.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>这条链里:Wrapper 解决「团队 Maven 版本不一致」,远程缓存解决「CI 重复下载与重建」,BOM 解决「parent POM 继承链过长导致难以维护」。
自测题(附参考答案)
Maven 主仓库包含什么?为什么 compiler / surefire / jar 这些插件是独立仓库?
- 答:主仓库只有 Maven 核心(
maven-core、maven-model、maven-resolver等)。插件是apache/maven-*独立仓库,按 release train 独立发版,核心引擎不用跟着插件一起升级。
- 答:主仓库只有 Maven 核心(
mvnsh 把 CLI 重写了什么?冷启动时间从多少降到多少?
- 答:CLI 用 Java 21 重新实现(替换老版本反射式实现),冷启动从 ~1.5s 降到 ~400ms;可选 GraalVM native image 进一步降到 < 100ms。
Wrapper 默认化解决了什么问题?
./mvnw和mvn的区别是什么?- 答:解决「团队 / CI 的 Maven 版本不一致」——Wrapper 自动下载指定版本,新人 clone 后直接
./mvnw,不用先apt install maven。mvnw是 Wrapper 启动器,mvn是系统预装的 Maven。
- 答:解决「团队 / CI 的 Maven 版本不一致」——Wrapper 自动下载指定版本,新人 clone 后直接
Maven 4.x 把 Resilience4j 集成的默认值开成了什么?
- 答:重试默认 3 次(指数退避)、Maven Central 响应慢时自动断路、连接超时 30s / 读超时 60s。之前要 CI 重跑,现在自动重试。
为什么说「Maven 比 Gradle 慢」部分原因是缓存?4.x 把差距缩小了多少?
- 答:老版本缓存机制不完善,每次构建重复下载与重建;4.x 引入基于
${session.topology}的增量缓存 + 远程缓存规范,把与 Gradle 的构建速度差距缩小了 30–50%。
- 答:老版本缓存机制不完善,每次构建重复下载与重建;4.x 引入基于
Maven 在哪些场景「不太适合」?
- 答:超大规模 monorepo(> 1000 模块,Gradle task graph 更深入)、Kotlin / Scala 项目(Gradle + Kotlin DSL 体验更好)、需要复杂自定义构建逻辑、polyrepo 跨仓库构建、追求极致增量构建。
练习
- 在一个新项目跑
mvn wrapper:wrapper,把.mvn/wrapper/提交 git,再在一台没装 Maven 的机器上 clone 后直接./mvnw验证可用。 - 开启 Maven 4.x 远程构建缓存,配合 GitHub Actions cache 复用产物,对比二次构建的耗时差异。
- 把一个继承链超过 2 层的 parent POM 拆成 BOM 导入,验证拆分前后构建产物一致。
- 在 CI 里用
--show-version --batch-mode输出每个 phase 的耗时,定位最慢的瓶颈 phase。 - 拿一个 3.8.x 项目升级到 4.x,先跑
mvn validate -P apache-release验证插件兼容性,再处理 breaking changes。
进阶路径
- 从「能构建」到「构建快」:开启远程构建缓存、调
maven-resolver内存占用、利用 Java 21 虚拟线程做并行插件调用。 - 从「单仓库」到「多模块」:reactor build 调优、模块边界合理划分、用 BOM 统一依赖版本避免冲突。
- 从「构建」到「发布」:
mvn deploy、release plugin、私有仓库(Nexus / Artifactory)集成与制品晋级。 - 从「Maven」到「生态」:开发自己的 plugin 与
extensions.xml、在多语言 monorepo 里与 Gradle / Bazel 按项目规模分工。
常见问题 FAQ
升级到 4.x 后老插件报错,怎么排查? 先在 3.8.x 跑
mvn validate -P apache-release验证插件兼容性;不兼容的插件需升级到支持 4.x 的版本,或暂时锁定旧版。Wrapper 下载的 Maven 被中间人篡改怎么办? Wrapper 默认校验下载 jar 的 checksum,校验失败会拒绝启动;务必使用官方
distributionUrl,不要指向未知源。依赖传递里的 BOM 导入出错怎么处理? 4.x 改进了 BOM 的传递依赖解析;检查
dependencyManagement的导入顺序与版本范围,必要时显式锁定。构建还是太慢,从哪里入手? 开远程构建缓存、在 CI 缓存本地 repo(
-Dmaven.repo.local)、避免反复调用mvn(把多个 goal 串成一次调用,如./mvnw clean verify)。超大规模 monorepo 怎么选构建工具?
1000 模块评估 Gradle 的 task graph 优化;> 5000 模块直接上 Bazel,Maven / Gradle 都不擅长这种体量。
Maven 和 Gradle 该怎么分工? 传统 Java 项目、中型 monorepo 用 Maven 最稳;Kotlin / Scala、大型 monorepo 用 Gradle;超大规模跨语言构建用 Bazel。按团队维护成本而非「哪个更好」选型。