【问题标题】:How do I resolve a dependency conflict in Maven?如何解决 Maven 中的依赖冲突?
【发布时间】:2018-11-23 18:56:52
【问题描述】:

我有一个相当大的遗留项目,我正在向其中添加一个组件。该组件使用HtmlUnit。我可以用 Maven 编译它,但是当我运行它时,我得到:

java.lang.NoSuchMethodError:
  org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>
    (Ljavax/net/ssl/SSLContext;[Ljava/lang/String;[Ljava/lang/String;Ljavax/net/ssl/HostnameVerifier;)

所以它缺少正确的构造函数。我认为这几乎可以肯定是httpclient 中的版本冲突,但我不确定如何解决它。这是我的pom.xml 的相关部分(注意我一直在尝试使用排除和依赖管理的所有游戏):

<dependencies>
        <dependency>
            <groupId>com.mycompany.mine</groupId>
            <artifactId>my-base-project</artifactId>
            <version>${project.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.httpcomponents</groupId>
                    <artifactId>httpclient</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>base-project</artifactId>
            <version>${project.version}</version>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.httpcomponents</groupId>
                    <artifactId>httpclient</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

有什么想法吗?

编辑:有人建议这个问题与this one 重复,但不是因为这种情况下的依赖类型不是war。

【问题讨论】:

  • 您是否尝试过mvn dependency:tree 以确保没有使用其他版本的org.apache.httpcomponents?
  • 您是否检查了 4.5.2 版本是否包含正确的构造函数?我在网上查看了 4.5 的来源,那些说最后一个参数的类型是 org.apache.http.conn.ssl.X509HostnameVerifier 而不是 javax.net.ssl.HostnameVerifier,所以这可能是个问题(或者 4.5.2 在这里发生了变化)。 - 您使用的是哪个版本的 Maven?我的印象是 Maven 2.x 在解决版本冲突方面有一些困难,而 Maven 3.x 似乎做得很好。
  • @Thomas 看起来它确实有那个构造函数:hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…。我正在使用 Maven 版本 3.3.9。
  • 按照 StephaneM 的建议,尝试使用 maven.apache.org/plugins/maven-dependency-plugin/examples/…dependency plugin;无论如何,只要在您正在运行的项目中指定依赖项,它就应该使用正确的依赖项,因为 Maven 通过最接近根目录解析

标签: java maven


【解决方案1】:

为了识别冲突的依赖关系,请使用mvn dependency:tree。为了便于使用,我喜欢将其通过管道传输到文本文件中:

mvn dependency:tree > tree.txt

然后,使用您最喜欢的文本编辑器查找依赖项的多个版本。

或者,如果您正在寻找特定的 groupId 或 artifactId,请使用 -Dincludes 标志:

mvn dependency:tree -Dincludes=<groupId>:<artifactId>:<version>:<packaging>
mvn dependency:tree -Dincludes=org.springframework <<< get all dependencies with by groupId
mvn dependency:tree -Dincludes=:spring-web <<< get all dependencies by artifactId

您可能还想在此处添加-Dverbose 标志。

解决依赖冲突,有两种方法:

1) 排除你不想要的

<depdency>
    <groupId>some.stuff</groupId>
    <artifactId>with.transitive.depdency</artifactId>
    <exclusions>
        <exclusion>
            <groupId>something</groupId>
            <artifactId>unwanted</artifactId>
        <exclusion>
    <exclusions>
<depdency>

通过这种方式,您将不得不排除每一个带来传递性依赖的依赖。出于这个原因,我更喜欢另一个。

2) 显式添加你想要的版本

<dependency>
    <groupId>something</groupId>
    <artifactId>with.version.conflict</artifactId>
    <version>what I want</version>
</dependency>

这将确保任何传递依赖都将与这个确切的版本交换。但是,如果某些框架实际上需要旧版本,这也可能导致错误。为了安全地使用此策略,您的依赖项需要非常接近最新的可用版本(或同时发布的版本)。

【讨论】:

  • 注意 - 如果你使用mvn dependency:tree &gt; tree.txt,你得到的文本文件会显示依赖关系,以包分隔的逗号。在 2 个或更多不同的包中查找相同子依赖项的不同版本号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 1970-01-01
  • 2017-11-20
  • 2019-01-01
相关资源
最近更新 更多