2017-06-19 119 views
5

我有一個Maven java web應用程序(.WAR)項目,其中包括幾個庫,其中包括Wicket庫(但我不認爲問題是wicket本身,而是與maven)。爲什麼Maven包含相同依賴的多個版本?

這裏的問題:即使壽我只包括Wicket 6.20.0,所產生的.WAR包含兩個副本檢票庫6.20.06.18.0,你可以在這個截圖中看到:

enter image description here

思考一些衝突的進口我打印依賴關係樹使用:

mvn dependency:tree 

commnad ...但在依賴關係樹中沒有提到Wicket 6.18.0!我還使用Eclipse的「依賴關係層次結構」視圖進行了雙重檢查,我可以確認沒有該導入的痕跡。

我甚至在Eclipse的整個工作區中搜索字符串「6.18.0」,但無處可查!

我怎樣才能找出是什麼導致包含該庫的重複版本?

+3

能否請您發表您的pom? – BackSlash

回答

5

Maven不以這種方式工作。
使用相同artifactId和groupId但使用不同版本的多個依賴項的解決方案將導致單個依賴項(所使用的版本不是確定性的)。

  • 你不執行mvn clean package

    兩個產物具有相同的artifactId和的groupId但是有兩個不同的版本,在戰爭的同一個lib文件夾的存在可能與其中的一個但只有mvn package

  • 您使用Maven war插件的bug版本。嘗試更新它來檢查。

  • 在構建組件的過程中,您有一個Maven插件,用於在目標文件夾的WEB-INF/lib文件夾中複製Wicket jars 6.18.0。

  • 您正在構建的maven WAR項目具有WAR類型的工件作爲依賴關係。在這種情況下,WAR依賴關係的依賴關係在您正在構建的WAR項目中是如此overlaid


一個有趣的Maven的問題有關,因爲WAR依賴複製JAR:

JARs with different versions can be in WEB-INF/lib with war as dependencies


Your answer和你comment表示,其實你必須在生成一個WAR依賴。
不幸的是,沒有一個真正的長期有效的解決方案來繞過這個限制。

正如我在評論說,使用Maven的戰爭插件的packagingExcludes屬性是一個有效的解決方法的實際問題:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-war-plugin</artifactId> 
    <version>2.4</version> 
    <configuration> 
     <!-- ... --> 
     <packagingExcludes>WEB-INF/lib/wicket-*-6.18.0.jar</packagingExcludes> 
    </configuration> 
</plugin> 

但要注意,使用將做您的構建通過時間不太可靠。 當您更新WAR依賴版本的那一天以及在其新版本中,它再次提取不同版本的wicket時,仍然有在構建的WAR中有兩個不同版本的重複jar的風險。

使用the overlay功能通過指定maven-war-pluginoverlay元素通常會更好,因爲它專注於應用於戰爭依賴關係的疊加層。它可以及早解決問題。 其結果是,你可以定義從戰爭依賴排除任何檢票的JAR:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <version>2.4</version> 
    <artifactId>maven-war-plugin</artifactId> 
    <configuration>  
     <overlays> 
      <overlay> 
       <groupId>com.whatever.youlike</groupId> 
       <artifactId>myArtifact</artifactId> 
       <excludes> 
        <exclude>WEB-INF/lib/wicket-*.jar</exclude>     
       </excludes> 
      </overlay> 
     </overlays> 
    </configuration> 
</plugin> 

這種方式是更好的,但是這仍然是一個解決辦法。
依賴關係WAR被更新的日子,並且它拉取在實際構建中聲明但具有不同版本的新依賴項(Wicket除外),那麼您可能會完成相同類型的問題。

我認爲聲明WAR文物的依賴關係應該只做,因爲我們沒有選擇。
由於poms和項目重構是可能的,引入兩個WAR所依賴的通用JAR依賴關係,並且只包含兩個WAR的常見源和資源,這使得事情變得更簡單。

+0

+1,因爲您的第一個要點指出我的方向正確,請參閱下面的答案以獲取詳細信息。基本上,它是一個依賴項,但類型爲「WAR」的依賴項(我認爲它們被稱爲覆蓋?)。這些不會顯示在構建樹/ dep中。顯然是層次結構。 –

+0

由於您注意到的原因,強烈建議不要在WAR中打包一個WAR類型依賴項。它不會在'dependency:tree'中顯示,因爲它並不構成依賴關係解析的一部分。它以lib/WAR構建組件的lib/WAR依賴項中包含的「原始」方式複製jar。對不起,我不知道確切的名字:怪物卡車副本也許? ;) – davidxxx

+1

編輯後我接受了你的答案,因爲我不喜歡接受我自己的答案:D任何對特定細節感興趣的人,請參閱我自己的答案:https://stackoverflow.com/a/44632079/300741 –

0

因爲其他庫可以使用相同的庫,但版本不同,或者您嘗試了不同的版本,並沒有使mvn clean

+0

我在每次構建時都在進行清理。問題是一個不同的問題,請參閱我自己的答案瞭解詳情。無論如何感謝建議。 –

1

使用clean install和雙依賴性可能會消失。

+0

我總是乾淨;)問題是一個不同的問題,請參閱下面我自己的答案。無論如何,感謝您的幫助。 –

0

命令mvn dependency:tree告訴你正確的信息 - 你在這裏看到的是一個eclipse/build問題。

清除項目中的所有目標和構建區域。如果需要,請從源代碼管理檢查到新文件夾。

或者,您可以在IntelliJ IDEA中構建您的項目,並查看您是否獲得了正確的依賴關係(很可能您會)。

2

那麼,我想出來,而徘徊。

我有型「戰爭」的項目的依賴:

<dependency> 
    <groupId>com.whatever.youlike</groupId> 
    <artifactId>myArtifact</artifactId> 
    <version>1.0.7-SNAPSHOT</version> 
    <type>war</type> 
</dependency> 

顯然,(我沒有意識到這一點,這裏是我的錯),這些類型的依賴性將通過複製自身包含在類路徑所有庫都放在主WAR/libs文件夾中,但這些文件不會在依賴關係樹/依賴關係層次結構中顯示應用程序。

我解決了通過配置在WAR插件的明確排除:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-war-plugin</artifactId> 
    <version>2.4</version> 
    <configuration> 
     <!-- ... --> 
     <packagingExcludes>WEB-INF/lib/wicket-*-6.18.0.jar</packagingExcludes> 
    </configuration> 
</plugin> 
+1

有效的解決方法。 +1但它有一些限制。在WAR依賴性發生變化的那一天,您仍然有可能在構建的WAR中出現具有兩個不同版本的jar。我認爲pom重構將是一個長期更好的解決方案。 – davidxxx

+0

+1,你是對的,這不是一個優雅的解決方案。我們將調整這兩個項目以在下一個版本中使用相同的版本。目前來看,這個快速解決方案完成了這項工作 –

+0

進一步澄清:我通過WAR依賴包括它,因爲包含的項目不在我們的JAR格式的倉庫中。我只需要一個類,重構整個項目以將單個類提取到單獨的共享JAR將是過分的。 –

相關問題