Configurations.compile.transitive = false doesn't remove transitive compile time dependencies

I see examples for disabling compile time transitive dependencies like this:

  //configuring existing configurations not to put transitive dependencies on the compile classpath
  //this way you can avoid issues with implicit dependencies to transitive libraries
  compile.transitive = false
  testCompile.transitive = false

Source: https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html

However when I tried this I was surprised to see that my compile classpath still included transitive dependencies.

After digging into this further it seems that you should really disable transitivity on the compileClasspath and testCompileClasspath configurations. These are the leaf configurations that are actually used by the compileJava and compileTestJava tasks. True, they extend from compile/testCompile, however extended configurations do not appear to actually inherit the transitivity setting (running the project-report plugin illustrates this nicely)

So all this being the case, is there really ever a reason to set transitive = false on the compile/testCompile configurations, or should you in fact always do this on the compileClasspath and testCompileClasspath configurations?

Only if you directly reference configurations.compile somewhere else (like a custom task). It just so happens that all the tasks configured by the ‘java’ plugin use configurations.compileClasspath as the input. The reason for this is that compileClasspath also includes compileOnly dependencies. So in general, no, you should refer to compileClasspath and testCompileClasspath in most cases as these configurations are the canonical representation of the actual compile classpaths.

You could alternatively do configurations.all { transitive = false } but this would apply to runtime configurations as well which may not be what you want.

1 Like

Yep, that’s exactly the case. I’m turning transitivity off only at compile time to ensure my build.gradle lists all my direct source code dependencies. But at runtime I’d like transitive dependencies enabled so I don’t have to delineate the entire dependency graph.

This is causing a lot of confusion since the introduction of the compileClasspath configuration. See also GRADLE-3524