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依賴版本降低,導致的