日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

一、前言

什么是依賴沖突

依賴沖突是指項(xiàng)目依賴的某一個(gè)jar包,有多個(gè)不同的版本,因而造成了包版本沖突。

依賴沖突的原因

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

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

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

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

當(dāng)然會(huì)有的

1、你想如果B引用X(2.0)的新創(chuàng)建的類,但因?yàn)樽罱K被解析的是X(1.0),所以就會(huì)出現(xiàn)很典型的NoClassDefFoundError 或ClassNotFoundException依賴沖突報(bào)錯(cuò)。

2、如果B引用X(2.0)的新創(chuàng)建的方法,但因?yàn)樽罱K被解析的是X(1.0),所以就會(huì)拋出 NoSuchMethodError系統(tǒng)異常。

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

那也不一定

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

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

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

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


 

二、maven依賴原則

maven依賴主要有兩大原則

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

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

舉例

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

該例中X(1.0)的路徑長度為3,而X(2.0)的路徑長度為2,因此X(2.0)會(huì)被解析使用。依賴調(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中依賴聲明的順序決定了誰會(huì)被解析使用,順序最前的那個(gè)依賴優(yōu)勝。該例中,如果A的依賴聲明在C之前,那么Y (1.0)就會(huì)被解析使用.

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


 

三、如何排除依賴

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

1、什么是傳遞性依賴

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

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

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

  <dependency>
     <groupId>org.Apache.poi</groupId>
     <artifactId>poi-ooxml</artifactId>
     <version>3.10.1</version>
  </dependency>

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

  <dependencies>
    <dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi</artifactId>
       <version>3.10.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>3.10.1</version>
    </dependency>
    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>1.6.1</version>
    </dependency>
 </dependencies>

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

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

2、如何排除依賴

關(guān)鍵字:exclusions

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

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

示例

   <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.10.1</version>
            <!--排除poi依賴-->
        <exclusions>
            <exclusion>
                <artifactId>poi</artifactId>
                <groupId>org.apache.poi</groupId>
             </exclusion>
        </exclusions>
   </dependency>


 

四、實(shí)例演示如何解決依賴沖突

我們先來復(fù)現(xiàn)因?yàn)橐蕾嚊_突導(dǎo)致項(xiàng)目報(bào)錯(cuò)的。

1、制造依賴沖突

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

pom文件如下:

   <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.10.1</version>
   </dependency>
   <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.2.8</version>
   </dependency>

然后在項(xiàng)目中添加如下代碼:

@SpringBootApplication
public 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里面的方法實(shí)現(xiàn)寫操作
		EasyExcel.write(fileName, UserDto.class).sheet("某某報(bào)表").doWrite(new ArrayList<>());
	}
}	

我們發(fā)現(xiàn)在SpringBoot啟動(dòng)的時(shí)候就報(bào)NoClassDefFoundError異常了。

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

 

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

為什么會(huì)這樣呢,我們可以通過idea看下,打開maven菜單,點(diǎn)擊show dependencies。

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

 

看到這里你大概就已經(jīng)明白,因?yàn)槲耶?dāng)前的easyexcel引入的poi是3.17版本的,但是因?yàn)楦鶕?jù)maven依賴原則,實(shí)際引入的poi版本確實(shí)是3.10.1版本的。


DefaultTempFileCreationStrategy這個(gè)類在3.10.1這個(gè)版本并沒有,只有3.17版本才有,所以報(bào)了這個(gè)錯(cuò)誤,這么一解釋是不是都通了。

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

Maven管理插件

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

選擇并下載插件

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

 

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

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

 

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

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

 

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

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

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

 

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

   <dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-ooxml</artifactId>
       <version>3.10.1</version>
       <exclusions>
          <exclusion>
             <artifactId>poi</artifactId>
             <groupId>org.apache.poi</groupId>
           </exclusion>
       </exclusions>
    </dependency>
    <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>easyexcel</artifactId>
       <version>2.2.6</version>
    </dependency>

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

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

 

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


 

五、總結(jié)

一般我們在解決依賴沖突的時(shí)候,都會(huì)選擇保留jar高的版本,因?yàn)榇蟛糠謏ar在升級的時(shí)候都會(huì)做到向下兼容,所以只要保留高的版本就不會(huì)有什么問題。

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

就比如下面這個(gè)案例

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

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

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

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

們?nèi)タ紤]的。所以說為什么說一個(gè)大型項(xiàng)目穩(wěn)定后,pom文件的升級是件繁瑣的事情,那是因?yàn)榭紤]的東西是在太多了,稍有不慎就會(huì)因?yàn)橐蕾嚊_突而導(dǎo)致系統(tǒng)報(bào)錯(cuò)。

分享到:
標(biāo)簽:maven
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定