欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Maven中jar包沖突原理與解決辦法

 更新時間:2020年09月04日 10:34:39   作者:是Guava不是瓜娃  
這篇文章主要介紹了Maven中jar包沖突原理與解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧

Maven中jar包沖突是開發(fā)過程中比較常見而又令人頭疼的問題,我們需要知道 jar包沖突的原理,才能更好的去解決jar包沖突的問題。本文將從jar包沖突的原理和解決兩個方面闡述Maven中jar包沖突的解決辦法。

一、Maven中jar包沖突產(chǎn)生原因

MAVEN項目運行中如果報如下錯誤:

Caused by:java.lang.NoSuchMethodError
Caused by: java.lang.ClassNotFoundException

十有八九是Maven jar包沖突造成的。那么jar包沖突是如何產(chǎn)生的?

首先我們需要了解jar包依賴的傳遞性。

1、依賴傳遞

當我們需要A的依賴的時候,就會在pom.xml中引入A的jar包;而引入的A的jar包中可能又依賴B的jar包,這樣Maven在解析pom.xml的時候,會依次將A、B 的jar包全部都引入進來。

舉個例子:
在Spring Boot應(yīng)用中導(dǎo)入Hystrix和原生Guava的jar包:

<!--原生Guava API-->
<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>20.0</version>
</dependency>

<!--hystrix依賴(包含對Guava的依賴)-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	<version>1.4.4.RELEASE</version>
</dependency>

利用Maven Helper插件得到項目導(dǎo)入的jar包依賴樹:


從圖中可以看出Hystrix包含對Guava jar包依賴的引用: Hystrix -> Guava,所以在引入Hystrix的依賴的時候,會將Guava的依賴也引入進來。

2、jar包沖突原理

那么jar包是如何產(chǎn)生沖突的?
假設(shè)有如下依賴關(guān)系:

A->B->C->D1(log 15.0):A中包含對B的依賴,B中包含對C的依賴,C中包含對D1的依賴,假設(shè)是D1是日志jar包,version為15.0

E->F->D2(log 16.0):E中包含對F的依賴,F(xiàn)包含對D2的依賴,假設(shè)是D2是同一個日志jar包,version為16.0

當pom.xml文件中引入A、E兩個依賴后,根據(jù)Maven傳遞依賴的原則,D1、D2都會被引入,而D1、D2是同一個依賴D的不同版本。
當我們在調(diào)用D2中的method1()方法,而D1中是15.0版本(method1可能是D升級后增加的方法),可能沒有這個方法,這樣JVM在加載A中D1依賴的時候,找不到method1方法,就會報NoSuchMethodError的錯誤,此時就產(chǎn)生了jar包沖突。

注:
如果在調(diào)用method2()方法的時候,D1、D2都含有這個方法(且升級的版本D2沒有改動這個方法,這樣即使D有多個版本,也不會產(chǎn)生版本沖突的問題。)

舉個例子:


利用Maven Helper插件分析得出:Guava這個依賴包產(chǎn)生沖突。
我們之前導(dǎo)入了Guava的原生jar包,版本號是20.0;而現(xiàn)在提示Guava產(chǎn)生沖突,且沖突發(fā)生位置是Hystrix所在的jar包,所以可以猜測Hystrix中包含了對Guava不同版本的jar包的引用。

為了驗證我們的猜想,使用Maven Helper插件打印出Hystrix依賴的jar tree:


可以看到:Hystrix jar中所依賴的Guava jar包是15.0版本的,而我們之前在pom.xml中引入的原生Guava jar包是20.0版本的,這樣Guava就有15.0 與20.0這兩個版本,因此發(fā)生了jar包沖突。

二、 Maven中jar包沖突的解決方案

Maven 解析 pom.xml 文件時,同一個 jar 包只會保留一個,那么面對多個版本的jar包,需要怎么解決呢?

1、 Maven默認處理策略最短路徑優(yōu)先

Maven 面對 D1 和 D2 時,會默認選擇最短路徑的那個 jar 包,即 D2。E->F->D2 比 A->B->C->D1 路徑短 1。

最先聲明優(yōu)先

如果路徑一樣的話,如: A->B->C1, E->F->C2 ,兩個依賴路徑長度都是 2,那么就選擇最先聲明。

2、移除依賴:用于排除某項依賴的依賴jar包

(1)我們可以借助Maven Helper插件中的Dependency Analyzer分析沖突的jar包,然后在對應(yīng)標紅版本的jar包上面點擊execlude,就可以將該jar包排除出去。


再刷新以后沖突就會消失。

(2)手動排除
或者手動在pom.xml中使用<exclusion>標簽去排除沖突的jar包(上面利用插件Maven Helper中的execlude方法其實等同于該方法):

