Maven 依赖顺序

2022-09-02 12:48:37

在我的项目中,有一个实现接口的类。接口来自依赖项。我有另一个依赖项,它本身依赖于一个也包含相同接口的jar,除了具有更多方法的版本;包含相同包接口的两个 jar 没有相同的 groupId 或 artifactId。
编译失败,因为编译器抱怨我的项目中的类没有实现所有方法。我意识到这是因为编译器从错误的jar中获取了接口引用。我的问题是,为什么maven使用来自传递依赖项的接口,而不是我在项目POM中明确提到的jar中的接口?我可以看到使用的jar出现在定义的早期(所以我也想象在类路径中),但我认为在这些情况下,maven通过使用具有最短路径的依赖项中的碰撞类/接口来解决它

下面是依赖项树的一部分。请注意,这是 grepped,但仍然可以看到(实际使用的那个)与(应该使用的那个)相比,它在树中更深javax.servlet:servlet-apitomcat:servlet

[builder@ca-rd-build11 proj]$ mvn dependency:tree | grep servlet
[INFO] |  +- javax.servlet:servlet-api:jar:2.4:compile
[INFO] +- tomcat:servlet:jar:4.0.6:compile

我使用的是 maven 3.0.4


答案 1

为什么 maven 使用来自可传递依赖项的接口,而不是我在项目 POM 中明确提到的 jar 中的接口?

因为,对Maven来说,这两者彼此之间没有任何关系。Maven 不知道类或包名称,Maven 只知道 groupId 和 artifactId。由于这些是不一样的,maven没有任何理由省略传递依赖关系。

如果我是正确的,Maven按照定义的顺序将依赖关系放在类路径上,即依赖关系的传递依赖关系出现在依赖关系之前。ab


答案 2

当您声明对另一个 jar 文件的依赖关系时,您可以告诉它排除对冲突 jar 文件的可传递依赖关系:

    <dependency>
        <groupId>group</groupId>
        <artifactId>artifact</artifactId>
        <version>1.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>othergroup</groupId>
                <artifactId>ArtifactToExclude</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

推荐