Transitive dependencies brought by provided scope

2019-06-08 12:30发布

We face an issue when a same artifact-X is transitively brought by a dependency-1 with provided scope, and another dependency-2 with default (compile) scope. This artifact-X will be computed as compile scope, while we expect it to be explicitly provided by dependency-1.

For example, dependency-1 pom contains:

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.1</version>
        </dependency>
    </dependencies>

dependency-2 pom contains:

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8</version>
        </dependency>
    </dependencies>

Assembly project pom contains:

    <dependencies>
        <!-- do not include dependencies already provided by module-1 at runtime -->
        <dependency>
            <groupId>com.company</groupId>
            <artifactId>module-1</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- get dependencies required by module-2 runtime -->
        <dependency>
            <groupId>com.company</groupId>
            <artifactId>module-2</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

But a mvn dependency:tree on assembly project will output:

[INFO] --- maven-dependency-plugin:3.1.0:tree (show-app-dependencies) @ module-3 ---
[INFO] com.company:module-3:pom:1.0
[INFO] +- com.company:module-1:jar:1.0:provided
[INFO] |  +- org.apache.commons:commons-lang3:jar:3.7:compile
[INFO] |  \- org.apache.commons:commons-collections4:jar:4.1:provided
[INFO] \- com.company:module-2:jar:1.0:compile

And we can see the artifact commons-lang3:jar:3.7 which come from dependency-1 is now at compile scope. Note that we don't use any <dependencyManagement> here.

This is very confusing, and leads to duplicate libraries in runtime classpath when dependency-1 is effectively provided in classpath of dependency-2 runtime (for example by an application server).

Moreover, based on Maven documentation about dependency mediation/scope, the transitive dependencies that are provided should be always ommited.

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

It seems to be a bug, that maven-3.6 does not handle, which is a shame !

However, as our goal is simply to package ONLY the libraries defined as compile/runtime (and ignore all the provided ones, and their transitives), how to achieve this using dependency management, or if impossible, using maven-assembly-plugin ??

0条回答
登录 后发表回答