2017-06-19 74 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将是过分的。 –

相关问题