maven错误排查经验
maven依赖的仲裁原则
- 有parent的情况先合并parent中的dependencies和dependencyManagement,到当前pom的dependencies和dependencyManagement,依照上层覆盖下层原则
- 不同路径深度,短路径优先;
- 相同路径深度,相同区域(dependencies或者dependencyManagement),深度为1后引入优先,深度不为1时,先引入为先
- 相同路径深度,不同区域,dependencies区域优先
- 只有最上层的dependencyManagement起作用,其他层的dependencyManagement将被忽略;
示例:
-
不同路径,短路径优先
C --> A 1.0 -->B 1.0
--> B 2.0最终是依赖于2.0
-
相同路径,路径为1后引入优先
C --> A 1.0
--> A 2.0
最终依赖于A 2.0 -
相同路径,路径不为1先引入优先
C --> A 1.0 --> B 1.0
--> D 1.0 --> B 2.0
最终依赖于B 1.0
常见的问题
由于pom依赖的问题,导致jar版本冲突,报错信息NoSuchMethodException,同类问题ClassNotFoundException、NoClassDefException、ClassCastException
排查方式
- -XX:+TraceClassLoading
加启动参数,会把这个类是从哪个jar包加载的打印出来 - jar -tvf *.jar
tomcat 从lib目录下加载jar包,解压打印所有的类,查找包名类名相同的,如果存在且md5不一样,就是版本冲突
解决方式:
mvn中做exclusion
心得体会:
最近在排查依稀pom依赖冲突,应用依赖了IC和UIC的相关pom,在升级相关版本的时候,jar包冲突,而且有很多依赖代码并没有实际引用,但是在启动的时候报了NoClassDef。
通常情况下,这种升级某个pom依赖后导致的jar包问题,最好的方式:在升级的版本依赖dependency是exclusion对应的冲突jar,一开始也是这样解决的,但是依然部署不起来,按照道理来讲,排除了这个依赖以后,应该是其他依赖包引入的。进过排查,有两个原因:
-
发现原来的spring升级不成功,导致依赖的pom实际是IC的pom,而exclusion后,版本降低,代码报错
-
同路径依赖,原先也是依赖IC的pom,排除以后,依赖版本不对进而报错
A -- IC --> B 3.0
C --> D --> B 2.0
E --> F --> B 1.0
这种情况下,原理依赖的B 3.0,由于升级了IC,exclusion B,之后B依赖版本降低,导致的