我对某些罐子的冲突版本有一些问题。我依赖于依赖于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
。
答案 0 :(得分:0)
根据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.让我们通过每个解决方案:
这是使用Maven的exclusions principle。 Maven可传递地解析依赖关系。但是当您不希望在类路径中包含特定的传递依赖项时,可以使用此机制将其排除。
排除的依赖项不会在编译时或运行时使用。
但这不是您想要的,因为您知道您的项目在运行时需要group-b:artifact-b
。在这种情况下,pom.xml
不会声明它。
您正在使用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
)结束。
这一次,您使用的是runtime
范围。这很像解决方案2。
不同之处在于,在最终的依赖关系树中,group-b:artifact-b:0.0.2
将被解析为运行时依赖关系,并将包含在最终工件中(例如,如果构建war
,则此库最终会在WEB-INF/lib
)。
这与解决方案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>