使用maven-enforcer-plugin出现Dependency convergence错误如何解决?
dependencyConvergence 规则核心逻辑
该规则的核心要求是:整个项目的依赖树中,同一groupId+artifactId的依赖,在所有引入路径里只能出现唯一版本。它完全不遵循Maven默认的「最短路径优先」「声明顺序优先」的依赖仲裁逻辑,只要存在多版本引入的情况,哪怕Maven最终仲裁只会用其中一个版本,也会直接报错,从根源上避免依赖版本不一致导致的运行时兼容问题。
你当前测试POM报错的根本原因:
- dependencyManagement中固定了
spring-core:5.2.10.RELEASE版本 - 直接依赖的
spring-context:5.3.5本身传递依赖的是spring-core:5.3.5,和dependencyManagement的版本形成冲突 spring-security-web:5.4.5也会传递引入对应版本的Spring基础组件,和你直接声明的spring-context:5.3.5版本不匹配,多个路径出现同组件不同版本,触发校验失败。
修复方案(按推荐优先级排序)
方案1:引入官方BOM统一管理同体系依赖(最适合企业级项目)
Spring、Spring Security这类同生态的组件,官方已经提供了经过全量兼容性测试的BOM(物料清单),不需要你手动逐个声明每个组件的版本:
- 首先在dependencyManagement中引入对应大版本的
spring-framework-bom和spring-security-bom - 后续声明所有Spring、Spring Security相关的直接依赖时,不需要填写版本号,自动和BOM内的版本对齐,从根源上避免同生态组件的版本冲突。
这种方式不会让你的POM变得臃肿,你只需要引入少量官方聚合BOM即可,不需要自己维护上百个依赖的版本,对构建耗时的影响可以忽略不计。
方案2:在dependencyManagement中统一声明冲突依赖的版本
如果冲突的依赖没有官方BOM,或者你需要自定义指定版本,可以将所有出现版本冲突的groupId+artifactId在dependencyManagement中声明一次你期望的唯一版本即可。
注意:直接依赖如果填写了版本号,优先级会高于dependencyManagement的配置,所以如果用这种方案,建议所有直接依赖都不要写版本号,版本完全由dependencyManagement统一管控,避免出现直接依赖版本和统一版本冲突的问题。
方案3:排除传递依赖(仅适合个别特殊场景)
如果只有个别第三方依赖引入了冲突版本,且无法通过上面两种方案调整,再使用exclusion排除冲突的传递依赖。不要将该方案作为常规处理方式,会导致POM配置冗余,后续维护成本极高。
企业级项目使用dependencyConvergence的最佳实践
- 优先引入官方BOM:所有主流开源生态比如Spring全家桶、Spring Cloud、Jackson、Apache Commons系列都有官方维护的BOM,引入后能解决90%以上的同生态依赖版本冲突问题
- 自定义dependencyManagement仅用来声明零散的、无官方BOM的第三方依赖版本,以及覆盖官方BOM中的特定组件版本
- 所有直接依赖均不写版本号,版本完全由dependencyManagement(包括引入的BOM)统一管理
- 出现冲突时优先排查是否手动声明了和BOM不一致的版本,或是引入的第三方依赖没有对齐主栈版本,针对性调整即可,不需要把所有传递依赖都声明到dependencyManagement中,只有出现冲突的组件需要处理
内容的提问来源于stack exchange,提问作者samshers
相关产品推荐
相关产品推荐

