来自提供的范围依赖的传递依赖

Posted

技术标签:

【中文标题】来自提供的范围依赖的传递依赖【英文标题】:Transitive dependencies coming from provided scope dependency 【发布时间】:2017-01-15 02:32:17 【问题描述】:

我在我的 vaadin 应用程序 pom 中添加了 vaadin-client-compiler 依赖作为 provided 范围依赖。

正如我所读到的,provided 依赖不是传递的,所以 vaadin-client-compiler 的依赖应该成为我的 webapp 的依赖。

但是,我在我的 WEB-INF/lib 目录中找到了 vaadin-client-compiler (commons-lang3-3.1.jar) 的依赖项。

此外,这些依赖关系也显示在mvn dependency:tree 输出中。

[INFO] |  +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] |  \- javax.validation:validation-api:jar:sources:1.0.0.GA:compile
[INFO] +- com.vaadin:vaadin-client-compiler:jar:7.6.4:provided
[INFO] |  +- com.vaadin:vaadin-sass-compiler:jar:0.9.13:compile
[INFO] |  |  \- com.yahoo.platform.yui:yuicompressor:jar:2.4.8:compile
[INFO] |  |     \- rhino:js:jar:1.7R2:compile
[INFO] |  +- commons-collections:commons-collections:jar:3.2.2:compile
................................................
.................................................
[INFO] |  +- commons-codec:commons-codec:jar:1.8:compile
[INFO] |  +- commons-io:commons-io:jar:2.4:compile
[INFO] |  +- org.apache.commons:commons-lang3:jar:3.1:compile

问题:为什么 provided 范围依赖的依赖变成了我的 webapp 的依赖?

【问题讨论】:

最终包里有jar吗? @VinayVeluri,是的。正如我所提到的,WEB-INF/lib 中可用的依赖 jar。 您是否在创建您的网络应用程序之前构建了它provided?如果您尝试运行 mvn clean package 会发生什么,它是否仍然显示在您的 lib 目录中? @Morfic,我在检查之前做了一个干净的构建。 【参考方案1】:

提供的依赖项的“非传递性”很棘手。这仅意味着您的依赖项提供的依赖项不会被拉取。另一方面,提供的依赖项的编译依赖项被提取(正如您所经历的那样)。完整的真相见下表:

https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

【讨论】:

【参考方案2】:

确实,根据官方Maven Dependency Mediation 的说法,provided 作用域将引入其传递依赖项,如下所示:

compile 范围内的传递依赖项 > 将被提取为 provided 范围 provided 范围内的传递依赖关系 > 被忽略 runtime 范围内的传递依赖项 > 将被提取为 provided 范围 test 范围内的传递依赖关系 > 被忽略

因此,provided 依赖项的传递依赖项要么被忽略,要么也被导入为 provided,因此不属于最终打包的 war

将以下依赖项添加到示例项目中:

<dependencies>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-client-compiler</artifactId>
        <version>7.6.4</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

会导致以下,执行:

mvn dependency:tree -Dincludes=com.vaadin

我们将作为输出的一部分:

[INFO] \- com.vaadin:vaadin-client-compiler:jar:7.6.4:provided
[INFO]    +- com.vaadin:vaadin-shared:jar:7.6.4:provided
[INFO]    +- com.vaadin:vaadin-server:jar:7.6.4:provided
[INFO]    +- com.vaadin:vaadin-client:jar:7.6.4:provided
[INFO]    +- com.vaadin:vaadin-sass-compiler:jar:0.9.13:provided
[INFO]    \- com.vaadin:vaadin-client-compiler-deps:jar:1.2.0:provided

与文档完全一致。

但是,如果我们将以下内容添加到 pom.xml 文件中:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-server</artifactId>
            <version>7.6.4</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

注意:我们将其传递依赖项之一的范围覆盖到compile

重新执行我们之前的命令:

[INFO] \- com.vaadin:vaadin-client-compiler:jar:7.6.4:provided
[INFO]    +- com.vaadin:vaadin-shared:jar:7.6.4:compile
[INFO]    +- com.vaadin:vaadin-server:jar:7.6.4:compile
[INFO]    +- com.vaadin:vaadin-client:jar:7.6.4:provided
[INFO]    +- com.vaadin:vaadin-sass-compiler:jar:0.9.13:compile
[INFO]    \- com.vaadin:vaadin-client-compiler-deps:jar:1.2.0:provided

这意味着:传递依赖 vaadin-server 仍由 vaadin-client-compiler 引入,但根据依赖管理,其范围现在位于 compile

因此,您应该:

检查您的pom.xml 是否定义了任何dependencyManagement 部分 检查您的父 pom 或层次结构中的任何 pom 是否会这样做,执行 mvn help:effective-pom -Doutput=full-pom.xml 肯定会有所帮助 检查是否有任何活动配置文件也会影响构建,执行 mvn help:active-profiles 也会有所帮助

【讨论】:

@LahiruChandima 你解决了这个问题吗?这个答案有帮助吗? 我认为这里没有依赖管理或配置文件特定行为。这是一个标准案例,也在这里描述***.com/q/55147019/1034782 并在 maven 问题跟踪器上注册issues.apache.org/jira/browse/MNG-6607 也许这不是一个“错误”,但似乎这在任何地方都没有记录!

以上是关于来自提供的范围依赖的传递依赖的主要内容,如果未能解决你的问题,请参考以下文章

maven的仓库配置指定jdk编译版本相关编译命令简介scope依赖的范围以及依赖的传递性

maven依赖管理(依赖配置依赖传递依赖冲突依赖范围)

传递依赖的范围确定

Maven 的依赖范围和传递

04_项目一众筹00_05Maven依赖概念,依赖范围依赖传递性依赖的原则:解决jar包冲突依赖排除统一版本管理

传递依赖的范围