Maven - 相同依赖项的多个版本

Posted

技术标签:

【中文标题】Maven - 相同依赖项的多个版本【英文标题】:Maven - Multiple version of same dependency 【发布时间】:2016-05-24 17:17:06 【问题描述】:

我有一个 Web 应用程序,其中的依赖项拉入两个名为:

    javassist-3.9.0.GA.jar javassist-3.20.0-GA.jar

当我将 WAR 打包在 WEB-INF/lib 目录中时,我的问题是应用程序正在运行以及为什么我不会遇到任何问题,因为显然我在两个 jar 和那里都有相同的类应该是问题吧?

【问题讨论】:

如果您的war 中确实有相同工件的两个版本,那么您做错了...使用默认的 Maven 和 maven-war-plugin 在您的库中永远不应该有重复的 jar 文件文件夹......(听起来你手动做的事情应该让 maven 去做)...... 谢谢,如果我使用'package'目标来构建war文件,是不是使用maven war插件来做到这一点?如果没有,maven-war-plugin 对“打包”目标有什么不同? package 不是目标,而是生命周期如果您在 pom 文件中设置了正确的<packaging>war</packaging>,这应该可以开箱即用...最好是查看 pom 文件你正在使用.. How to include two different versions of the same dependency?的可能重复 【参考方案1】:

对于 Java,您提供多少版本的类并不重要。默认的类加载器只会选择它可以找到的类路径中的第一个。

由于您可以无错误地运行应用程序,这意味着以下情况之一:

如果 javassist-3.9.0.GA.jar 位于类路径的第一个位置:您的应用程序不依赖于 javassist-3.20.0-GA.jar 中的新 API 或错误修复,您也没有使用此 API库在这些版本之间发生了变化(库不应该在次要版本之间这样做)

如果 javassist-3.20.0-GA.jar 在类路径中首先出现:该库向后兼容

我建议:

如果这些依赖项是应用程序不同部分的直接依赖项,请确保您在任何地方都使用相同的版本。最好的方法是在父 POM 的 dependencyManagement 部分中修复版本,然后在依赖部分中省略 version 属性。 如果这些依赖项是传递依赖项,则排除您不想使用的依赖项,以确保您在最终应用程序中只有一个版本的库。还可以考虑为仍然使用旧版本的项目提交问题,并要求他们升级依赖的版本。 如果您需要使用同一个库的两个不兼容版本,它们具有相同的包名和类名,请考虑使用模块系统,例如 OSGi,它在一定程度上支持运行同一库的不同版本。

【讨论】:

我理解这一点,这是一种合乎逻辑的解释,但这并不意味着应用程序真的处于危险之中,因为如果我有一个依赖于 3.9.0.GA 中的类的依赖项并且该类在 3.20.2-GA 中更新,并且 3.20.0-GA 是第一个并且在类路径中并且该依赖项需要 3.9.0.GA 中该特定类的版本? 另外一个问题是如何找出哪个是类路径中的第一个? 你不知道哪个是第一个......这是你的应用程序中的一个大问题......你应该解决这个问题......否则你的应用程序可以运行,有时它会失败。 .. @Puce,感谢您的帮助。我能够摆脱手动放入 POM 的依赖,这让我依赖于依赖 javaassist-3.20 的依赖,但现在一切都很好!谢谢 @Tefa 如果您在某个地方直接依赖于 javaassist 之类的库,最好还是这样声明它。只需确保版本与 javaassist 的其他传递依赖相匹配。【参考方案2】:

回答“有什么建议可以解决吗?”看看Resolving conflicts using the dependency tree。使用命令mvn dependency:tree,您将能够知道任何依赖项的来源。当您知道哪些工件依赖于 javassist 时,您可以添加一个排除条目以避免其中一个 javassist 版本。

【讨论】:

以上是关于Maven - 相同依赖项的多个版本的主要内容,如果未能解决你的问题,请参考以下文章

是否有一个 Maven 插件可以验证传递依赖项的冲突版本?

如何找到特定版本的maven依赖项的最低JDK版本?

使用 Maven 依赖项的 Spark 版本不匹配

Maven 与 Jenkins - 更新依赖项的父 pom 版本

Java / Maven如何使用使用项目中已使用的另一个依赖项的旧版本的依赖项

在 maven pom.xml 中更改传递依赖项的版本