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

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
Evgeny Makarov
  • 1,417
  • 1
  • 21
  • 41
  • is the same dependency also transitively introduced by another dependency in scope compile? – A_Di-Matteo Feb 17 '16 at 10:12
  • No. Just in this one – Evgeny Makarov Feb 17 '16 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 – Balaji Katika Feb 17 '16 at 10:21
  • 1
    [dependency mediation](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html) would put transitive dependencies on scope provide automatically, regardless of their declared scope. @BalajiKatika what you are saying is not correct – A_Di-Matteo Feb 17 '16 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? – A_Di-Matteo Feb 17 '16 at 10:25

1 Answers1

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.

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128