先还原一个场景:项目是一个标准多模块 Maven 工程,外层一个父 pom,下面挂着 common、dao、service、web 这几个子模块。你在 IDEA 里想一次性把它们全部打包,于是盯上 Maven 工具窗口最顶上那个父节点,双击 package,控制台唰唰输出,最后一行显示 BUILD SUCCESS。然后你满怀期待地去 target 目录翻,结果父项目的 target 里没有业务 jar,部分子模块也没有生成对应产物。很多人这时候就会抛出标题里这句话:IDEA 对父项目打包时,不会打包下面的子项目。
每次看到类似问题我都会习惯性反问一句:你说的“打包”,是希望一堆子模块被逐个构建出来,还是希望父项目最终产出的那个包里包含子模块的 class 和配置?这两种诉求看起来差不多,实际解决路径完全不同。下面从 Maven 和 IDEA 的基本行为说起,把父 pom 配置、多模块聚合逻辑、fat jar 与 Spring Boot 的 repackage 触发时机,以及 IDEA 的操作入口差异一次理清楚。
1. 先搞清楚:父项目“打包”这个动作,在不同 packaging 下命运完全不同
1.1 packaging=pom 的父模块更像调度中心,不是装货柜
Maven 多模块项目里有两个容易混淆的层级关系:聚合和继承。聚合靠父 pom 里的 <modules> 把子模块目录列出来,让 Maven 知道“这次构建要带上哪些项目”;继承靠子 pom 里的 <parent> 回指父 pom,让子模块共享父 pom 里的依赖版本、插件配置和公共属性。
如果父 pom 的 <packaging> 写的是 pom,这个模块在 Maven 看来主要是个管理容器。它没有 src/main/java,所以正常情况下不会像 jar 或 war 那样进入 Java 编译和产物打包流程。它的职责是读取 <modules>,把所有子模块纳入同一个 reactor 构建批次,再按模块间的依赖顺序逐个构建。
这也是“父项目打包不会打包下面的子项目”这句话最容易产生的误解:你看到的父项目 target 里没有东西,不代表子模块没被打包,而是因为父模块本身就没有普通 jar 产物。真正的产物都应该在“各自子模块”的 target 目录下:
`
