【问题标题】:Maven transitive dependency has scope compile while when dependency has provided scope当依赖项提供范围时,Maven 传递依赖项具有范围编译
【发布时间】:2016-05-28 23:24:30
【问题描述】:

在我的项目中,我有 openejb-core 范围 provided 的依赖项。但是它具有slf4j 的传递依赖关系,其范围是compile(见截图)。所有其他传递依赖项都按预期提供。

问题:是错误还是我遗漏了什么?

【问题讨论】:

  • 同一个依赖是否也被编译范围内的另一个依赖传递引入?
  • 没有。就在这个
  • 好吧,它为您的项目提供了范围。但是 openejb-core 可以用 compile 范围声明它,这就是你可以将它视为 compile 的原因
  • dependency mediation 会自动将传递依赖项放在作用域提供上,而不管它们声明的作用域如何。 @BalajiKatika 你说的不对
  • @EvgenyMakarov 如果您运行mvn dependency:tree -Dincludes=org.slf4j,您会在其他地方发现它吗?是否有父 pom 或 dependenciesManagement 部分?

标签: java maven maven-3 pom.xml dependency-management


【解决方案1】:

在我添加的示例 pom 中:

<dependencies>
    <dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-core</artifactId>
        <version>4.7.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

然后运行:

mvn dependency:tree -Dincludes=org.slf4j

输出是:

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ test-junit ---  
[INFO] com.sample:test-sample:jar:0.0.1-SNAPSHOT   
[INFO] \- org.apache.openejb:openejb-core:jar:4.7.0:provided   
[INFO]    +- org.slf4j:slf4j-jdk14:jar:1.7.7:provided   
[INFO]    \- org.slf4j:slf4j-api:jar:1.7.7:provided   

如您所见,Maven 与其official documentation 是一致的。您的屏幕截图中的问题可能出在您的 IDE 上。

表格是这个话题的重点:

从中我们可以看出,compileruntime 范围内的可传递内容进入提供的范围内,providedtest 范围内的内容被忽略。

但是,如果我将示例 pom 更改为:

<dependencies>
    <dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-core</artifactId>
        <version>4.7.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
    </dependency>
</dependencies>

然后重新运行依赖树命令,输出如下:

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ test-junit ---
[INFO] com.sample:test-sample:jar:0.0.1-SNAPSHOT   
[INFO] +- org.apache.openejb:openejb-core:jar:4.7.0:provided  
[INFO] |  \- org.slf4j:slf4j-jdk14:jar:1.7.7:provided  
[INFO] \- org.slf4j:slf4j-api:jar:1.7.7:compile  

现在看:它不是作为提供的依赖项的子项,而是在同一级别。

让我们继续。

如果在我的示例 pom 中,我删除了 sl4f-api 依赖项,但我在 pom 中添加了以下内容:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

然后重新运行依赖树命令,我终于得到和你截图一样的了:

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ test-junit ---
[INFO] com.sample:test-sample:jar:0.0.1-SNAPSHOT   
[INFO] \- org.apache.openejb:openejb-core:jar:4.7.0:provided   
[INFO]    +- org.slf4j:slf4j-jdk14:jar:1.7.7:provided  
[INFO]    \- org.slf4j:slf4j-api:jar:1.7.7:compile  

BingodependencyManagement 部分覆盖了传递依赖的范围,也影响了provided 范围的中介。这不是错误,它是设计使然,因为在本节中您定义了与依赖项相关的治理类型。这种情况下的图表也是正确的并且没有误导性,因为依赖关系仅由openejb-core 引入,然后受dependencyManagement 决定将sl4f-api 置于compile 范围内的影响。

【讨论】:

  • 感谢您的详细回答。这似乎是依赖管理的情况。我不知道这种行家行为
  • 感谢您提供如此详细的答案,为我清除了一些东西。
  • 我们可以在没有任何dependencyManagement 的情况下看到类似的问题,但是当提供范围的分支由另一个编译范围的分支带来传递依赖时:编译范围胜出传递依赖,非常混乱
  • 我发现dependency:analyze 很容易理解使用了哪些依赖项,哪些没有使用
猜你喜欢
  • 2018-07-30
  • 2013-03-25
  • 2018-05-19
  • 2019-08-23
  • 1970-01-01
  • 2015-04-12
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多