国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Maven】jar包沖突原因與最優(yōu)解決方案

這篇具有很好參考價(jià)值的文章主要介紹了【Maven】jar包沖突原因與最優(yōu)解決方案。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

【Maven】jar包沖突原因與最優(yōu)解決方案

前言

你是否經(jīng)常遇到這樣的報(bào)錯(cuò):

java.lang.NoSuchMethodError
java.lang.ClassNotFoundException
java.lang.NoClassDefFoundError

以上報(bào)錯(cuò)就有可能是jar包沖突造成的,Maven中jar包沖突是開(kāi)發(fā)過(guò)程中比較常見(jiàn)而又令人頭疼的問(wèn)題,我們需要知道 jar包沖突的原理,才能更好的去解決jar包沖突的問(wèn)題。本文將從jar包沖突的原理和解決jar包沖突兩個(gè)方面闡述Maven中jar包問(wèn)題。

jar包沖突原因

當(dāng)我們?cè)趍aven項(xiàng)目中引入第三方組件時(shí),三方組件中的依賴可能會(huì)與項(xiàng)目已有組件發(fā)生沖突。
比如三方組件中依賴httpclient的版本是4.5.x,而項(xiàng)目中已有的httpclient版本是3.1.x,那么此時(shí)就會(huì)產(chǎn)生一下兩種情況:

如果用三方組件的高版本httpclient覆蓋原有的低版本httpclient,有可能會(huì)導(dǎo)致原來(lái)項(xiàng)目啟動(dòng)運(yùn)行失敗。即使高版本兼容低版本,這樣高風(fēng)險(xiǎn)的操作也是很危險(xiǎn)的;

如果在三方maven依賴中對(duì)其對(duì)依賴的httpclient在引入時(shí)使用進(jìn)行排除,使三方組件使用項(xiàng)目中的低版本httpclient,此時(shí)可能會(huì)因?yàn)榘姹静灰恢聦?dǎo)致三方組件無(wú)法使用

在這樣的情況下我們應(yīng)當(dāng)如何保證不影響項(xiàng)目原有依賴版本的情況下正常使用三方組件呢?此時(shí)可以考慮使用maven-shade-plugin插件,jar包沖突解決方案最后介紹。

依賴傳遞

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

關(guān)于依賴作用范圍詳解見(jiàn):【Maven】屬性scope依賴作用范圍詳解。

當(dāng)我們需要A的依賴的時(shí)候,就會(huì)在pom.xml中引入A的jar包;而引入的A的jar包中可能又依賴B的jar包,這樣Maven在解析pom.xml的時(shí)候,會(huì)依次將A、B 的jar包全部都引入進(jìn)來(lái)。

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

com.google.guava guava 20.0 org.springframework.cloud spring-cloud-starter-netflix-hystrix 1.4.4.RELEASE

利用Maven Helper插件得到項(xiàng)目導(dǎo)入的jar包依賴樹(shù):
【Maven】jar包沖突原因與最優(yōu)解決方案
從圖中可以看出Hystrix包含對(duì)Guava jar包依賴的引用: Hystrix -> Guava,所以在引入Hystrix的依賴的時(shí)候,會(huì)將Guava的依賴也引入進(jìn)來(lái)。

沖突原因

假設(shè)有如下依賴關(guān)系:

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

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

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

注:
如果在調(diào)用method2()方法的時(shí)候,D1、D2都含有這個(gè)方法(且升級(jí)的版本D2沒(méi)有改動(dòng)這個(gè)方法,這樣即使D有多個(gè)版本,也不會(huì)產(chǎn)生版本沖突的問(wèn)題。)

舉個(gè)例子:
【Maven】jar包沖突原因與最優(yōu)解決方案
利用Maven Helper插件分析得出:Guava這個(gè)依賴包產(chǎn)生沖突。
我們之前導(dǎo)入了Guava的原生jar包,版本號(hào)是20.0;而現(xiàn)在提示Guava產(chǎn)生沖突,且沖突發(fā)生位置是Hystrix所在的jar包,所以可以猜測(cè)Hystrix中包含了對(duì)Guava不同版本的jar包的引用。

為了驗(yàn)證我們的猜想,使用Maven Helper插件打印出Hystrix依賴的jar tree:
【Maven】jar包沖突原因與最優(yōu)解決方案
可以看到:Hystrix jar中所依賴的Guava jar包是15.0版本的,而我們之前在pom.xml中引入的原生Guava jar包是20.0版本的,這樣Guava就有15.0 與20.0這兩個(gè)版本,因此發(fā)生了jar包沖突。

