编程 Maven 4 Consumer POM:`maven.consumer.pom.flatten` 默认变 false,D 拿到的 C 从 1.1 变成 1.2

2026-10-03 00:03:45

Maven 4 Consumer POM:maven.consumer.pom.flatten 默认变 false,D 拿到的 C 从 1.1 变成 1.2

参考资料:

为什么要把 POM 拆成 build / consumer 两份

Maven 长期卡在 POM v4 上没动。直接把新模型发布到 Maven Central 会砸掉一类消费者:用旧版 Maven 的,以及其他把 POM v4 当兼容格式读的构建工具。其他构建工具的做法是——构建格式只留在内部,发布产物时另生成一份 POM,只含消费者需要的信息,不含构建指令。

Maven 4 走同一条路:发布到仓库时生成 consumer POM(去掉字段、推断字段、修改字段之后的简化 POM),本地那份原始 POM 叫 build POM,含构建该 artifact 的指令。consumer POM 保持对经典 POM v4 兼容,唯一的要求是「能从 build POM 生成 consumer POM」。flatten-maven-plugin 已经证明这条路可行。

可用性边界:非 pom packaging 的 POM 以 consumer POM(v4)发布;pom-packaging 的 POM(父 POM、BOM import 等)只以 build POM 发布——这类没有可消费的 artifact。

consumer POM 删了什么、留了什么

removed 的部分:build plugins、report plugins、plugin-management 等构建指令。

MNG-8527(PR #2058)进一步瘦身:不再内联大量 managed dependencies(导入大 BOM 或 cascading 时会爆炸);去掉 informational 数据 developers、contributors、mailing lists、issue management。这个 PR 重新在 Maven 4 对所有模型启用 consumer POM(此前 4.0.0 曾因体积问题禁用)。

可推断或需要更新的字段:

  • sub-module 的 project.version 可从磁盘推断;
  • 含 property 的 version 在 consumer POM 中转为精确值;
  • reactor 内部引用的 dependency version 在 build POM 可以省略。

maven.consumer.pom.flatten 默认值变了

新 feature flag maven.consumer.pom.flatten,默认 false——consumer POM 默认不再 flatten。

  • flatten=false(默认):consumer POM 像父 POM 一样保留 dependencyManagement,允许 consumer 继承;非 POM 项目不做 dependencyManagement 展平;向后兼容。
  • flatten=true(opt-in):移除 dependencyManagement,只保留有 transitive scope 的直接依赖;等同旧行为。

依赖解析的差异,用 PR 描述里的例子:

  • A 1.0 依赖 B 1.0,并把 C 管理到 1.2
  • B 2.0 依赖 C 1.1
  • D 依赖 A 1.0,并把 B 管理到 2.0

flatten=false(默认):D 最终得到 C 1.2——A 的 dependencyManagement 作用到了 D 的传递依赖上。
flatten=true:走传统扁平 consumer POM,dependencyManagement 被移除。

文档需要同步更新 whatsnewinmaven4.html#Consumer_POM,可能要求 4.0.0-rc-5。

mixins 与 preserve.model.version:4.2.0 还是 4.0.0

DefaultConsumerPomBuilder 里有一条硬性判断:若 model 含 mixins,且未启用 flatten,且未 preserveModelVersion,直接抛 MavenException:

The consumer POM for
cannot be created because the POM contains mixins.
Mixins are not supported in the default consumer POM format.

两条出路:

  1. preserve.model.version=true,生成 modelVersion 4.2.0(支持 mixins);
  2. maven.consumer.pom.flatten=true,去掉 mixins。

默认情况下 Maven 会把 modelVersion 降级为 4.0.0,以兼容 Maven 3;preserve.model.version=true 才保留 4.2.0。

BOM 与 pom-packaging 的特殊处理

BOM(packaging bom)单独处理:packaging 改为 pom;transformPom 中走 withRoot(false).withModules(null).withSubprojects(null),父路径清空。

pom-packaging 的 POM 则干脆只发 build POM,不进 consumer POM 流程。

上手与自查

  • 依赖树对不上,先看 maven.consumer.pom.flatten 的取值。默认 false,consumer 会继承 dependencyManagement,传递依赖的版本可能因此被改写。
  • 项目里有 mixins:要么 preserve.model.version=true 保 4.2.0,要么 maven.consumer.pom.flatten=true。
  • 消费端还停在 Maven 3:默认降级到 modelVersion 4.0.0 就是给这个场景的。
  • 大 BOM / cascading import:MNG-8527 之后不再内联 managed dependencies,发布产物会明显变小。
  • 父 POM、BOM 这类 pom-packaging 坐标:发布出去的就是 build POM,别指望在仓库里看到消费版。
复制全文 生成海报 consumer pom Maven POM 依赖管理 Java构建

推荐文章

程序员茄子在线接单