【问题标题】:How to resolve conflict between same classes coming from 2 different jar?如何解决来自 2 个不同 jar 的相同类之间的冲突?
【发布时间】:2019-09-17 11:51:49
【问题描述】:

我正在将项目的 jdk 从 8 更新到 11 。所以,在跑步时我面临着这样的警告

org.aspectj.internal.lang.annotation.ajcDeclareAnnotation scanned from multiple locations: jar:file:///Users/nishtha.garg/.m2/repository/org/aspectj/aspectjrt/1.9.2/aspectjrt-1.9.2.jar!/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.class, jar:file:///Users/nishtha.garg/.m2/repository/org/aspectj/aspectjweaver/1.9.2/aspectjweaver-1.9.2.jar!/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.class

javax.mail.search.MessageIDTerm scanned from multiple locations: jar:file:///Users/nishtha.garg/.m2/repository/javax/mail/mail/1.4/mail-1.4.jar!/javax/mail/search/MessageIDTerm.class, jar:file:///Users/nishtha.garg/.m2/repository/javax/mail/javax.mail-api/1.6.2/javax.mail-api-1.6.2.jar!/javax/mail/search/MessageIDTerm.class

org.aspectj.lang.reflect.DeclarePrecedence scanned from multiple locations: jar:file:///private/var/folders/rw/9_fr4s6s01d5vcykl3fqkd7d3j59v0/T/jetty-0.0.0.0-0-attache-api-rest.war-_api-any-13258162480745251787.dir/webapp/WEB-INF/lib/aspectjrt-1.9.2.jar!/org/aspectj/lang/reflect/DeclarePrecedence.class, jar:file:///private/var/folders/rw/9_fr4s6s01d5vcykl3fqkd7d3j59v0/T/jetty-0.0.0.0-0-attache-api-rest.war-_api-any-13258162480745251787.dir/webapp/WEB-INF/lib/aspectjweaver-1.9.2.jar!/org/aspectj/lang/reflect/DeclarePrecedence.class

org.apache.cxf.transport.http.policy.HTTPClientAssertionBuilder$HTTPClientPolicyAssertion scanned from multiple locations: jar:file:///private/var/folders/rw/9_fr4s6s01d5vcykl3fqkd7d3j59v0/T/jetty-0.0.0.0-0-attache-api-rest.war-_api-any-13258162480745251787.dir/webapp/WEB-INF/lib/cxf-rt-transports-http-3.1.12.jar!/org/apache/cxf/transport/http/policy/HTTPClientAssertionBuilder$HTTPClientPolicyAssertion.class, jar:file:///private/var/folders/rw/9_fr4s6s01d5vcykl3fqkd7d3j59v0/T/jetty-0.0.0.0-0-attache-api-rest.war-_api-any-13258162480745251787.dir/webapp/WEB-INF/lib/cxf-rt-transports-http-3.1.4.jar!/org/apache/cxf/transport/http/policy/HTTPClientAssertionBuilder$HTTPClientPolicyAssertion.class

我可以理解这是因为 2 个 jar 具有相同的类,我必须排除一些依赖项,但我不知道如何排除以及标准应该是什么。

【问题讨论】:

  • 您是否尝试过使用 maven 排除?
  • 其实我试过了,但没有得到要排除的特定依赖项,标准应该是什么?

标签: java spring maven jar dependencies


【解决方案1】:

让我们以你的一个冲突为例:

org.apache.cxf.transport.http.policy.HTTPClientAssertionBuilder$HTTPClientPolicyAssertion 从多个位置扫描:

jar:file:///private/var/folders/rw/9_fr4s6s01d5vcykl3fqkd7d3j59v0/T/jetty-0.0.0.0-0-attache-api-rest.war-_api-any-13258162480745251787.dir/webapp/WEB- INF/lib/cxf-rt-transports-http-3.1.12.jar!/org/apache/cxf/transport/http/policy/HTTPClientAssertionBuilder$HTTPClientPolicyAssertion.class,

