Maven的 parent 解决配置继承,modules 解决一起构建。一个项目可以同时承担两种角色,但“某项目是父项目”本身,不意味着对它执行package就会构建所有继承者。
用一个最小目录区分两条关系
假设有以下布局:
demo/
pom.xml
app/
pom.xml
根POM同时提供共享属性并列出模块:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>demo-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<demo.message>shared-value</demo.message>
</properties>
<modules>
<module>app</module>
</modules>
</project>
app/pom.xml 指定父POM:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>example</groupId>
<artifactId>demo-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>app</artifactId>
</project>
这个结构中,app从父POM继承groupId、version及共享属性;根POM通过modules把app纳入聚合。两条关系恰好重合,但并不必然重合。Maven POM:继承与聚合
改一处,就能看出它们不相同
如果从根POM移除modules,app仍可以继承它,但从根项目启动的构建不会自动搜索磁盘上所有把它当parent的项目。
反过来,聚合POM也可以列出不以自己为parent的模块。聚合选择谁进入同次构建;继承决定每个项目的有效配置,不能互相替代。
另外,“构建所有模块”不是把所有子模块内容塞进一个JAR。各模块按各自packaging产生产物;聚合根的 pom 类型也不是可执行应用包。
构建入口决定这次会做什么
在根目录执行 mvn package 与进入app目录执行同一目标,项目集合可能不同。-pl、-am 等选择项还会影响reactor范围;依赖关系用于安排顺序,modules列表顺序不是唯一依据。Maven reactor说明
排查时分别核对父坐标、relativePath、模块路径、有效POM和Reactor Build Order。不要仅凭看到parent标签,就断言所有兄弟模块都已打包或发布。