Maven-从DependencyManagement中排除传递依赖项

时间:2020-01-26 01:45:08

标签: java maven

考虑使用Maven pom.xml跟随3.6.2

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <artifactId>foo</artifactId>
  <groupId>bar</groupId>
  <version>1.0.0</version>

  <dependencies>
<!-- #1
    <dependency>
      <groupId>org.jdbi</groupId>
      <artifactId>jdbi3-jackson2</artifactId>
      <version>3.12.0</version>
    </dependency>
-->
    <dependency>
      <groupId>org.apache.kafka</groupId>
      <artifactId>kafka_2.12</artifactId>
      <version>2.4.0</version>
      <scope>compile</scope>
    </dependency>
<!-- #2
    <dependency>
      <groupId>org.jdbi</groupId>
      <artifactId>jdbi3-jackson2</artifactId>
      <version>3.12.0</version>
    </dependency>
-->
  </dependencies>

<!-- #3
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jdbi</groupId>
        <artifactId>jdbi3-bom</artifactId>
        <type>pom</type>
        <version>3.12.0</version>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
-->

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>
</project>

如果运行mvn dependency:tree | grep databind,应该会看到:

[INFO]    +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.0:compile

这是基准,并确定kafka_2.12使用jackson-databind:2.10.0

如果您取消注释仅注释#1并重新运行,则应该看到:

[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.9.3:compile

这对我来说很有意义,并告诉我jdbi3-jackson2使用jackson-databind:2.9.9.3,并且使用此版本是因为它出现在之前 kafka_2.12

如果您取消注释仅注释#2并重新运行,则应该看到:

[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.0:compile

这对我也很有意义,因为jdbi3-jackson2现在出现在之后 kafka_2.12

如果您取消注释仅注释#3并重新运行,则应该看到:

[INFO]    +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.9.3:compile

我期望2.10.0是因为我没有使用Bom中的任何东西(特别是jdbi3-jackson2

基于几乎每个人对Bom所说的一切,我会认为只有在Bom中应用依赖项时才会使用他们的版本信息

此外,如果我在dependencyManagement中的任意位置添加以下 ,那么它将返回到2.10.0

  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.0</version>
  </dependency>
  1. 我如何检测到此问题(我之所以发现此问题是因为kafka会失败,并告诉您它需要特定的杰克逊)。我的想法是编写一个脚本/插件,将“ dependency:tree”与“黄金”副本进行比较,如果它们不同,则至少在使人dependencyManagement
  2. 如何从dependencyManagement中排除依赖项?我已经完成了正常的依赖关系,并且为dependencyManagement存在相同的exclusions标记,但是我没有任何尝试。我认为排除在您实际使用依赖项时生效,但我也认为该版本也将在您实际使用依赖项时生效,但这种假设似乎是错误的。
  3. 因为我无法排除它,所以可以通过上述方法强制使用该版本,但是为什么它在dependencyManagement中使用时不管其顺序如何,与常规dependencies标签中的顺序很重要?

2 个答案:

答案 0 :(得分:0)

首先,BOM会覆盖传递依赖关系。如果某个依赖项出现在依赖项树中,并且BOM表为其指定了一个版本,则该版本将获胜,除非:

  • 您使用其他版本自己定义了依赖项。
  • 您自己添加了dependencyManagement条目,以覆盖BOM表中的值。

当然,如果BOM重叠,那么只有一个可以获胜。

因此,如果您将jackson-databind作为传递依赖项,并且具有包含它的BOM表,则可以从BOM表获取版本。除非您自己创建一个覆盖BOM的dependencyManagement条目。

答案 1 :(得分:0)

  • 对于#1。我建议使用maven-enforcer-plugin

  • 对于#2。您只能排除直接传递依赖项。

  • 对于#3。该算法基于最接近的定义进行决策,这意味着依赖将与您的项目越接近,它将被选择。