Gradle includes a transitive runtime dependency as a compilation dependency

I describe a weird behavior in gradle dependency management, where project A refers to project B as a compilation dependency, and to reference library B of project B as a run-time dependency. Now I can use the classes from the C library in my project A.

My question is: (Why) is this a bug or feature?

The problem can be reproduced with gradle 2.9 and 2.10 and the following minimal installation:

// settings.gradle include ':A', ':B' 
 // build.gradle allprojects { apply plugin: 'java' apply plugin: 'maven' repositories { mavenLocal() mavenCentral() } } project(':A') { dependencies { compile project(':B') } } project(':B') { dependencies { runtime "org.slf4j:slf4j-log4j12:1.7.13" } } 

As you can see, gradle :A:dependencies shows

 [...] compile - Compile classpath for source set 'main'. \--- project :B \--- org.slf4j:slf4j-log4j12:1.7.13 +--- org.slf4j:slf4j-api:1.7.13 \--- log4j:log4j:1.2.17 [...] 

and using log4j is entirely possible in the Java code residing in project A.

+8
java dependency-management gradle
source share
2 answers

See this Q & A. If you do not specify a configuration, Gradle will select the default configuration, which extends from runtime . A quick fix is ​​to use

 compile project(path: ":B", configuration: "compile") 
+6
source share

In the case of a transitive Android library runtime (aar) dependency, this has been fixed with Gradle since 5.0.

+1
source share

All Articles