Lahiru Chandima
Lahiru Chandima

Reputation: 24078

Transitive dependencies coming from provided scope dependency

I have added vaadin-client-compiler dependency as a provided scope dependency in my vaadin application pom.

As I have read, provided dependency is not transitive, so the dependencies of vaadin-client-compiler should become dependencies of my webapp.

But, I found dependencies of vaadin-client-compiler (commons-lang3-3.1.jar) inside my WEB-INF/lib directory.

Also, these dependencies are shown in mvn dependency:tree output as well.

[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

Question: Why did dependencies of a provided scope dependency became dependencies of my webapp?

Upvotes: 2

Views: 1418

Answers (2)

A_Di-Matteo
A_Di-Matteo

Reputation: 27812

Indeed, according to official Maven Dependency Mediation, the provided scope would bring in its transitive dependencies as following:

  • Transitive dependencies in compile scope > would be fetched as provided scope
  • Transitive dependencies in provided scope > ignored
  • Transitive dependencies in runtime scope > would be fetched as provided scope
  • Transitive dependencies in test scope > ignored

Hence, transitive dependencies of a provided dependency would either be ignored or be imported as provided as well and as such no part of the final packaged war.

Adding the following dependency to a sample project:

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

Would lead to the following, executing:

mvn dependency:tree -Dincludes=com.vaadin

We would have as part of the output:

[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

Perfectly consistent with the documentation.

However, if we add to the pom.xml file the following:

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

Note: we are overriding the scope of one of its transitive dependencies to compile.

Re-executing the previous command we would have:

[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

Which means: the transitive dependency vaadin-server is still brought in by vaadin-client-compiler, but its scope is now at compile as per dependency management.

Hence, you should:

  • Check whether your pom.xml defines any dependencyManagement section
  • Check whether your parent pom or any pom in the hierarchy would do so, executing mvn help:effective-pom -Doutput=full-pom.xml would definitely help
  • Check whether any active profile would also influence the build, executing mvn help:active-profiles would also help

Upvotes: 1

J Fabian Meier
J Fabian Meier

Reputation: 35833

The "non-transitivity" of provided dependencies is tricky. It only means that the provided dependencies of your dependencies are not pulled. On the other hand, compile dependencies of provided dependencies are pulled (as you have experienced). The full truth is in the table shown in:

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

Upvotes: 0

Related Questions