Maven多模块依赖冲突:父工程编译SpringBoot项目报错求解决方案
这是典型的Maven依赖传递优先级导致的问题——你的API模块把低版本的javax.servlet-api:2.3传递到了父工程,而Spring Boot子模块默认会继承父工程的依赖版本,导致原本应该用tomcat-embed-core里的高版本Servlet API被覆盖,最终因为缺少方法报错。下面给你几个靠谱的解决方案,按推荐程度排序:
方案1:给API模块的Servlet API依赖设置provided范围
API模块只是用来定义接口的,本身不需要把Servlet API打包到最终产物里,运行时这个依赖会由Spring Boot的Tomcat容器提供。给它加上provided范围后,Maven就不会把这个依赖传递给其他子模块了。
修改API模块的pom.xml:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>2.3</version> <scope>provided</scope> <!-- 关键:编译时用,打包/传递时忽略 --> </dependency>
这是最符合Maven依赖最佳实践的方案,从根源上切断了旧版本依赖的传递路径。
方案2:在父工程用dependencyManagement统一锁定版本
如果不想修改API模块的依赖配置,可以在父工程的pom.xml里通过dependencyManagement节点强制指定所有子模块使用的Servlet API版本(对应Spring Boot Tomcat的版本)。这样不管哪个子模块传递来的依赖,都会优先用这里指定的版本。
父工程pom.xml添加:
<dependencyManagement> <dependencies> <!-- 直接锁定Servlet API的高版本,对应Tomcat 9.0.34的是4.0.1 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!-- 或者直接锁定tomcat-embed-core的版本,确保Spring Boot用自己的依赖 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>9.0.34</version> </dependency> </dependencies> </dependencyManagement>
这个方案适合需要统一管理所有子模块依赖版本的场景,能避免后续其他依赖冲突。
方案3:在Spring Boot子模块中排除API模块的Servlet依赖
如果API模块必须保留javax.servlet-api的传递性(不推荐,但特殊场景可用),可以在Spring Boot子模块引入API模块时,主动排除掉它带来的旧版本Servlet依赖:
修改Spring Boot子模块的pom.xml:
<dependency> <groupId>你的API模块groupId</groupId> <artifactId>你的API模块artifactId</artifactId> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </exclusion> </exclusions> </dependency>
这样Spring Boot子模块就只会使用自身tomcat-embed-core里的Servlet API了。
推荐优先用方案1,它最简洁也最符合依赖设计的原则,修改后重新编译父工程应该就能解决问题了。
内容的提问来源于stack exchange,提问作者Junaed




