当前位置: 首页 > 知识库问答 >
问题:

为什么在Maven中不可能包含相同依赖项的多个版本?

马边浩
2023-03-14

根据Maven文档,将使用依赖项中介来决定使用哪个依赖项:

因此,假设我们首先声明依赖项A,那么X1.0版将在我们的应用程序中使用。这意味着依赖项b将在运行时使用x1.0版,而as是根据x2.0版编译的。如果b使用的是2.0版的一些特性,那么我们将会得到一个运行时错误(nosuchmethoderror,classNotFoundexception等),这是不好的。

因此要“修复”这一点,我们可以从依赖项A中排除依赖项X,从而使用X2.0版本。但是哦不!X2.0版不向后兼容,因此我们最终会从A得到运行时错误。

据我所知,Maven没有办法正确地解决这个问题。您所能做的就是希望得到其中一个库的源代码,并自行修复它。那是正确的吗?

为什么不能将x的两个版本打包到我的应用程序中,这样A使用x版本1.0,B使用x版本2.0,而我的应用程序中可用的x版本是Maven通过依赖关系中介选择的。这是Java的限制,还是Maven的限制?这种情况普遍吗?还有其他可能的解决方案吗?是否所有库都应保证向后兼容以避免此问题?

共有1个答案

夏侯宏旷
2023-03-14

不能将两个同名的类加载到一个类加载器中。如果Maven允许您拥有同一工件的多个版本,那么无疑会出现这种情况。所以这是Maven能够解决的Java问题。

我不确定有什么万全之策能解决这个问题。如果您控制了AB,则可以使用着色将X的用法重命名为不会冲突的用法,如maven-shade-plugin的用途,以及为什么要重定位java包?中所述。

通常,我们必须希望库之间保持向下兼容,并对生成的应用程序进行良好的测试,以确保没有问题。显然,您希望将Maven配置为包含x-2.0而不是x-1.0,可以先列出b或在POM中显式列出x

一句警告:大多数版本命名方案允许在1.x.x和2.x.x之间中断更改,因此您可能会遇到问题。一些Maven项目(如Apache Commons Lang)在更改主版本时会使用新的工件ID和包结构,以避免这些冲突。

 类似资料:
  • 问题内容: 我正在为Java中的ERP系统进行定制。在我的定制中,我想使用Apache POI 3.10.1。因此,我集成了jars poi-3.10.1-20140818.jar和poi-ooxml-3.10.1-20140818.jar。 但是,这些jar包含几个类,这些类已经包含在ERP系统的核心代码中,但是有所不同。 如果核心ERP类覆盖POI类,则定制将引发运行时异常。如果POI类覆盖核

  • 问题内容: 我刚刚遇到了一个案例,即我的Maven项目有两个直接依赖项,其中有两个不同版本的特定传递性依赖项。 在我的特殊情况下,我直接依赖以下内容: 和 这两个依赖项都对com.sun.jersey:jersey- core具有(较深)的传递性依赖关系,但是每个都有不同的版本。Maven并没有失败,甚至没有警告(或者,如果没有,我从来没有看到过!)正在发生这样的事情……因此,直到调试了球衣版本时

  • 我正在尝试用maven-shade插件2.1构建一个uber-jar。我希望它包括我的jar和依赖jar中的所有类。但我发现它不包括依赖jar中的类。我可能做错了什么?以下是我在pom.xml中对maven-shade插件的用法。可能是因为finalName与project.artifactid相同吗?

  • Maven插件(maven-compiler-plugin: 3.8.1和maven-surefire-plugin: 3.0.0-M3)在运行mvn清洁包时似乎正在下载同一依赖项(plexus-utils)的多个版本,即使我在依赖项中指定了plexus-utils的最新版本。这不会导致任何错误,但3.0.16之前的任何版本的plexus-utils都容易受到命令注入的影响。有没有办法阻止这种情况

  • 我正在开发一个Java项目,使用maven作为依赖项管理器/构建工具。我当前在将依赖项的依赖项解析到正确版本时遇到问题。 有问题的依赖项称为JasperReports-Functions-6.1.0.jar,它不是托管在maven repo中,而是以jar形式提供的。 如何强制jar依赖项使用子依赖项的某个版本?

  • 问题内容: 有没有一种方法可以强制maven(2.0.9)将所有依赖项包含在单个jar文件中? 我有一个构建到单个jar文件中的项目。我希望将依赖项中的类也复制到jar中。 更新:我知道我不能只在jar文件中包含jar文件。我正在寻找一种方法来解压缩指定为依赖项的jar,并将类文件打包到我的jar中。 问题答案: 你可以使用带有描述符的插件来执行此操作。这是我们之一的相关块,它可以完成此任务: