日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
好機會,我要幫女同事解決Maven沖突問題

任何一個故事起因最重要

任何一個職業(yè),女生都有絕對的優(yōu)勢。更別提 IT 行業(yè)了,在部門中要是有女程序猿那肯定是香餑餑,備受呵護呀。

之前有一次,一位剛來的妹子遇到問題了,畫風(fēng)頓時就變成上面的圖片了,群起而圍之,但是最后的結(jié)果并不理想,還是得我出馬(此處有點小吹牛)。

妹子遇到的是 Jar 包沖突的問題,錯誤信息是 Caused by: java.lang.ClassNotFoundException,看錯誤要么就是缺少某個 Jar 包,要么就是沖突了。

其實在工作中經(jīng)常會遇到這種沖突的問題,比如:Caused by:java.lang.NoSuchMethodError 這個異常信息也是沖突導(dǎo)致的,想要解決沖突問題就必須得知道哪里沖突了(好像是廢話)。

大部分都是用 Maven 來管理依賴的 Jar,今天這篇文章主要是講解如何解決 Maven 帶來的依賴沖突問題。

Maven 回顧

Maven 自述

Maven 是用于構(gòu)建和管理 Java 項目的工具。對于 Java 方向的來說,Maven 幾乎都要接觸和使用。當(dāng)然也有其他的工具來代替 Maven,比如 Ant 和 Gradle。

之前有接觸過 Grails 構(gòu)建的 Java Web 項目,就是用 Gradle 來做依賴管理的。至于 Ant 也在剛工作的時候在一些老項目中有見到過,后面幾乎沒見過了。

Maven 文檔地址:https://maven.apache.org[1]

使用 Maven 可以讓我們快速構(gòu)建一個新的項目,并且很方便的可以集成和管理多個三方的框架。當(dāng)我們需要某個框架時可以去搜索一下這個框架的信息,然后配置到你的項目中即可。

搜索地址:https://mvnrepository.com[2]

比如我們想要使用 Spring Boot,除了在 Spring 的文檔中獲取依賴的版本,也可以自己去搜索,選擇對應(yīng)的版本,如下圖:

可以看到默認(rèn)就是 Maven 的依賴方式,只需要將 dependency 整段內(nèi)容復(fù)制到項目的 pom.xml 文件中即可。右側(cè)還有很多其他的依賴方式,比如 Gradle 等。

Maven 依賴傳遞

今天主要講下如何去解決 Maven 做依賴管理的時候 Jar 包沖突的問題,在解決之前先來了解下基本的知識。

上圖展示了 Maven 的依賴傳遞性,首先是項目 B 中依賴了 Spring 和 Guava 兩個框架。然后項目 A 又依賴了項目 B,所以項目 A 也會依賴 Spring 和 Guava 兩個框架。

依賴傳遞 Jar 包選擇邏輯依賴性傳遞會導(dǎo)致項目中依賴很多其他版本的 Jar,這種情況下怎么進行 Jar 包的選擇呢?

有兩個規(guī)則:

  • 不同距離,距離近優(yōu)先
  • 相同距離,前者優(yōu)先

如下圖所示,項目依賴了項目 A 和項目 B,A 和 B 分別依賴了 Guava,但是從依賴層次來看,項目 B 的層次更淺,故 Guava18.0 會被優(yōu)先選擇。

當(dāng)距離相同的時候,就會優(yōu)先選擇定義在前面的,如下圖所示,項目 A 和項目 B 都分別依賴了 Guava15.0 和 Guava18.0 的版本,但是項目 A 的順序在項目 B 的前面,所以會優(yōu)先選擇 Guava15.0 版本。

通過依賴傳遞性經(jīng)常會導(dǎo)致 Jar 包沖突的問題,比如下圖的項目 A 本身依賴了 Guava15.0,然后又依賴了項目 B,項目 B 中依賴了 Guava18.0,這樣項目 A 就會同時依賴 Guava15.0 和 Guava18.0。

如果剛好用到了高版本不兼容低版本的方法和類時,就會出現(xiàn)選擇錯誤,因為 Maven 會根據(jù)依賴樹的深淺來選型淺的依賴,也就是 15.0。

沖突案例

下面就是一個典型的 Jar 包沖突問題,當(dāng)一個 Jar 有多個版本的時候,就會出現(xiàn)沖突。

