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?
compile This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects. provided This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime.
It is not transitive. This scope indicates that the dependency is not required for compilation, but is for execution. Maven includes a dependency with this scope in the runtime and test classpaths, but not the compile classpath.
Compile. This is the default scope when no other scope is provided. Dependencies with this scope are available on the classpath of the project in all build tasks. They are also propagated to the dependent projects.
Maven Dependency Tree Transitive dependency means that if A depends on B and B depends on C, then A depends on both B and C. Sometimes, transitivity brings a very serious problem when different versions of the same artifacts are included by different dependencies. It may cause version mismatch issues in runtime.
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:
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With