Maven 4 Consumer POM:maven.consumer.pom.flatten 默认变 false,D 拿到的 C 从 1.1 变成 1.2
参考资料:
- 官方研究页:maven.apache.org/studies/consumer-pom
- 提案页:Build vs Consumer POM
- 实现类:DefaultConsumerPomBuilder.java
- PR #11347(新 feature flag):apache/maven#11347
- PR #2058(MNG-8527):apache/maven#2058
为什么要把 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.
两条出路:
preserve.model.version=true,生成modelVersion4.2.0(支持 mixins);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:默认降级到
modelVersion4.0.0 就是给这个场景的。 - 大 BOM / cascading import:MNG-8527 之后不再内联 managed dependencies,发布产物会明显变小。
- 父 POM、BOM 这类 pom-packaging 坐标:发布出去的就是 build POM,别指望在仓库里看到消费版。