我有一个 Maven
java web 应用程序 (.WAR) 项目,其中包含多个库,包括 Wicket
库(但我不认为问题出在 wicket 本身,而是使用 maven)。
这就是问题所在:即使我只包含 Wicket 6.20.0
,生成的 .WAR 包含 Wicket 库的两个副本:6.20.0
和 6.18.0
,如您在此屏幕截图中所见:
考虑到一些相互冲突的导入,我使用以下方法打印了依赖关系树:
mvn dependency:tree
commnad...但是在依赖关系树中没有提到 Wicket 6.18.0!我还使用 Eclipse 的“依赖关系层次结构” View 进行了仔细检查,我可以确认没有任何导入痕迹。
我什至使用 Eclipse 在整个工作区中搜索字符串“6.18.0”,但无处可寻!
我如何找出导致包含该库的重复版本的原因?
最佳答案
Maven 不以这种方式工作。
多个具有相同 artifactId 和 groupId 但具有不同版本的依赖项的解析将导致单个依赖项(使用的版本是不确定的)。
在 WAR 的同一个 lib 文件夹中存在两个具有相同 artifactId 和 groupId 但具有两个不同版本的 Artifact 可能与以下之一有关:
您不执行
mvn clean package
,而只执行mvn package
。您使用的是有漏洞的 Maven war 插件版本。尝试更新它以检查。
您有一个 Maven 插件,它在构建组件期间将 Wicket jars 6.18.0 复制到目标文件夹的
<WEB-INF/lib
文件夹中。您正在构建的 Maven WAR 项目具有 WAR 类型的 Artifact 作为依赖项。在这种情况下,WAR 依赖项的依赖项是这样的 overlaid在您正在构建的 WAR 项目中。
一个有趣的 Maven 问题,关于由于 WAR 依赖性而导致的重复 JAR:
JARs with different versions can be in WEB-INF/lib with war as dependencies
Your answer和你的 comment表示实际上您的构建中有 WAR 依赖项。
不幸的是,并没有真正好的和长期有效的解决方案来绕过这个限制。
正如我在评论中所说,使用 Maven war 插件的 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-plugin
的 overlay
元素的功能通常更好,因为它专注于应用于 war 依赖项的覆盖。它及早解决了问题。
因此,您可以定义从 WAR 依赖项中排除任何 wicket 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 Artifact 的依赖。
由于 poms 和项目重构是可能的,因此引入两个 WAR 所依赖的公共(public) JAR 依赖项并且仅包含两个 WAR 的公共(public)源和资源使事情变得更简单。
关于java - 为什么 Maven 包含相同依赖项的多个版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44631683/