我该如何排除提供的jar的错误版本?

时间:2015-08-28 16:24:52

标签: java maven dependencies

我对某些罐子的冲突版本有一些问题。我依赖于依赖于group-a:artifact-a:0.0.1的库group-b:artifact-b:0.0.1,但我不希望包含group-b:artifact-b:0.0.1,因为我知道在运行时会有group-b:artifact-b:0.0.2

如何编写pom.xml文件?

这是下列之一吗?这些之间的区别是什么?

解决方案1:

group-b:artifact-b排除group-a:artifact-a:0.0.1

<dependencies>
    <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>0.0.1</version>
        <exclusions>
            <exclusion>
                <groupId>group-b</groupId>
                <artifactId>artifact-b</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

解决方案2:

group-b:artifact-b依赖项添加为提供

<dependencies>
    <dependency>
        <groupId>group-b</groupId>
        <artifactId>artifact-b</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>0.0.1</version>
    </dependency>
</dependencies>

解决方案3:

group-b:artifact-b依赖项添加为运行时

<dependencies>
    <dependency>
        <groupId>group-b</groupId>
        <artifactId>artifact-b</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>0.0.1</version>
    </dependency>
</dependencies>

解决方案4:

group-b:artifact-b依赖项添加为提供运行时,并将其从group-a:artifact-a:0.0.1中排除。

更新 很抱歉没有明确,但是@Tunaki的假设是正确的,编译时不需要依赖group-b:artifact-b:0.0.2

2 个答案:

答案 0 :(得分:0)

选项5:只需在POM中明确声明版本。

如果你在pom中明确声明它们,Maven将覆盖传递依赖项。您无需对提供的或运行时范围进行任何操作。

根据docs(强调我的):

  

依赖关系中介 - 这确定在遇到多个版本的工件时将使用哪个版本的依赖项。目前,Maven 2.0仅支持使用“最接近的定义”,这意味着它将在依赖树中使用与项目最接近的依赖项版本。 您可以通过在项目的POM中明确声明版本来保证版本。请注意,如果两个依赖版本在依赖关系树中处于相同的深度,那么在Maven 2.0.8之前没有定义哪一个版本赢了,但是从Maven 2.0.9起,它就是声明中的顺序:第一个声明赢了。

所以你的pom应该是:

<dependencies>
    <dependency>
        <groupId>group-b</groupId>
        <artifactId>artifact-b</artifactId>
        <version>0.0.2</version>
    </dependency>
    <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>0.0.1</version>
    </dependency>
</dependencies>

答案 1 :(得分:0)

您应该使用解决方案4.让我们通过每个解决方案:

解决方案1 ​​

这是使用Maven的exclusions principle。 Maven可传递地解析依赖关系。但是当您不希望在类路径中包含特定的传递依赖项时,可以使用此机制将其排除。

排除的依赖项不会在编译时或运行时使用。

但这不是您想要的,因为您知道您的项目在运行时需要group-b:artifact-b。在这种情况下,pom.xml不会声明它。

解决方案2

您正在使用provided范围。 Maven中的provided表示在编译时需要此依赖项,但不应包含在最终工件中。通常,此依赖关系将在运行时由容器(例如Web服务器)提供

因此,Maven将覆盖group-b:artifact-b:0.0.1的传递依赖group-a:artifact-a。在最终的依赖关系树中,group-b:artifact-b:0.0.2将被解析为提供的依赖关系,而将不会包含在最终工件中(例如,如果构建war,则此库< em>不会以WEB-INF/lib)结束。

解决方案3

这一次,您使用的是runtime范围。这很像解决方案2。

不同之处在于,在最终的依赖关系树中,group-b:artifact-b:0.0.2将被解析为运行时依赖关系,并将包含在最终工件中(例如,如果构建war,则此库最终会在WEB-INF/lib)。

解决方案4

这与解决方案2和3相同。区别在于Maven不会覆盖依赖关系,因为您明确地将其从artifact-a的传递依赖关系列表中排除。但结果将是相同的。

什么是正确的解决方案?

这实际上取决于如何你的依赖将在run-rime中出现。如果它由容器提供,则应使用具有provided范围的解决方案4。如果没有,则应使用具有runtime范围的解决方案4。

我建议这个解决方案是因为:

  • 您明确地排除了artifact-a传递依赖项中不需要的依赖项:这使得更明确的是不应该在项目中使用该特定依赖项。
  • 您明确地在正确的范围和正确的版本中包含所需的依赖关系。同样,这使pom.xml更容易阅读和理解。
<dependencies>
    <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>0.0.1</version>
        <exclusions>
            <exclusion>
                <groupId>group-b</groupId>
                <artifactId>artifact-b</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>group-b</groupId>
        <artifactId>artifact-b</artifactId>
        <version>0.0.2</version>
        <scope>provided</scope> <!-- or runtime, depending on your specific case -->
    </dependency>
</dependencies>