Maven多模块项目正确结构是:父模块packaging必须为pom,子模块路径在父pom的中显式声明且目录需在父模块下;子模块通过继承版本与插件,依赖需在各自pom中声明才能生效。
多模块项目不是把多个 pom.xml 放进不同文件夹就完事。核心是:一个父模块(pom packaging 为 pom)统一管理子模块的版本、插件和依赖,子模块必须在父模块的 中显式声明。
常见错误是子模块目录不在父模块下,或父模块的 packaging 写成 jar —— 这会导致 Maven 完全忽略 配置,子模块压根不参与构建。
pom.xml,且 pom
pom.xml 的 里,如:user-service
必须指向父模块的 groupId + artifactId + version,不能只写坐标不写
显式设为空:,避免 Maven 错误向上查找父模块的 只做**版本仲裁**,不引入实际依赖;子模块需在自己 pom.xml 中声明 和 才会真正引入——这点极易混淆,导致编译报 ClassNotFoundException。
插件同理: 在父模块中统一配置插件版本和默认参数,但子模块必须在自己的 中显式写出插件坐标,才会生效。
管理 Spring Boot 版本:spring-boot-dependencies,子模块只需写 org.springframework.boot spring-boot-starter-web 即可pom.xml 中写:org.apache.maven.plugins maven-surefire-plugintrue
中直接写依赖(除非是所有子模块共用的 API 模块),否则会强制所有子模块都引入该依赖子模块之间依赖必须用 compile 范围(默认),且依赖的模块必须已安装到本地仓库或在同一构建中被先编译。最常踩的坑是:A 模块依赖 B,但 B 尚未构建,又没执行 mvn install,直接运行 A 会提示 Could not find artifact。
更隐蔽的问题是“隐式传递依赖”:B 模块依赖了 C 的某个旧版 jar,而 A 模块又直接依赖新版 C —— 此时 Maven 默认按“第一声明优先”策略选旧版,导致 A 运行时报 NoSuchMethodError。
com.example common-utils${project.version} ,用 ${project.version} 确保版本同步system 范围或 systemPath 引入 jar,这会让模块无法被其他机器构建mvn dependency:tree -Dverbose 查看依赖链,若出现 A → B → A,则必须拆分或引入中间接口模块IDEA 不会自动识别父子关系,单纯打开父目录 ≠ 正确导入多模块项目。常见现象是:父 pom.xml 显示 “Maven project”,但子模块只是普通文件夹,没有小蓝标,也无法右键运行 mvn clean compile。
根本原因是 IDEA 没触发 Maven import 流程,或缓存了旧配置。此时靠“Reload project”按钮往往无效,必须重置上下文。
.idea 文件夹和所有 *.iml 文件clean、compile 等生命周期命令4.0.0 com.example parent-project1.0.0-SNAPSHOT pom user-service order-service common-utils org.springframework.boot spring-boot-dependencies3.2.0 pom import
模块名拼错、relativePath 指向偏差、IDE 缓存残留——这三个点卡住的人最多。别急着查文档,先确认父 pom 是否真被识别为 packaging=pom,再看 IDEA 的 Maven 面板有没有列出全部子模块。别的都可以调,这个结构对不上,后面全是白忙。