目录

apache/maven:4.4k Stars 的 Java 构建工具,21 年后为什么还在 Trending

本文导读

读完本文你将能够:

  • 解释为什么 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 主线改了什么、采用边界在哪里。


目录


一、先给判断

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-modelPOM(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 overhead
  • feat(mvnsh): support Java 21 virtual threads
  • docs(mvnsh): update installation guide for Windows

mvnsh 用 Java 21 虚拟线程(virtual threads)替换老线程模型,意味着 CLI 在大量并行插件调用时的吞吐量提升。

2. Wrapper 校验

  • feat(wrapper): verify checksum of wrapper jar
  • fix(wrapper): handle missing distributionUrl gracefully

Wrapper 自动下载 Maven 发行版,校验和验证防止中间人篡改。

3. 依赖解析改进

  • fix(resolver): handle BOM imports in transitive dependencies
  • perf(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.xGradle 8.xBazel 7.x
配置语言XMLKotlin DSL / GroovyStarlark
学习曲线
构建速度中(4.x 缓存改进)极快
增量构建支持(4.x 稳定化)支持(成熟)一等公民
远程缓存实验一等公民一等公民
插件生态极广(Java 生态默认)广较窄
适用规模中(< 500 模块)中(< 2000 模块)大(任意规模)

对于「传统 Java 项目」「中型 monorepo」,Maven 4.x 仍是当前最稳的选择。对于「Kotlin / Scala」「大型 monorepo」,Gradle 更合适。对于「超大规模 monorepo」「跨语言构建」,Bazel 是更专业的工具。


七、起步建议

  1. 新项目直接用 Maven 4.x + Wrappermvn wrapper:wrapper 生成 .mvn/wrapper/,提交到 git
  2. CI 启用构建缓存:Maven 4.x 的远程缓存协议 + CI 缓存目录(GitHub Actions cache)配合使用
  3. POM 简化:删掉继承链超过 2 层的 parent POM,迁移到 BOM 导入
  4. 监控构建时间:CI 启用 Maven 4.x 的 --show-version --batch-mode,看每个 phase 耗时
  5. 升级路径: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 继承链过长导致难以维护」。


自测题(附参考答案)

  1. Maven 主仓库包含什么?为什么 compiler / surefire / jar 这些插件是独立仓库?

    • 答:主仓库只有 Maven 核心maven-coremaven-modelmaven-resolver 等)。插件是 apache/maven-* 独立仓库,按 release train 独立发版,核心引擎不用跟着插件一起升级。
  2. mvnsh 把 CLI 重写了什么?冷启动时间从多少降到多少?

    • 答:CLI 用 Java 21 重新实现(替换老版本反射式实现),冷启动从 ~1.5s 降到 ~400ms;可选 GraalVM native image 进一步降到 < 100ms。
  3. Wrapper 默认化解决了什么问题?./mvnwmvn 的区别是什么?

    • 答:解决「团队 / CI 的 Maven 版本不一致」——Wrapper 自动下载指定版本,新人 clone 后直接 ./mvnw,不用先 apt install mavenmvnw 是 Wrapper 启动器,mvn 是系统预装的 Maven。
  4. Maven 4.x 把 Resilience4j 集成的默认值开成了什么?

    • 答:重试默认 3 次(指数退避)、Maven Central 响应慢时自动断路、连接超时 30s / 读超时 60s。之前要 CI 重跑,现在自动重试。
  5. 为什么说「Maven 比 Gradle 慢」部分原因是缓存?4.x 把差距缩小了多少?

    • 答:老版本缓存机制不完善,每次构建重复下载与重建;4.x 引入基于 ${session.topology} 的增量缓存 + 远程缓存规范,把与 Gradle 的构建速度差距缩小了 30–50%。
  6. Maven 在哪些场景「不太适合」?

    • 答:超大规模 monorepo(> 1000 模块,Gradle task graph 更深入)、Kotlin / Scala 项目(Gradle + Kotlin DSL 体验更好)、需要复杂自定义构建逻辑、polyrepo 跨仓库构建、追求极致增量构建。

练习

  1. 在一个新项目跑 mvn wrapper:wrapper,把 .mvn/wrapper/ 提交 git,再在一台没装 Maven 的机器上 clone 后直接 ./mvnw 验证可用。
  2. 开启 Maven 4.x 远程构建缓存,配合 GitHub Actions cache 复用产物,对比二次构建的耗时差异。
  3. 把一个继承链超过 2 层的 parent POM 拆成 BOM 导入,验证拆分前后构建产物一致。
  4. 在 CI 里用 --show-version --batch-mode 输出每个 phase 的耗时,定位最慢的瓶颈 phase。
  5. 拿一个 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

  1. 升级到 4.x 后老插件报错,怎么排查? 先在 3.8.x 跑 mvn validate -P apache-release 验证插件兼容性;不兼容的插件需升级到支持 4.x 的版本,或暂时锁定旧版。

  2. Wrapper 下载的 Maven 被中间人篡改怎么办? Wrapper 默认校验下载 jar 的 checksum,校验失败会拒绝启动;务必使用官方 distributionUrl,不要指向未知源。

  3. 依赖传递里的 BOM 导入出错怎么处理? 4.x 改进了 BOM 的传递依赖解析;检查 dependencyManagement 的导入顺序与版本范围,必要时显式锁定。

  4. 构建还是太慢,从哪里入手? 开远程构建缓存、在 CI 缓存本地 repo(-Dmaven.repo.local)、避免反复调用 mvn(把多个 goal 串成一次调用,如 ./mvnw clean verify)。

  5. 超大规模 monorepo 怎么选构建工具?

    1000 模块评估 Gradle 的 task graph 优化;> 5000 模块直接上 Bazel,Maven / Gradle 都不擅长这种体量。

  6. Maven 和 Gradle 该怎么分工? 传统 Java 项目、中型 monorepo 用 Maven 最稳;Kotlin / Scala、大型 monorepo 用 Gradle;超大规模跨语言构建用 Bazel。按团队维护成本而非「哪个更好」选型。