jar:file:///private/var/folders/rw/9_fr4s6s01d5vcykl3fqkd7d3j59v0/T/jetty-0.0.0.0-0-attache-api-rest.war-_api-any-13258162480745251787.dir/webapp/WEB- INF/lib/cxf-rt-transports-http-3.1.4.jar!/org/apache/cxf/transport/http/policy/HTTPClientAssertionBuilder$HTTPClientPolicyAssertion.class

深入挖掘(粗体),您可以看到有问题的类是由不同版本的“cxf-rt-transports-http”提供的,即版本 3.1.4 和 3.1.12 的单独 jar。

您需要单独检查每个冲突并从类路径中删除不太理想的 jar。

最好的方法是创建一个排除项,例如:

<exclusions>
    <exclusion>  <!-- declare the exclusion here -->
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
    </exclusion>
</exclusions> 

您在依赖于上述内容的依赖项上声明这一点。

除非您拥有说明依赖关系图的软件,否则这并不总是很容易弄清楚。 例如,在 Eclipse 中,Maven POM 编辑器可以向您显示依赖关系、冲突并为您生成排除项。

选择标准:

在大多数情况下,您可能需要最新版本,因此在这种情况下,可能会是 3.1.12。 但是,您可能不想要最新的、最新的,而是您已经广泛测试但不包含任何漏洞的特定稳定版本。所以这个问题的答案不是直截了当的。

如果您需要特定版本,最好在您自己的 pom 中声明对该工件的显式依赖,并将其从所有其他工件中排除。

编辑:

您可能需要选择特定版本而不是另一个的另一个原因是,您可能正在使用另一个库,而该库又依赖于冲突依赖项的特定版本,但新版本存在问题。

在大多数情况下,版本编号是&lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;,并且几乎所有情况下,错误修复版本都是二进制兼容的,因此对于上面的 cxf-rt-transports-http,您应该可以选择 3.1.12。

另一方面,假设您有依赖项 A 依赖于 C v1.5.0,而 B 依赖于 C v2.1.2。由于这些主要版本之间可能不兼容,这将更加困难。 v2 中可能有你需要的特性,但是 A 不兼容,因为 A 依赖的重要方法被移除了。

然后,您需要检查是否存在可与 C v2.1.X 一起使用的新版本 A 并替换它。如果没有,您可能需要降级 B,或者并排安装它们。在可能涉及重新包装产品的极端情况下。 另一种方法是贡献或分叉项目 A 以创建具有更新依赖项的版本。

也许考虑一下警告的目的会有所帮助: 他们实际上是在说您的代码可以运行,但是有可能以不确定的方式选择了依赖版本,因此您的代码的某些操作可能不符合您的预期。 您想要做的是通过在每种情况下为 JVM 提供一个可供选择的选项来使其具有确定性。作为开发人员,您可以通过有意识地选择使用或依赖哪个版本来做到这一点。

如果您没有其他原因,那么我会选择最新/最高的稳定版本,因为它可能包含最多的功能和错误修复。 像你一样彻底测试,如果你遇到的问题不是由你自己的代码引起的,隔离并报告一个可能的错误,如果你需要降级,直到错误被修复,和/或提供修复自己。

【讨论】:

  • 感谢您的回答,能否请您深入告诉我选择版本的标准。
  • 警告只是警告 - 代码将运行,但如果选择了错误的版本,您的代码可能无法正常运行。以任何方式删除重复项可以解决该问题,但通常您会选择最高版本以包含最多的错误修复。除了选择最高功能或最高稳定性之外,我不确定我还能提供哪些其他信息。有没有什么特别的事情让你怀疑该怎么做?
  • @Nishthagarg 我又添加了几行,希望对您有所帮助。
  • 感谢您的澄清,让我尝试在您提到的所有这些方法的帮助下进行挖掘。希望这些事情奏效!再次感谢:)
猜你喜欢
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 2021-04-25
相关资源
最近更新 更多