12

In my project I have openejb-core dependency with scope provided. However it has transitive dependency of slf4j and its scope is compile (see screenshot). All other transitive dependencies are provided as expected.

Question: Is it bug or am I missing something?

enter image description here

5
  • is the same dependency also transitively introduced by another dependency in scope compile? Commented Feb 17, 2016 at 10:12
  • No. Just in this one Commented Feb 17, 2016 at 10:13
  • Well, its provided scope for your project. But openejb-core could have declared it with compile scope and that is the reason you could be seeing it as compile Commented Feb 17, 2016 at 10:21
  • 1
    dependency mediation would put transitive dependencies on scope provide automatically, regardless of their declared scope. @BalajiKatika what you are saying is not correct Commented Feb 17, 2016 at 10:21
  • @EvgenyMakarov if you run mvn dependency:tree -Dincludes=org.slf4j do you spot it somewhere else? is there a parent pom or a dependenciesManagement section? Commented Feb 17, 2016 at 10:25

1 Answer 1

16

In a sample pom I added:

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

Then running:

mvn dependency:tree -Dincludes=org.slf4j

The output is:

[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   

So as you can see Maven is coherent with its official documentation. The issue from your screenshot is probably on your IDE.

The table is the key point on this topic: enter image description here

From it, we can see that what is transitively in scope compile or runtime goes in scope provided, what is in scope provided or test is ignored.

However, if I change my sample pom to:

<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>

And re-run the dependency tree command, the output is as following:

[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  

Look now: it comes not as a child of the provided dependency, but at the same level.

Let's keep on.

If on my sample pom I remove the sl4f-api dependency but I add to the pom the following:

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

And re-re-run the dependency tree command, I finally get the same as your screenshot:

[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  

Bingo: the dependencyManagement section is overriding the scope of the transitive dependency, affecting also the mediation on provided scope. This is not a bug, it's by design as in this section you define kind of governance concerning your dependencies. The diagram in this case is also correct and not misleading, since the dependency is only introduced by openejb-core which is then affected by the dependencyManagement decision to put sl4f-api in scope compile.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the detailed answer. It's seems to be the case of dependencyManagement. I wasn't aware of such maven behaviour
Thanks for such a detailed answer, cleared a few things for me.
we can see similar issue whithout any dependencyManagement but when a transitive dependency is brought by a provided-scoped branch and by another compile-scoped branch : compile scope wins for transitive dependency, which is very confusing
I found dependency:analyze quite handy to understand which dependency was used and which wasn't
This answer is underrated. +1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.