为何部分重复类触发Maven Shade重叠警告,部分触发Dependency冲突省略?
为什么Maven Shade的重叠类警告和dependency:tree的冲突省略信息不对应?
其实这俩提示本质上来自Maven生态里两个完全不同的工具逻辑,核心目标不一样,所以触发条件自然有区别:
1. mvn dependency:tree -Dverbose的「冲突省略」是Maven核心依赖调解的结果
Maven的依赖解析机制会自动处理同构件(同一个groupId:artifactId)的多版本冲突:当同一个依赖出现多个版本时,Maven会按照「路径最短优先」「声明优先」的规则选出一个版本,把其他版本标记为omitted for conflict with X.X.X。
这个提示的关键是构件级的冲突——只要groupId:artifactId相同、版本不同,不管两个版本里的类有没有重复,都会触发省略标记。而且被标记为omitted的依赖,其实不会被加入到项目的构建classpath里,相当于被Maven排除了。
比如你看到的commons-lang3:3.3.2被省略,是因为Maven最终选了3.5版本,3.3.2的JAR根本不会参与后续的打包过程,所以Shade插件根本碰不到它。
2. Maven Shade插件的「重叠类」警告是打包合并时的类文件扫描结果
Shade插件的核心工作是把所有参与打包的class文件合并成一个胖JAR,它的警告是在扫描实际参与打包的class文件时,发现全限定类名完全相同的类(比如com.esotericsoftware.kryo.Kryo在kryo-4.0.0和kryo-2.21里都存在)才会触发。
这里的关键是类文件级的重复,和构件是否相同无关:
- 哪怕是两个不同groupId:artifactId的JAR,只要有同名类,Shade就会警告;
- 如果是同构件的不同版本,但两个版本的类没有重叠(比如新版本删除了旧类,或者新增了类),Shade也不会警告;
- 另外,只有那些没被Maven依赖调解排除的JAR,才会被Shade扫描——如果某个依赖已经被标记为omitted,它根本不会进入Shade的处理流程,自然不会产生重叠类警告。
为什么你会看到两种不对应的情况?
结合你的例子来看:
- kryo的两个版本触发Shade警告:说明这两个版本的kryo都没有被Maven依赖调解排除(比如它们来自不同的依赖路径,路径长度相同,或者你在pom里同时声明了),所以都进入了Shade的扫描范围,而它们的核心类大量重复,因此触发了重叠类警告;
- commons-lang3的旧版本只触发省略提示:因为Maven已经把3.3.2版本排除了,它不会参与打包,Shade根本没机会扫描到它的类,所以不会产生重叠类警告。
内容的提问来源于stack exchange,提问作者RVS
相关产品推荐
相关产品推荐

