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

Maven版本沖突的原因分析和解決指南

 更新時間:2025年11月09日 08:30:11   作者:皮皮林551  
我們可能會因為Maven功能變更、性能提升、修復(fù)漏洞等多種原因,去更換第三方庫或框架,此時就容易發(fā)生版本沖突,本期我們就介紹一下相關(guān)知識,以及如何解決版本沖突方法,需要的朋友可以參考下

之前我們講解了Maven的配置,那么這次我們就講講一些更貼近日常維護(hù)的東西,就是maven的版本控制,在一個工程的正常生命周期內(nèi)。

我們可能會因為功能變更、性能提升、修復(fù)漏洞等多種原因,去更換第三方庫或框架。此時就容易發(fā)生版本沖突,本期我們就介紹一下相關(guān)知識,以及如何解決版本沖突。

一、版本沖突的原因

內(nèi)部沖突:  當(dāng)一個項目直接依賴了不同的版本號,可能會導(dǎo)致沖突。

模塊間沖突:  一個庫內(nèi)部不同模塊之間使用了不同的版本號,或互相引用時,也可能導(dǎo)致沖突。

二、查看與分析沖突

1. 依賴樹

① 原生命令

使用dependency:tree命令查看依賴樹:maven提供了一個命令mvn dependency:tree,可以查看項目的依賴樹,從而幫助我們分析版本沖突的原因。例如:

mvn dependency:tree

運(yùn)行上述命令,maven會打印出項目的依賴樹,我們可以根據(jù)這個依賴樹找到?jīng)_突的版本并解決它。

② Maven Helper

原生命令的可視化成都有限,所以對于開發(fā)者來說,最常用的還是在IDEA上安裝maven helper插件了,我們可以在IDEA插件市場里將其安裝上

安裝并啟用成功后,我們打開某pom文件,就能看到該pom下的依賴情況了

2. 沖突分析

① 查看沖突

在安裝完Maven Helper后, 我們其實可以直接看到有哪些沖突,如下圖,項目上就存在如下的jar包沖突,當(dāng)我們選中poi-oomxl后,右邊則具體顯示了造成該沖突的具體情況

不難看出,項目中用了多個不同的組件,而這些組件又使用了不同版本的 poi-oomxl,最終導(dǎo)致在項目中引用了三個不同版本的 poi-oomxl

② maven的版本規(guī)則

不難看出,盡管項目中依賴了三個不同的版本,但最后我們實際在項目中存在的卻只會有一個 poi-oomxl 組件。那么在發(fā)生沖突時,maven 到底會取用哪個版本的組件呢?這就涉及到maven的版本規(guī)則

就近原則(最短路徑)

多條路徑時,選擇最短的路徑(依賴的層級小),如下,就會選用第二條路徑,最后選擇的版本為 version 0.0.2

  1. A —> C —> D —> E —> X(version 0.0.1)
  2. A —> F —> X(version 0.0.2)

聲明順序

在路徑相同的情況下,Maven會選擇最先聲明的版本。如下,就會選用第一條路徑,最后選擇的版本為 version 0.0.1

  1. A —> C —> X(version 0.0.1)
  2. A —> F —> X(version 0.0.2)

我們來看一個例子,這里maven為我們選擇了4.1.2,就是因為我們直接在pom文件里指定了版本4.1.2,所以它就只有一層,是最短路徑。

如果我們把pom里的直接引用內(nèi)容注釋掉

那么就會用新的最短路徑了,最終選取的版本為4.1.1

③ 版本選擇

一般來說,我們相信組件都具有“向下兼容”的能力,即低版本組件的功能,在高版本上應(yīng)該也能使用。所以當(dāng)出現(xiàn)組件沖突時,我們往往選擇保留目前的最高版本。

三、maven解決版本沖突的方法

1. 排除依賴

當(dāng)我們發(fā)現(xiàn)某個依賴引起了沖突,可以使用 maven 的exclude標(biāo)簽排除它。例如:

<dependencies>
    <dependency>
        <groupId>example.group</groupId>
        <artifactId>example.artifact</artifactId>
        <version>1.0</version>
        <!-- <exclusions> 元素用于排除指定的依賴 -->
        <exclusions>
            <exclusion>
                <groupId>conflict.group</groupId>
                <artifactId>conflict.artifact</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

上述代碼中,假如 example.artifact 引用了某個版本的 conflict.artifact ,與其他地方引用的conflict.artifact 發(fā)生沖突,我們就可以這樣,把example.artifact 里的 conflict.artifact 剔除掉。如果是使用插件的話,則更方便,右鍵選中組件,即可以快速進(jìn)行 exclude

2. 依賴管理

但是使用 exclusions 也有比較麻煩的地方,exclusions 只對當(dāng)前依賴有效,并不會影響其他依賴。因此,如果項目中有多個依賴引入了相同的沖突依賴,需要在每個依賴中都使用 exclusions 元素進(jìn)行排除。所以,有時候我們希望明確指定某個依賴的版本號,可以使用maven的dependencyManagement標(biāo)簽來達(dá)到目的