jar包沖突解決方案

Maven 解析 pom.xml 文件時(shí),同一個(gè) jar 包只會(huì)保留一個(gè),那么面對(duì)多個(gè)版本的jar包,需要怎么解決呢?

Maven默認(rèn)處理策略

最短路徑優(yōu)先

Maven 面對(duì) D1 和 D2 時(shí),會(huì)默認(rèn)選擇最短路徑的那個(gè) jar 包,
即 D2。E->F->D2 比 A->B->C->D1 路徑短1。

最先聲明優(yōu)先

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

排除依賴

移除依賴:用于排除某項(xiàng)依賴的依賴jar包

1.我們可以借助Maven Helper插件中的Dependency Analyzer分析沖突的jar包,然后在對(duì)應(yīng)標(biāo)紅版本的jar包上面點(diǎn)擊execlude,就可以將該jar包排除出去。
【Maven】jar包沖突原因與最優(yōu)解決方案
再刷新以后沖突就會(huì)消失。

2.手動(dòng)排除

手動(dòng)在pom.xml中使用<exclusion>標(biāo)簽去排除沖突的jar包(上面利用插件Maven Helper中的execlude方法其實(shí)等同于方法1):

<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

版本鎖定

版本鎖定原則:一般用在繼承項(xiàng)目的父項(xiàng)目中
正常項(xiàng)目都是多模塊的項(xiàng)目,如moduleA和moduleB共同依賴X這個(gè)依賴的話,那么可以將X抽取出來(lái),同時(shí)設(shè)置其版本號(hào),這樣X(jué)依賴在升級(jí)的時(shí)候,不需要分別對(duì)moduleA和moduleB模塊中的依賴X進(jìn)行升級(jí),避免太多地方(moduleC、moduleD…)引用X依賴的時(shí)候忘記升級(jí)造成jar包沖突,這也是實(shí)際項(xiàng)目開(kāi)發(fā)中比較常見(jiàn)的方法。

首先定義一個(gè)父pom.xml,將公共依賴放在該pom.xml中進(jìn)行聲明:

<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包的時(shí)候,直接使用父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>

maven-shade-plugin插件

作用是將依賴的包在package階段一起打入jar包中,以及對(duì)依賴的jar包進(jìn)行重命名從而達(dá)到隔離的作用。這里為了解決上面的問(wèn)題我們主要使用第二個(gè)功能特性,使得相同依賴不同版本達(dá)到共存的目的。

1.環(huán)境準(zhǔn)備
這里用fastjson來(lái)模擬使用maven-shade-plugin解決項(xiàng)目中不同版本共存問(wèn)題。原項(xiàng)目此時(shí)使用的是1.1.15版本的fastjson

<!-- 原項(xiàng)目 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.1.15</version>
</dependency>

