How to disable transitive compile dependencies

Hi,

We want to explicitly define all compile dependencies. We define the following configuration:

configurations {
    compile.transitive = false
}

We have used this configuration for sometime. We upgraded from 2.14 to 4.10.3 and just recently noticed that dependencies are being resolved transitively.

What is the correct way to force us to define all compile dependencies? We want run time to be transitive, but not compile.

This is my understanding of what changed between 2.14 and 4.10.3. Since gradle 3.4, compileClasspath was added which the Java Plugin uses. Although compileClasspath depends on compile, settings transitive = false on compile is not inherited (by design) and therefore code is compiled with a classpath that includes all the transitive dependencies.

Is this the best solution to force us to explicitly define compile dependencies?

configurations {
    compileClasspath.transitive = false
}
1 Like

Hi @A_Rhuberg,

Yes the change is correct. In Gradle 4/5/6 you have to do these things on compileClasspath (and/or runtimeClasspath). compile should not be used at all anymore. Use implementation or api to declare dependencies: https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation

Interesting question is why you want to exclude the transitives in the first place. There might be other new Gradle features (require Gradle 6 or later Gradle 5 versions) that could be of interest for you (depending on why you do it):

  • If it is only about controlling versions, you should have a look at constraints and platforms. With Gradle 6, there are also strict versions: https://docs.gradle.org/current/userguide/platforms.html
  • If it is about controlling which things you get exactly, dependency locking could also be of interest. One of the next versions will also include dependency verification mechanisms which could be of interest here.
  • If you get ‘too much’ dependencies transitively, you can also exclude selected dependencies or use component metadata rules to adjust wrong dependency declarations

Thanks.

We expect all components to explicitly define compile dependencies. Setting transitive = false will not allow a dependency to be satisfied because it was also required by another dependency. For example: if a component requires ‘com.fasterxml.jackson’, it must explicitly define that dependency; it will not inherit it because it depends on another component that also depends on ‘com.fasterxml.jackson’.

The purpose here is to make it obvious which third parties are being used.

When we upgrade, what new feature would help?

1 Like

I face exactly the same issue with the same reason: we want modules to explicitly define their dependencies. So I want to exclude for compile time transitive dependencies.

If I understood it correctly the implementation configuration should do excaclty what you want. Replace all compile dependencies with implementation and the compile classpath will not be transitive, but the runtime classpath will be.

This behavior is however limited to dependencies you provide (your projectes or libraries). What may be unintentional is that if you depend on 3rd party libraries with maven metadata not generated by gradle, dependencies may still be transitive. This happens when the pom.xml scopes them as compile and not runtime (wich gradle does when you use implementation).

Is this your problem?