ChatGPT解决这个技术问题 Extra ChatGPT

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 (maven GroupId = stax) 替换为 stax-api-1.0-2 (maven GroupId = javax.xml.stream)”解决了问题,所以我'正在尝试那样。

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

我正在使用 maven 2.0.9 以防万一。

mvn 依赖的输出:tree"

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>

T
Thunderforge

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

强制一个版本 如果一个版本在当前 POM 中以特定版本声明,它将始终被尊重 - 但是,应该注意的是,如果它本身依赖于使用传递依赖项,这也会影响下游的其他 pom。

资源 :

依赖调解和冲突解决

依赖机制介绍


目前尚不清楚如何指定版本,因为我没有声明对 D 的依赖。此外,您提供的第一个链接具有“本文档描述了尚未为 Maven 2.0 实现的依赖管理的其余要求,尤其是在传递依赖方面。”在顶部。
@wishihadabettername,正如另一份文档中所说:“您可以在 A 中显式添加对 D 2.0 的依赖项以强制使用 D 2.0”
您实际上在自己的 pom.xml 中复制了相同的 条目。在您的依赖项中,指定您想要的 。这将覆盖“更深”依赖项使用的任何版本。
s
scot

或者,您可以只排除您不想要的依赖项。 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>

需要注意的是,可以使用这种传递依赖,如果需要,排除可能会导致构建失败。
如果您使用的是现代 JDK(即 1.6+)并且您需要通过传递依赖包含的更旧版本的 stax,您可能会遇到各种可怕的运行时类加载器问题。我的建议:使用 JDK 中的那个。如果您遇到“构建失败”,则您依赖于某种形式的古老 API,应该升级。或者:将 JDK 回滚到 1.5。祝你好运。
K
Kent Munthe Caspersen

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

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

您还可以使用 </dependencyManagement> 修改传递依赖项中使用的版本,因为在最上面的 pom 文件中声明的版本就是将要使用的版本。如果您的项目 A 包含一个包含另一个外部项目 C v1.0 的外部项目 B v1.0,这将很有用。有时会在项目 C v1.0 中发现安全漏洞,在 v1.1 中已更正,但 B 的开发人员更新项目以使用 C 的 v1.1 的速度很慢。在这种情况下,您可以简单地声明在项目的根 pom 中依赖于 C v1.1,一切都会好起来的(假设 B v1.0 仍然可以使用 C v1.1 编译)。


使用带有 Spring Boot 父级的 Kotlin 依赖项,dependencyManagement 方法(在顶层)是唯一有效的解决方案
这是正确的答案。您不希望这些库使您的 POM 混乱,除非您知道您将继续将它们永远作为传递依赖项。
请阅读并理解这个错误:“依赖管理不是传递的。” issues.apache.org/jira/browse/MNG-5761 在尝试此解决方案之前。它可能不适用于您的问题。
E
Ewoks

我也无法推翻第三方库中的依赖项。我将 scot's approach 与排除一起使用,但我还在 pom.xml 中添加了具有较新版本的依赖项。 (我使用了 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>

F
Fernando Maia

接受的答案是正确的,但我想加两分钱。我遇到了一个问题,我有一个项目 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 上存在的函数,在检查了 ecipe 的依赖层次选项卡后,我发现在构建期间它使用的是项目 B 中的 slf4j 1.6.1,而不是使用 logback 的 slf4j 1.7.5 .

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

编辑:在项目 B 依赖项也起作用之前添加 slf4j 1.7.5 依赖项。