假引入一個(gè)三方依賴,該依賴使用1.2.75版本的fastjson
```xml
<!-- 將引入依賴 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

2.解決方案
搭建一個(gè)新的模塊rename-dependencies,專門用于存放1.2.75依賴。在pom文件中添加1.2.75的依賴,然后添加maven-shade-plugin插件。rename-dependencies的pom如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <groupId>com.sk</groupId>
    <artifactId>rename-dependencies</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <relocations>
                                <relocation>
                                    <pattern>com.alibaba</pattern>
                                    <shadedPattern>shade.com.alibaba</shadedPattern>
                                </relocation>
                            </relocations>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

從配置文件中可以看到,由于maven-shade-plugin插件在解決這個(gè)問(wèn)題上其實(shí)是通過(guò)對(duì)依賴進(jìn)行重命名而達(dá)到隔離的目的,所以配置主要是集中在relocations中。這里將以com.alibaba開(kāi)頭的包全部重命名為以shade.com.alibaba開(kāi)頭。

3.引入依賴
將rename-dependencies進(jìn)行打包,打包好之后在原項(xiàng)目中引入rename-dependencies的依賴。此時(shí)在引入rename-dependencies之后,可以在項(xiàng)目下看到該依賴中的fastjson包名發(fā)生了變化
【Maven】jar包沖突原因與最優(yōu)解決方案

此時(shí)在代碼中調(diào)用fastjson相關(guān)方法,會(huì)提示選擇所需要包,如下圖,此時(shí)問(wèn)題解決,兩個(gè)版本的fastjson可同時(shí)使用已經(jīng)兼容。

【Maven】jar包沖突原因與最優(yōu)解決方案

一些需要注意的坑

描述: 引入依賴找不到重命名的shade包

原因:重命名的模塊和需要引入依賴的模塊在一個(gè)項(xiàng)目中,idea優(yōu)先找本項(xiàng)目,所以沒(méi)有走倉(cāng)庫(kù)

解決方案:
將模塊從項(xiàng)目maven中移除,右鍵項(xiàng)目-maven-unlink maven projects
新建一個(gè)項(xiàng)目專門來(lái)做依賴

總結(jié)

本文從jar包沖突的原理和解決jar包沖突兩個(gè)方面闡述Maven引入jar包依賴的問(wèn)題;

其中在解決方案選擇方面:

如果Maven不能根據(jù)默認(rèn)處理策略解決掉,就需要從移除依賴或者升級(jí)現(xiàn)有依賴處理;

但是升級(jí)現(xiàn)有依賴風(fēng)險(xiǎn)比較大,有時(shí)會(huì)對(duì)原項(xiàng)目不兼容的代碼進(jìn)行大量修改,就比如有次項(xiàng)目引入封裝的工作流組件時(shí),其中組件內(nèi)使用的mybatis-plus為3.5.1版本,原項(xiàng)目使用的3.3.1,先是對(duì)組件排除掉mybatis-plus,但是后面發(fā)現(xiàn)mybatis-plus中有一個(gè)反射工具類無(wú)法使用,只有高版本才能使用,于是就對(duì)原項(xiàng)目做依賴升級(jí),但是需要對(duì)原項(xiàng)目不兼容的代碼進(jìn)行大量修改,比如mybatisconfig類和大量接口返回類型修改;

最優(yōu)選擇:maven-shade-plugin 保證不影響項(xiàng)目原有依賴版本的情況下正常使用三方組件。

參考:

https://blog.csdn.net/qq_38550836/article/details/111567355

https://blog.csdn.net/noaman_wgs/article/details/81137893文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-421876.html

到了這里,關(guān)于【Maven】jar包沖突原因與最優(yōu)解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Maven第八章:如何解決Maven的jar版本沖突

    前言 本文重點(diǎn)講解Maven依賴沖突原因,maven依賴原則以及如何利用idea Maven Helper插件分析解決問(wèn)題。 背景 開(kāi)發(fā)過(guò)程中引入第三方j(luò)ar遇到依賴沖突的,非常影響開(kāi)發(fā),甚至大部分時(shí)間都在調(diào)試版本兼容。

    2024年02月06日
    瀏覽(22)
  • maven依賴jar包時(shí)版本沖突的解決

    maven依賴jar包時(shí)版本沖突的解決

    在pom.xml配置文件中,如果有兩個(gè)名稱相同版本不同的依賴聲明,那么先寫的會(huì)生效。 直接依賴優(yōu)先于傳遞依賴,如果傳遞依賴的jar包版本沖突了,那么可以自己聲明一個(gè)指定版本的依賴jar,即可解決沖突。 傳遞依賴沖突時(shí),可以在不需要的jar的傳遞依賴中聲明排除,從而解

    2024年02月03日
    瀏覽(29)
  • Maven解決jar包版本沖突的4種方法

    ??先解釋下maven的依賴傳遞:a jar包引入了b jar包,如果項(xiàng)目中引入了a jar包,其實(shí)也會(huì)把a(bǔ)依賴的b jar包引入。那現(xiàn)在有a、c這2個(gè)jar包,a jar包依賴的是1.0.0版本的b jar包,c jar包也依賴了b jar包,版本是2.0.0;如果項(xiàng)目中引入了a、c jar包,那b jar包到底引入哪個(gè)版本呢,是1.0.0還

    2024年02月15日
    瀏覽(17)
  • java-IDEA MAVEN查看依賴樹(shù),解決jar包重復(fù)和沖突

    java-IDEA MAVEN查看依賴樹(shù),解決jar包重復(fù)和沖突

    ? ?如果這里面的依賴關(guān)系有紅線,就說(shuō)明有包沖突,一般都是版本不一致,可以在idea里下一個(gè)插件 Maven Helper, 點(diǎn)擊install并重啟IDEA ?打開(kāi)pom.xml文件,在下方會(huì)出現(xiàn)Dependency Analyzer,選擇它會(huì)出現(xiàn)重復(fù)依賴列表,選擇對(duì)應(yīng)的依賴,右鍵紅色部分選擇Exclude,然后選擇上面的reimport就可

    2024年02月13日
    瀏覽(20)
  • 【多線程】| 線程沖突解決方案

    【多線程】| 線程沖突解決方案

    同一進(jìn)程內(nèi)的線程是共享同一內(nèi)存空間的,所以在多個(gè)線程的進(jìn)程里,線程是可以同時(shí)操作這個(gè)進(jìn)程空間的數(shù)據(jù)的,這樣就容易造成線程沖突的情況。 舉個(gè)小李子:一個(gè)房子里(代表一個(gè)進(jìn)程),只有一個(gè)廁所(代表一個(gè)資源)。屋子里面有兩個(gè)人A和B(代表兩個(gè)線程),共

    2024年02月05日
    瀏覽(92)
  • Elasticsearch并發(fā)寫入版本沖突解決方案

    搜索公眾號(hào), AmCoder 干貨及時(shí)送達(dá)??? 眾所周知,es經(jīng)常被用于存儲(chǔ)日志數(shù)據(jù),其中在某些場(chǎng)景下,日志產(chǎn)生的時(shí)機(jī)不同,并且需要將多類具備關(guān)聯(lián)關(guān)系的日志寫入同一個(gè)document,就會(huì)帶來(lái)同一個(gè)文檔可能會(huì)被其它文檔覆蓋,或者missing等問(wèn)題。 大家都知道es是不支持事務(wù)的,

    2023年04月19日
    瀏覽(24)
  • 寶塔面板+Nextcloud搭建教程——可能是目前最優(yōu)解決方案

    寶塔面板+Nextcloud搭建教程——可能是目前最優(yōu)解決方案

    個(gè)人/企業(yè)云盤項(xiàng)目,網(wǎng)上有許多種解決方案。既有像索鳥(niǎo)快傳,Cloudreve等主要面向個(gè)人用戶的項(xiàng)目,也不乏許多如Nextcloud, owncloud, 可道云等優(yōu)秀的商用項(xiàng)目。 Nextcloud是一個(gè)極為優(yōu)秀的個(gè)人/團(tuán)體/商用網(wǎng)盤解決方案,自發(fā)布以來(lái),已經(jīng)經(jīng)過(guò)了二十多個(gè)版本的更新迭代。其前身是

    2024年02月11日
    瀏覽(14)
  • EIP-6963: 多錢包沖突的解決方案

    最近提出的 EIP-6963 旨在提供一個(gè)解決方案,以解決當(dāng)用戶試圖在一個(gè)單一的網(wǎng)絡(luò)瀏覽器中使用多個(gè)錢包供應(yīng)商時(shí)出現(xiàn)的沖突問(wèn)題。在這種情況下,這些沖突的錢包會(huì)導(dǎo)致用戶體驗(yàn)下降,阻礙用戶對(duì)其以太坊界面的控制,并使與 dApp 互動(dòng)的過(guò)程變得復(fù)雜。 原始提案文檔地址:

    2024年03月10日
    瀏覽(23)
  • Git_常用命令+代碼沖突解決方案

    Git_常用命令+代碼沖突解決方案

    –local: 配置對(duì)當(dāng)前倉(cāng)庫(kù)有效 –global: 配置對(duì)當(dāng)前用戶(指的是當(dāng)前用于登錄系統(tǒng)的用戶)的所有倉(cāng)庫(kù)有效 設(shè)置用戶名及郵箱 注意:由于此處設(shè)置的用戶名中間有空格所以要使用雙引號(hào),正常設(shè)置時(shí)無(wú)需使用雙引號(hào) 設(shè)置倉(cāng)庫(kù)的認(rèn)證方式 credentail.helper后的參數(shù)可選: cache: 在第

    2024年04月14日
    瀏覽(27)
  • git請(qǐng)求合并時(shí)出現(xiàn)沖突的解決方案

    git請(qǐng)求合并時(shí)出現(xiàn)沖突的解決方案

    請(qǐng)求合并時(shí)出現(xiàn)沖突,一般是有多人修改了同一個(gè)地方導(dǎo)致的,我們一般在本地解決好沖突后再上傳到遠(yuǎn)端倉(cāng)庫(kù),然后再次發(fā)起合并。 本流程適合無(wú)主分支權(quán)限的情況 在出現(xiàn)沖突的開(kāi)發(fā)分支上解決流程: 1、先拉取主干分支 main到本地開(kāi)發(fā)分支dev git pull origin main 2、借助工具

    2024年02月11日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包