Java Maven依赖顺序

Java Maven依赖顺序,java,maven,jar,Java,Maven,Jar,在我的项目中,有一个实现接口的类。接口来自一个依赖项。我有另一个依赖项,它本身依赖于一个jar,这个jar也包含相同的接口,除了一个有更多方法的版本;包含相同包接口的两个jar没有相同的groupId或artifactId。 编译失败,因为编译器抱怨我的项目中的类没有实现所有方法。我意识到这是因为编译器从错误的jar获取接口引用。我的问题是,为什么maven使用来自可传递依赖项的接口,而不是我在项目POM中明确提到的来自jar的接口?我可以看到所使用的jar出现在定义的前面(因此我也想象在类路径

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

这是依赖关系树的一部分。注意,这是灰色的,但是仍然可以看到
javax.servlet:servlet api
(实际使用的)在树中比
tomcat:servlet
(应该使用的)更深


我使用的是maven 3.0.4

当您声明对另一个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>

组
人工制品
1.0.0
其他组
人工排除
为什么maven使用可传递依赖关系中的接口 而不是我在 POM计划

因为,对马文来说,这两个人彼此无关。Maven不知道类或包的名称,Maven只知道groupId和artifactId。由于它们不一样,maven没有任何理由省略可传递依赖项

如果我是正确的,Maven会按照定义的顺序将依赖项放在类路径上,即依赖项
a
的可传递依赖项出现在依赖项
b
之前,供将来的访问者使用(因为标题是通用的):

在Maven中,有两类依赖项:

  • :直接在pom.xml文件中定义的内容
  • :pom.xml依赖项所需的依赖项(自动包括,以及它们的依赖项,等等)
根据官方Maven,当遇到多个版本作为依赖项时,将应用以下中介:

Maven选择“最近的定义”
。也就是说,它使用依赖关系树中与项目最接近的依赖关系的版本。您总是可以通过在项目的POM中显式声明来保证版本。请注意,如果两个依赖项版本在依赖项树中的深度相同,则第一个声明获胜

示例:如果A、B和C的依赖项定义为A->B->C->D2.0和A->E->D1.0,则在构建A时将使用D1.0,因为从A到D到E的路径较短。您可以在中显式地向D2.0添加依赖项,以强制使用D2.0


在上面的示例中,A是实际的项目,B和E是在pom.xml文件中定义的外部依赖项,C和D是可传递的依赖项。

是的,我想过这样做。但我的问题,不仅仅是如何修复它,是为什么maven从错误的jar获取接口?我想理解逻辑,在这种情况下,我认为Sean Patrick Floyd是正确的,它们将按照在pom文件中声明的顺序出现在类路径中。您应该根据javax.servlet:ServletAPI进行编译,并在适当的版本上添加依赖项。
    <dependency>
        <groupId>group</groupId>
        <artifactId>artifact</artifactId>
        <version>1.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>othergroup</groupId>
                <artifactId>ArtifactToExclude</artifactId>
            </exclusion>
        </exclusions>
    </dependency>