① 單模塊

如下 在pom文件中,我們加入dependencyManagement,并在其中指定了poi-ooxml的版本號為4.1.2(注意dependencyManagement只有管理信息的功能,并沒有真實引用poi-ooxml,所以后面的引用段落仍然要保留)

然后在引用的段落里,把版本號清除掉

此時我們再去看引用情況,就會發(fā)現(xiàn)所有的引用全部變成了 4.1.2,不再有沖突提示

② 跨模塊處理

多模塊的管理,更加需要使用 dependencyManagement 來確保各子模塊在使用相同版本的組件。所以此時需要在父POM文件中加入dependencyManagement

<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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
       <module>../child1</module>
       <module>../child2</module>
       <module>../child3</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

然后在所有子模塊的pom文件里只保留引用,不再指定版本號,如下

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
    </dependency>
</dependencies>

此時,所有子模塊凡是引用了poi-ooxml的, 就都會指定使用 4.1.2 版本,而不會再產(chǎn)生沖突了。當(dāng)然,如果某個子項目需要指定一個特殊的版本號時,只需要在自己項目的pom.xml中顯示聲明一個版本號即可,因為就近原則的關(guān)系,該模塊會使用自己指定的版本號

四、結(jié)論

在軟件開發(fā)過程中,版本沖突是一個常見的問題。我們本次就了解maven在發(fā)生版本沖突時,該如何查看沖突情況,并知道m(xù)aven選擇哪個版本是遵循就近原則、與聲明順序的。而在處理時我們可以使用排包(exclusive)法,或者顯示的使用 dependencyManagement 來指定版本號。

以上就是Maven版本沖突的原因分析和解決指南的詳細(xì)內(nèi)容,更多關(guān)于Maven版本沖突解決的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)哈希表的分離鏈接法

    Java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)哈希表的分離鏈接法

    今天給大家?guī)淼氖顷P(guān)于Java數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識,文章圍繞著Java哈希表的分離鏈接法展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Java?MyBatis本地緩存原理詳解

    Java?MyBatis本地緩存原理詳解

    這篇文章主要介紹了Java?MyBatis本地緩存原理詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • Java使用備忘錄模式實現(xiàn)過關(guān)類游戲功能詳解

    Java使用備忘錄模式實現(xiàn)過關(guān)類游戲功能詳解

    這篇文章主要介紹了Java使用備忘錄模式實現(xiàn)過關(guān)類游戲功能,結(jié)合實例形式詳細(xì)分析了java備忘錄模式的概念、原理及其在過關(guān)類游戲中的具體應(yīng)用方法,需要的朋友可以參考下
    2018-04-04
  • SpringBoot配置動態(tài)數(shù)據(jù)源的實戰(zhàn)詳解

    SpringBoot配置動態(tài)數(shù)據(jù)源的實戰(zhàn)詳解

    Spring對數(shù)據(jù)源的管理類似于策略模式,不懂策略模式也沒關(guān)系,其實就是有一個全局的鍵值對,類型是Map<String, DataSource>,當(dāng)JDBC操作數(shù)據(jù)庫之時,會根據(jù)不同的key值選擇不同的數(shù)據(jù)源,本文介紹了SpringBoot配置動態(tài)數(shù)據(jù)源的方法,需要的朋友可以參考下
    2024-08-08
  • SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)

    SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)

    這篇文章主要介紹了SpringBoot如何配置MySQL和Oracl雙數(shù)據(jù)源(Mybatis)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • SpringBoot+Netty實現(xiàn)簡單聊天室的示例代碼

    SpringBoot+Netty實現(xiàn)簡單聊天室的示例代碼

    這篇文章主要介紹了如何利用SpringBoot Netty實現(xiàn)簡單聊天室,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)SpringBoot有一定幫助,感興趣的同學(xué)可以了解一下
    2022-02-02
  • Springboot @RequestBody注解踩坑記錄

    Springboot @RequestBody注解踩坑記錄

    這篇文章主要介紹了Springboot @RequestBody注解踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java實現(xiàn)數(shù)據(jù)庫連接池的方法

    Java實現(xiàn)數(shù)據(jù)庫連接池的方法

    這篇文章主要介紹了Java實現(xiàn)數(shù)據(jù)庫連接池的方法,涉及java數(shù)據(jù)庫連接池的創(chuàng)建、連接、刷新、關(guān)閉及狀態(tài)獲取的常用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別)

    Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別)

    這篇文章主要介紹了Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別) ,需要的朋友可以參考下
    2017-02-02
  • Java中的MapStruct的使用方法代碼實例

    Java中的MapStruct的使用方法代碼實例

    這篇文章主要介紹了Java中的MapStruct的使用方法代碼實例,mapstruct是一種實體類映射框架,能夠通過Java注解將一個實體類的屬性安全地賦值給另一個實體類,有了mapstruct,只需要定義一個映射器接口,聲明需要映射的方法,需要的朋友可以參考下
    2023-10-10

最新評論