這篇文章主要介紹“怎么解決Maven沖突問題”,在日常操作中,相信很多人在怎么解決Maven沖突問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么解決Maven沖突問題”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)公司云計(jì)算的互聯(lián)網(wǎng)服務(wù)提供商,擁有超過13年的服務(wù)器租用、成都移動(dòng)機(jī)房、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn),已先后獲得國家工業(yè)和信息化部頒發(fā)的互聯(lián)網(wǎng)數(shù)據(jù)中心業(yè)務(wù)許可證。專業(yè)提供云主機(jī)、虛擬主機(jī)、空間域名、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
Maven 回顧
Maven 自述
Maven 是用于構(gòu)建和管理 Java 項(xiàng)目的工具。對于 Java 方向的來說,Maven 幾乎都要接觸和使用。當(dāng)然也有其他的工具來代替 Maven,比如 Ant 和 Gradle。
之前有接觸過 Grails 構(gòu)建的 Java Web 項(xiàng)目,就是用 Gradle 來做依賴管理的。至于 Ant 也在剛工作的時(shí)候在一些老項(xiàng)目中有見到過,后面幾乎沒見過了。
使用 Maven 可以讓我們快速構(gòu)建一個(gè)新的項(xiàng)目,并且很方便的可以集成和管理多個(gè)三方的框架。當(dāng)我們需要某個(gè)框架時(shí)可以去搜索一下這個(gè)框架的信息,然后配置到你的項(xiàng)目中即可。
比如我們想要使用 Spring Boot,除了在 Spring 的文檔中獲取依賴的版本,也可以自己去搜索,選擇對應(yīng)的版本,如下圖:
可以看到默認(rèn)就是 Maven 的依賴方式,只需要將 dependency 整段內(nèi)容復(fù)制到項(xiàng)目的 pom.xml 文件中即可。右側(cè)還有很多其他的依賴方式,比如 Gradle 等。
Maven 依賴傳遞
今天主要講下如何去解決 Maven 做依賴管理的時(shí)候 Jar 包沖突的問題,在解決之前先來了解下基本的知識。
上圖展示了 Maven 的依賴傳遞性,首先是項(xiàng)目 B 中依賴了 Spring 和 Guava 兩個(gè)框架。然后項(xiàng)目 A 又依賴了項(xiàng)目 B,所以項(xiàng)目 A 也會(huì)依賴 Spring 和 Guava 兩個(gè)框架。
依賴傳遞 Jar 包選擇邏輯依賴性傳遞會(huì)導(dǎo)致項(xiàng)目中依賴很多其他版本的 Jar,這種情況下怎么進(jìn)行 Jar 包的選擇呢?
有兩個(gè)規(guī)則:
不同距離,距離近優(yōu)先
相同距離,前者優(yōu)先
如下圖所示,項(xiàng)目依賴了項(xiàng)目 A 和項(xiàng)目 B,A 和 B 分別依賴了 Guava,但是從依賴層次來看,項(xiàng)目 B 的層次更淺,故 Guava18.0 會(huì)被優(yōu)先選擇。
當(dāng)距離相同的時(shí)候,就會(huì)優(yōu)先選擇定義在前面的,如下圖所示,項(xiàng)目 A 和項(xiàng)目 B 都分別依賴了 Guava15.0 和 Guava18.0 的版本,但是項(xiàng)目 A 的順序在項(xiàng)目 B 的前面,所以會(huì)優(yōu)先選擇 Guava15.0 版本。
通過依賴傳遞性經(jīng)常會(huì)導(dǎo)致 Jar 包沖突的問題,比如下圖的項(xiàng)目 A 本身依賴了 Guava15.0,然后又依賴了項(xiàng)目 B,項(xiàng)目 B 中依賴了 Guava18.0,這樣項(xiàng)目 A 就會(huì)同時(shí)依賴 Guava15.0 和 Guava18.0。
如果剛好用到了高版本不兼容低版本的方法和類時(shí),就會(huì)出現(xiàn)選擇錯(cuò)誤,因?yàn)?Maven 會(huì)根據(jù)依賴樹的深淺來選型淺的依賴,也就是 15.0。
沖突案例
下面就是一個(gè)典型的 Jar 包沖突問題,當(dāng)一個(gè) Jar 有多個(gè)版本的時(shí)候,就會(huì)出現(xiàn)沖突。
錯(cuò)誤信息可以看到 com.google.common.collect.FluentIterable.concat 這個(gè)方法找不到,目前是從 guava-18.0.jar 中加載的,這種問題我們該怎么解決呢?
Description: An attempt was made to call the method com.google.common.collect.FluentIterable.concat(Ljava/lang/Iterable;Ljava/lang/Iterable;)Lcom/google/common/collect/FluentIterable; but it does not exist. Its class, com.google.common.collect.FluentIterable, is available from the following locations: jar:file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar!/com/google/common/collect/FluentIterable.class It was loaded from the following location: file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar Action: Correct the classpath of your application so that it contains a single, compatible version of com.google.common.collect.FluentIterable
解決思路之懸絲診脈
找出沖突的 Jar,看看當(dāng)前項(xiàng)目中依賴了哪幾個(gè)版本。
Eclipse
在 Eclipse 中可以雙擊 pom 文件,進(jìn)入 Dependency 視圖,輸入你要搜索的 jar 名稱進(jìn)行搜索,就可以看出當(dāng)前項(xiàng)目中哪些框架依賴了你搜索的 jar,什么版本都能知道。
Idea
Idea 中可以安裝 maven helper 插件來查看相關(guān)依賴信息,默認(rèn)選中 Conflicts 會(huì)展示當(dāng)前項(xiàng)目存在沖突的依賴,當(dāng)然我們也可以直接查看樹形的依賴關(guān)系去分析沖突。
Maven 命令
不用不借助于開發(fā)工具的插件,我們可以直接用 Maven 命令來查看當(dāng)前項(xiàng)目的依賴關(guān)系,命令行進(jìn)入到你要分析的項(xiàng)目目錄下,執(zhí)行下面的命令將分析結(jié)果保存到文件中:
mvn dependency:tree > tree.log
執(zhí)行完之后依賴的信息結(jié)構(gòu)如下:
搜索了下 guava,發(fā)現(xiàn)在 smjdbctemplate 中依賴了 18.0 版本,這個(gè)框架是我自己基于 jdbctemplate 封裝的一個(gè)框架。
解決思路之察言觀色其實(shí)很明顯,錯(cuò)誤信息已經(jīng)告訴我們 18.0 中找不到 concat 方法,所以 18.0 肯定是不能用的,通過前面的分析,找到了直接依賴 guava.18.0.jar 的是 smjdbctemplate,解決辦法就是將 smjdbctemplate 中的 guava 排除掉。
com.github.yinjihuan smjdbctemplate 1.1 com.google.guava guava
還有就是根據(jù)依賴樹的深淺度來判斷當(dāng)前項(xiàng)目依賴的是哪個(gè)版本,如下圖:
18.0 是最淺的,肯定是依賴它,其實(shí)在 Eclipse 里面直接查看 Maven Dependencies 就可以指定當(dāng)前項(xiàng)目依賴哪些框架和版本信息,如下圖:
當(dāng)我們排除掉 18.0 后再來看依賴的版本是 20.0,如下圖:
根據(jù)依賴樹的深淺度,20.0 和 19.0 都是一樣的層級,但是 20.0 在 19.0 前面,所以優(yōu)先選擇 20.0 版本。
再來看項(xiàng)目中的 pom 文件,發(fā)現(xiàn) swagger 的聲明順序在 apollo 的前面。
如果我們把順序調(diào)整一下,那么就會(huì)依賴 19.0 的版本。
到此,關(guān)于“怎么解決Maven沖突問題”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!