Maven依赖顺序

时间:2012-09-27 15:27:53

标签: java maven jar

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

来解决它

这是依赖树的一部分。 请注意,这是grepped 但仍然可以看到javax.servlet:servlet-api(实际使用的那个)在树中比tomcat: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

3 个答案:

答案 0 :(得分:18)

  

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

因为,对于Maven来说,这两个人彼此无关。 Maven不知道类名或包名,Maven只知道groupId和artifactId。由于那些不一样,maven没有任何理由忽略传递依赖。

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

答案 1 :(得分:5)

当您声明对其他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>

答案 2 :(得分:1)

为将来的访问者(由于标题是通用的):

在Maven中,您有两类依赖项:

根据官方Maven documentation,当遇到多个版本作为依赖项时,将应用以下中介:

  

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

     

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

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