<dependency>
	<groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
		<version>1.4.4.RELEASE</version>
		<exclusions>
			<exclusion>
				<groupId>com.google.guava</groupId>
				<artifactId>guava</artifactId>
			</exclusion>
	</exclusions>
</dependency>

mvn分析包沖突命令:

mvn dependency:tree

3 版本鎖定原則:一般用在繼承項目的父項目中

正常項目都是多模塊的項目,如moduleA和moduleB共同依賴X這個依賴的話,那么可以將X抽取出來,同時設(shè)置其版本號,這樣X依賴在升級的時候,不需要分別對moduleA和moduleB模塊中的依賴X進行升級,避免太多地方(moduleC、moduleD…)引用X依賴的時候忘記升級造成jar包沖突,這也是實際項目開發(fā)中比較常見的方法。

首先定義一個父pom.xml,將公共依賴放在該pom.xml中進行聲明:

<properties>
  <spring.version>spring4.2.4</spring.version>
<properties>

<dependencyManagement>
  <dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.versio}</version>
		</dependency>
	</dependencies>
</dependencyManagement>

這樣如moduleA和moduleB在引用Spring-beans jar包的時候,直接使用父pom.xml中定義的公共依賴就可以:
moduleA在其pom.xml使用spring-bean的jar包(不用再定義版本):

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
	</dependency>
</dependencies>

moduleB在其pom.xml使用spring-bean的jar包如上類似:

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
	</dependency>
</dependencies>

以上就是日常開發(fā)中解決Maven沖突的幾個小方案,當然實際開發(fā)中jar包沖突的問題可能遠遠比這個更復(fù)雜,需要具體問題具體處理。更多相關(guān)Maven jar包沖突內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Springboot打成jar包thymeleaf的問題

    使用Springboot打成jar包thymeleaf的問題

    這篇文章主要介紹了使用Springboot打成jar包thymeleaf的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java 中枚舉類enum的values()方法的詳解

    java 中枚舉類enum的values()方法的詳解

    這篇文章主要介紹了java 中枚舉類enum的values()方法的詳解的相關(guān)資料,希望通過本文大家能夠掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • Spring Cloud OAuth2中/oauth/token的返回內(nèi)容格式

    Spring Cloud OAuth2中/oauth/token的返回內(nèi)容格式

    Spring Cloud OAuth2 生成access token的請求/oauth/token的返回內(nèi)容就需要自定義,本文就詳細介紹一下,感興趣的可以了解一下
    2021-07-07
  • Java concurrency之互斥鎖_動力節(jié)點Java學(xué)院整理

    Java concurrency之互斥鎖_動力節(jié)點Java學(xué)院整理

    本文通過示例代碼給大家介紹了Java concurrency之互斥鎖的相關(guān)知識,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-06-06
  • Maven下載依賴的順序及配置文件小結(jié)

    Maven下載依賴的順序及配置文件小結(jié)

    本文主要介紹了Maven下載依賴的順序及配置文件小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2023-07-07
  • java類與對象案例之打字游戲

    java類與對象案例之打字游戲

    這篇文章主要為大家詳細介紹了java類與對象案例之打字游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • mapstruct的用法之qualifiedByName示例詳解

    mapstruct的用法之qualifiedByName示例詳解

    qualifiedByName的意思就是使用這個Mapper接口中的指定的默認方法去處理這個屬性的轉(zhuǎn)換,而不是簡單的get?set,今天通過本文給大家介紹下mapstruct的用法之qualifiedByName示例詳解,感興趣的朋友一起看看吧
    2022-04-04
  • MyBatis查詢返回Map示例代碼

    MyBatis查詢返回Map示例代碼

    這篇文章主要給大家介紹了關(guān)于MyBatis查詢返回Map的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2018-10-10
  • Springboot快速集成sse服務(wù)端推流(最新整理)

    Springboot快速集成sse服務(wù)端推流(最新整理)

    SSE?Server-Sent?Events是一種允許服務(wù)器向客戶端推送實時數(shù)據(jù)的技術(shù),它建立在?HTTP?和簡單文本格式之上,提供了一種輕量級的服務(wù)器推送方式,通常也被稱為“事件流”(Event?Stream),這篇文章主要介紹了Springboot快速集成sse服務(wù)端推流(最新整理),需要的朋友可以參考下
    2024-02-02
  • Java并發(fā)編程之原子操作類詳情

    Java并發(fā)編程之原子操作類詳情

    這篇文章主要介紹了Java并發(fā)編程之原子操作類詳情,文章基于Java并發(fā)編程展開相關(guān)內(nèi)容,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-04-04

最新評論