在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    解決maven依賴沖突,這篇就夠了

    解決maven依賴沖突,這篇就夠了

    一、前言

    什么是依賴沖突

    依賴沖突是指項目依賴的某一個jar包,有多個不同的版本,因而造成了包版本沖突。

    依賴沖突的原因

    我們在maven項目的pom中 一般會引用許許多多的dependency。例如,項目A有這樣的依賴關(guān)系:

    A -> C -> X(1.0)B -> D -> X(2.0)

    X是A的傳遞性依賴,但是兩條依賴路徑上有兩個版本的X,那么哪個X會被Maven解析使用呢? 兩個版本都被解析顯然是不對的,因為那會造成依賴重復(fù),因此必須選擇一個。

    至于怎么選肯定有它的規(guī)則(下面會講),這里我們先假設(shè)最終引用的X(1.0)版本,這樣會不會有問題呢?

    當(dāng)然會有的

    1、你想如果B引用X(2.0)的新創(chuàng)建的類,但因為最終被解析的是X(1.0),所以就會出現(xiàn)很典型的NoClassDefFoundError 或ClassNotFoundException依賴沖突報錯。

    2、如果B引用X(2.0)的新創(chuàng)建的方法,但因為最終被解析的是X(1.0),所以就會拋出 NoSuchMethodError系統(tǒng)異常。

    但換種角度,如果最終解析的是X(2.0),就沒問題了嗎?

    那也不一定

    1、如果X(2.0)刪掉了X(1.0)的一些類,但A已經(jīng)引用了,同樣也會報NoClassDefFoundError或者ClassNotFoundException錯誤。

    2、如果X(2.0)刪掉了X(1.0)的一些方法,但A已經(jīng)引用了,同樣也會報NoSuchMethodError錯誤。

    所以說具體問題還需具體分析,到底采用哪個版本還需要看實際項目。也可能我們需要升級對應(yīng)的A或者B的版本才能解決問題。

    如果有兩個版本的X,Maven是依據(jù)什么原則來選擇解析哪個X呢?

    二、maven依賴原則

    maven依賴主要有兩大原則

    1、路徑最近者優(yōu)先

    相同jar不同版本,根據(jù)依賴的路徑長短來決定引入哪個依賴。

    舉例

    依賴鏈路一:A -> B -> C -> X(1.0)依賴鏈路二:F -> D -> X(2.0)

    該例中X(1.0)的路徑長度為3,而X(2.0)的路徑長度為2,因此X(2.0)會被解析使用。依賴調(diào)解第一原則不能解決所有問題,比如這樣的依賴關(guān)系:

    A -> B -> Y(1.0)c -> D -> Y(2.0)

    Y(1.0)和Y(2.0)的依賴路徑長度是一樣的,都為2。Maven定義了依賴調(diào)解的第二原則:

    2、第一聲明者優(yōu)先

    在依賴路徑長度相等的前提下,在POM中依賴聲明的順序決定了誰會被解析使用,順序最前的那個依賴優(yōu)勝。該例中,如果A的依賴聲明在C之前,那么Y (1.0)就會被解析使用.

    注意 子pom內(nèi)聲明的優(yōu)先于父pom中的依賴。

    三、如何排除依賴

    我們先來解釋下什么是傳遞性依賴

    1、什么是傳遞性依賴

    比如當(dāng)我們項目中,引用了A的依賴,A的依賴通常又會引入B的jar包,B可能還會引入C的jar包。

    這樣,當(dāng)你在pom.xml文件中添加了A的依賴,Maven會自動的幫你把所有相關(guān)的依賴都添加進(jìn)來。

    這里隨便舉一個例子,比如我們?yōu)榱藢崿F(xiàn)導(dǎo)入導(dǎo)出功能我們可能會引入poi

    org.apache.poi poi-ooxml 3.10.1

    當(dāng)你引入它的時候,它其實還會映入其它jar包

    org.apache.poi poi 3.10.1 org.apache.poi poi-ooxml-schemas 3.10.1 dom4j dom4j 1.6.1

    就這樣一層層的,Maven會自動的幫你把所有相關(guān)的依賴都添加進(jìn)來。傳遞性依賴會給項目引入很多依賴,簡化項目依賴管理,但是也會帶來問題。

    最明顯的就是容易發(fā)生依賴沖突。

    2、如何排除依賴

    關(guān)鍵字:exclusions

    exclusions可以包含一個或者多exclusion子元素,因此可以排除一個或者多個傳遞性依賴。

    需要注意的是,聲明exclusion的時候只需要groupld和artifactld,而不需要要version元素。

    示例

    org.apache.poi poi-ooxml 3.10.1 poi org.apache.poi

    四、實例演示如何解決依賴沖突

    我們先來復(fù)現(xiàn)因為依賴沖突導(dǎo)致項目報錯的。

    1、制造依賴沖突

    在當(dāng)前項目中,我即引用了org.apache.poi,又引用了com.alibaba的easyexcel。

    pom文件如下:

    org.apache.poi poi-ooxml 3.10.1 com.alibaba easyexcel 2.2.8

    然后在項目中添加如下代碼:

    @SpringBootApplicationpublic class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);test();}public static void test() {//1.獲取文件地址String fileName = “/excel/test.xlsx”;//2、調(diào)用easyExcel里面的方法實現(xiàn)寫操作EasyExcel.write(fileName, UserDto.class).sheet(“某某報表”).doWrite(new ArrayList());}}

    我們發(fā)現(xiàn)在SpringBoot啟動的時候就報NoClassDefFoundError異常了。

    這就是依賴沖突導(dǎo)致的異常報錯。

    為什么會這樣呢,我們可以通過idea看下,打開maven菜單,點擊show dependencies。

    看到這里你大概就已經(jīng)明白,因為我當(dāng)前的easyexcel引入的poi是3.17版本的,但是因為根據(jù)maven依賴原則,實際引入的poi版本確實是3.10.1版本的。

    而DefaultTempFileCreationStrategy這個類在3.10.1這個版本并沒有,只有3.17版本才有,所以報了這個錯誤,這么一解釋是不是都通了。

    然后我們再來思考一個問題,上面這個案例我們一眼就知道是最終應(yīng)用哪個依賴?yán)锏哪膫€版本,但如果你的項目中依賴許許多多的jar,肉眼排查就沒那么方便了,這里推薦一個

    Maven管理插件

    2、Maven Helper插件分析jar包沖突

    選擇并下載插件

    在pom文件中看到 dependency analyzer標(biāo)志,說明maven helper插件就安裝成功了。

    點擊dependency analyzer之后就會進(jìn)入到下面的頁面

    從圖中可以看出有哪些jar存在沖突,存在沖突的情況下最終采用了哪個依賴的版本。標(biāo)紅的就是沖突版本,白色的是當(dāng)前的解析版本。

    如果我們想保留標(biāo)紅的版本,那我們可以標(biāo)白區(qū)域右擊選擇排除(Exclude)

    然后我們再來看pom文件,發(fā)現(xiàn)在org.apache.poi中已經(jīng)移除了poi了。

    org.apache.poi poi-ooxml 3.10.1 poi org.apache.poi com.alibaba easyexcel 2.2.6

    我們再來看最終引用的poi版本是哪個?

    我們發(fā)現(xiàn)最終的版本最終已經(jīng)變成3.17版本,現(xiàn)在再啟動就不會報錯了,成功解決依賴沖突問題。

    五、總結(jié)

    一般我們在解決依賴沖突的時候,都會選擇保留jar高的版本,因為大部分jar在升級的時候都會做到向下兼容,所以只要保留高的版本就不會有什么問題。

    但是有些包,版本變化大沒法去做向下兼容,高版本刪了低版本的某些類或者某些方法,那么這個時候就不能一股腦的去選擇高版本,但也不能選擇低版本。

    就比如下面這個案例

    依賴鏈路一:A -> B -> C -> X(1.0)依賴鏈路二:F -> D -> X(2.0)

    X(2.0) 沒有對 X(1.0) 做向下兼容也就是說可能存在排除哪個都不行,那怎么辦我們只能考慮升級A的版本或者降低F的版本。比如A升級到A(2.0),使它依賴的X版本

    變成X(2.0)這樣的話就解決依賴沖突。

    但話有說回來 A升級到A(2.0) 可能會影響許許多多的地方,比如自己項目中代碼是否需要改變,或者因為 A升級到A(2.0) 導(dǎo)致 B和C的版本有所改變,這些影響點都需要我

    們?nèi)タ紤]的。所以說為什么說一個大型項目穩(wěn)定后,pom文件的升級是件繁瑣的事情,那是因為考慮的東西是在太多了,稍有不慎就會因為依賴沖突而導(dǎo)致系統(tǒng)報錯。

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    上一篇 2022年6月20日 06:17
    下一篇 2022年6月20日 06:17

    相關(guān)推薦

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息