Maven: 如何覆盖库添加的依赖项

这是我的一般问题:

我的项目 P 依赖于 A,它依赖于 B,它依赖于 C,它依赖于 D 的1.0.1版本。

D 版本1.0.1有一个问题,我想强制使用另一个模块。我不知道如何在项目的 POM 中声明这一点,因为我没有直接添加对 D 的依赖。是 C 声明了对 D 的依赖关系。

重要提示: 在这种情况下,不仅版本发生了变化,而且组和工件也发生了变化。所以这不仅仅是覆盖依赖项版本的问题,而是排除一个模块并包含另一个模块的问题。

在具体的例子中,D 是 StAX,它的1.0.1有一个 臭虫。根据 bug 中的说明,“通过将 stax-api-1.0.1(专家 GroupId = stax)替换为 stax-api-1.0-2(专家 GroupId = javax.xml.stream) ,问题得到了解决。”。

因此,D = stax: stax-api: jar: 1.0.1和 C = org.apache.xmlbeans: xmlbeans: jar: 2.3.0

我用的是 Maven2.0.9以防万一。

Mvn 依赖项的输出: 树”

mvn dependency:tree
[..snip..]
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile
[INFO] |  +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile
[INFO] |  |  +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] |  |  |  \- stax:stax-api:jar:1.0.1:compile

在我的项目的 POM 中,我对“ A”有以下依赖:

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.6</version>
</dependency>
227258 次浏览

只需在当前的 pom 中指定版本。此处指定的版本将覆盖其他。

强迫一个版本
如果在当前的 POM 中使用特定的版本声明一个版本,那么这个版本将始终受到尊重——但是,应该指出的是,如果这个版本本身依赖于使用传递依赖关系,那么这也将影响下游的其他 POM。


资源:

或者,您可以只排除您不想要的依赖项。STAX 包含在 JDK 1.6中,所以如果您使用的是1.6,可以完全排除它。

我下面的例子对你来说有点错误-你只需要两个排除中的一个,但是我不确定是哪一个。还有其他版本的 Stax,在我下面的例子中,我导入了 A,B 导入了 C & D,每个版本(通过更多的传递依赖)导入了不同版本的 Stax。所以在我对“ A”的依赖中,我排除了两个版本的 Stax。

<dependency>
<groupId>a.group</groupId>
<artifactId>a.artifact</artifactId>
<version>a.version</version>
<exclusions>
<!--  STAX comes with Java 1.6 -->
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>javax.xml.stream</groupId>
</exclusion>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
<dependency>

我也无法推翻第三方图书馆的依赖关系。我使用了 斯考特来了作为排除,但是也在 pom 中添加了新版本的依赖项。(我使用 Maven 3.3.3)

对于 stAX 的例子,它看起来是这样的:

<dependency>
<groupId>a.group</groupId>
<artifactId>a.artifact</artifactId>
<version>a.version</version>
<exclusions>
<!--  STAX comes with Java 1.6 -->
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>javax.xml.stream</groupId>
</exclusion>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
<dependency>


<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency>

您放在根 pom 的 </dependencies>标记中的内容将包含在根 pom 的所有子模块中。如果您的所有模块都使用该依赖项,那么就应该这样做。

但是,如果10个子模块中只有3个使用某种依赖项,则不希望将此依赖项包含在所有子模块中。在这种情况下,只需将依赖项放在 </dependencyManagement>中即可。这将确保任何需要依赖项的子模块都必须在它们自己的 pom 文件中声明它,但是它们将使用与 </dependencyManagement>标记中指定的相同版本的依赖项。

您还可以使用 </dependencyManagement>来修改传递依赖关系中使用的版本,因为在最上面的 pom 文件中声明的版本就是将要使用的版本。如果您的项目 A 包含一个外部项目 B v1.0,其中包含另一个外部项目 C v1.0,那么这将非常有用。有时会发现项目 C 1.0版本中存在安全漏洞,这个问题在1.1版本中得到了纠正,但是 B 的开发人员在更新他们的项目使用 C 1.1版本时动作很慢。在这种情况下,您可以简单地在项目的根 pom 中声明对 C v1.1的依赖,一切都会很好(假设 B v1.0仍然能够用 C v1.1编译)。

这个被接受的答案是正确的,但是我想补充一下我的意见。我遇到了一个问题,我有一个项目 A,有一个项目 B 作为一个依赖。两个项目都使用 slf4j,但项目 B 使用 log4j,而项目 A 使用 logback。 项目 B 使用 slf4j 1.6.1,而项目 A 使用 slf4j 1.7.5(由于已经包含了 logback 1.2.3依赖项)。

问题是: 项目 A 无法找到存在于 slf4j 1.7.5上的函数,在检查了 eclippe 的依赖层次选项卡后,我发现在构建过程中使用的是项目 B 的 slf4j 1.6.1,而不是 logback 的 slf4j 1.7.5。

我通过更改项目 A pom 的依赖关系顺序解决了这个问题,当我将项目 B 条目移到 logback 条目下面时,然后 maven 开始使用 slf4j 1.7.5构建项目。

编辑: 在 ProjectB 依赖项之前添加 slf4j 1.7.5依赖项也有效。