錯誤信息可以看到 com.google.common.collect.FluentIterable.concat 這個方法找不到,目前是從 guava-18.0.jar 中加載的,這種問題我們該怎么解決呢?

 
 
 
 
  1. Description: 
  2. 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: 
  3.     jar:file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar!/com/google/common/collect/FluentIterable.class 
  4. It was loaded from the following location: 
  5.     file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar 
  6.  
  7. Action: 
  8. Correct the classpath of your application so that it contains a single, compatible version of com.google.common.collect.FluentIterable 

解決思路之懸絲診脈

找出沖突的 Jar,看看當(dāng)前項目中依賴了哪幾個版本。

Eclipse

在 Eclipse 中可以雙擊 pom 文件,進入 Dependency 視圖,輸入你要搜索的 jar 名稱進行搜索,就可以看出當(dāng)前項目中哪些框架依賴了你搜索的 jar,什么版本都能知道。

Idea

Idea 中可以安裝 maven helper 插件來查看相關(guān)依賴信息,默認(rèn)選中 Conflicts 會展示當(dāng)前項目存在沖突的依賴,當(dāng)然我們也可以直接查看樹形的依賴關(guān)系去分析沖突。

Maven 命令

不用不借助于開發(fā)工具的插件,我們可以直接用 Maven 命令來查看當(dāng)前項目的依賴關(guān)系,命令行進入到你要分析的項目目錄下,執(zhí)行下面的命令將分析結(jié)果保存到文件中:

 
 
 
 
  1. mvn dependency:tree > tree.log 

執(zhí)行完之后依賴的信息結(jié)構(gòu)如下:

搜索了下 guava,發(fā)現(xiàn)在 smjdbctemplate 中依賴了 18.0 版本,這個框架是我自己基于 jdbctemplate 封裝的一個框架。

解決思路之察言觀色其實很明顯,錯誤信息已經(jīng)告訴我們 18.0 中找不到 concat 方法,所以 18.0 肯定是不能用的,通過前面的分析,找到了直接依賴 guava.18.0.jar 的是 smjdbctemplate,解決辦法就是將 smjdbctemplate 中的 guava 排除掉。

 
 
 
 
  1.  
  2.   com.github.yinjihuan 
  3.   smjdbctemplate 
  4.   1.1 
  5.    
  6.      
  7.       com.google.guava 
  8.       guava 
  9.      
  10.    
  11.  

還有就是根據(jù)依賴樹的深淺度來判斷當(dāng)前項目依賴的是哪個版本,如下圖:

18.0 是最淺的,肯定是依賴它,其實在 Eclipse 里面直接查看 Maven Dependencies 就可以指定當(dāng)前項目依賴哪些框架和版本信息,如下圖:

當(dāng)我們排除掉 18.0 后再來看依賴的版本是 20.0,如下圖:

根據(jù)依賴樹的深淺度,20.0 和 19.0 都是一樣的層級,但是 20.0 在 19.0 前面,所以優(yōu)先選擇 20.0 版本。

再來看項目中的 pom 文件,發(fā)現(xiàn) swagger 的聲明順序在 apollo 的前面。

如果我們把順序調(diào)整一下,那么就會依賴 19.0 的版本。

總結(jié)

通過我仔細(xì)耐心的講解,妹子終于自己解決了遇到的問題,后面的事你們就猜去吧。

這種問題其實無法避免,當(dāng)你依賴的三方框架越多的時候,沖突的可能性就越大。碰到問題的時候沉下心來仔細(xì)分析,借助于工具幫助你排查問題。

當(dāng)然我們在自己項目中去依賴三方的框架,也是要注意版本的問題,特別是對于多模塊的項目,每個子模塊都去依賴不同的版本,這樣很容易出問題,一般建議在父 pom 中 dependencyManagement 來統(tǒng)一管理版本,子模塊直接統(tǒng)一使用父 pom 中定義好的版本。

還有就是可以使用 optional 來設(shè)置可選依賴,比如說你要封裝一個通用的模塊 Common,這個模塊中有很多通用的功能,項目 A 依賴只需要使用功能 A,項目 B 依賴只需要使用功能 B。每個功能都依賴了三方的 Jar,這個時候如果你不做任何處理,只要依賴了你這個通用的模塊 Common,那么也就會間接依賴這兩個功能的第三方 Jar。這個時候可以通過設(shè)置 optional=true 來解決這個問題,我依賴了你的通用模塊 Common,如果我要使用 A 功能,那么我必須顯示依賴 A 功能需要的三方依賴才可以。


網(wǎng)站題目:好機會,我要幫女同事解決Maven沖突問題
文章URL:http://www.5511xx.com/article/cohcsdg.html