小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Maven提高篇系列之五

 feimishiwo 2014-12-30

本系列上一篇文章中,我們講到了如何使用Profile,在本文中,我們將講到如何處理Maven的依賴沖突。

 

不知道你在使用Maven時是否遇到過諸如"NoSuchMethodError"或"ClassNotFoundException"之類的問題,甚至發(fā)生這些問題的Java類你沒都沒有聽說過。要搞清楚這里面的緣由,我們得學習Maven對依賴沖突的處理機制。

 

Maven采用“最近獲勝策略(nearest wins strategy)”的方式處理依賴沖突,即如果一個項目最終依賴于相同artifact的多個版本,在依賴樹中離項目最近的那個版本將被使用。讓我們來看看一個實際的例子。

 

請下載本文的github源代碼:https://github.com/davenkin/maven-dependency-conflict-demo

 

我們有一個web應用resolve-web,該工程依賴于project-A和project-B,project-A依賴于project-common的1.0版本并調(diào)用其中的sayHello()方法。project-B依賴于project-C,而project-C又進一步依賴于project-common的2.0版本并調(diào)用其中的sayGoodBye()方法。project-common的1.0和2.0版本是不同的,1.0中之包含sayHello()方法,而2.0中包含了sayHello()和sayGoodBye()兩個方法。整個項目的依賴關系如下圖:

 



根據(jù)Maven的transitive依賴機制,resolve-web將同時依賴于project-common的1.0和2.0版本,這就造成了依賴沖突。而根據(jù)最近獲勝策略,Maven將選擇project-common的1.0版本作為最終的依賴。這和Gradle不同,Gradle在默認情況下將選擇最新的版本作為獲勝版本。而對于Maven,由于proejct-common的1.0版本比2.0版本在依賴樹中離resolve-web更近,故1.0版本獲勝。在resolve-web中執(zhí)行"mvn dependency:tree -Dverbose"可以看到resolve-web的依賴關系:


[INFO] resolve-web:resolve-web:war:1.0-SNAPSHOT

[INFO] +- junit:junit:jar:3.8.1:test

[INFO] +- project-B:project-B:jar:1.0:compile

[INFO] |  \- project-C:project-C:jar:1.0:compile

[INFO] |     \- (project-common:project-commmon:jar:2.0:compile - omitted for conflict with 1.0)

[INFO] +- project-A:project-A:jar:1.0:compile

[INFO] |  \- project-common:project-commmon:jar:1.0:compile

[INFO] \- javax.servlet:servlet-api:jar:2.4:provided


由上可知,project-common:project-commmon:jar:2.0被忽略掉了。此時在resolve-web的war包中將只包含project-common的1.0版本,于是問題來了。由于project-common的1.0版本中不包含sayGoodBye()方法,而該方法正是project-C所需要的,所以運行時將出現(xiàn)“NoSuchMethodError”。(請根據(jù)本文github工程中的README.md中的步驟重現(xiàn)該錯誤信息。)


解決辦法

對于這種有依賴沖突所導致的問題,我們有兩種解決方法。


方法1:顯式加入對project-common 2.0版本的依賴。先前的2.0版本不是離resolve-web遠了點嗎,那我們就直接將它作為resolve-web的依賴,這不就比1.0版本離resolve-web還近嗎?在resove-web的pom.xml文件中直接加上對project-common 2.0 的依賴:


     <dependency>

     <groupId>project-common</groupId>

     <artifactId>project-commmon</artifactId>

     <version>2.0</version>

   </dependency>


方法2:resolve-web對project-A的dependency聲明中,將project-common排除掉。在resolve-web的pom.xml文件中修改對project-A的dependency聲明:


       <dependency>

           <groupId>project-A</groupId>

           <artifactId>project-A</artifactId>

           <version>1.0</version>

           <exclusions>

               <exclusion>

                   <groupId>project-common</groupId>

                   <artifactId>project-commmon</artifactId>

               </exclusion>

           </exclusions>

       </dependency>


此時再在resolve-web中執(zhí)行"mvn dependency:tree -Dverbose",結果如下:


......

[INFO] resolve-web:resolve-web:war:1.0-SNAPSHOT

[INFO] +- junit:junit:jar:3.8.1:test

[INFO] +- project-B:project-B:jar:1.0:compile

[INFO] |  \- project-C:project-C:jar:1.0:compile

[INFO] |     \- project-common:project-commmon:jar:2.0:compile

[INFO] +- project-A:project-A:jar:1.0:compile

[INFO] \- javax.servlet:servlet-api:jar:2.4:provided

......


此時的依賴樹中已經(jīng)不包含project-common的1.0版本了。


另外,我們還可以在project-A中將對project-common的依賴聲明為optional,optional即表示非transitive,此時當在resolve-web中引用project-A時,Maven并不會將project-common作為transitive依賴自動加入,除非有別的項目(比如project-B)聲明了對project-common的transitive依賴或者我們在resolve-web中顯式聲明對project-common的依賴(方法一)。


下一篇文章中,我們將講到如何編寫自己的Plugin。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多