Transitive project dependencies available at compile to the depending project


(Daniel Vermaasen) #1

When using a project dependency (with scope compile), Gradle adds the subprojects transitive dependencies as a compile dependency to the project itself.

Here is a sample projects structure:

------------------------------------------------------------
Project :datamodel
------------------------------------------------------------
compile - Dependencies for source set 'main'.
No dependencies


------------------------------------------------------------
Project :backend
------------------------------------------------------------
compile - Dependencies for source set 'main'.
\--- project :datamodel


------------------------------------------------------------
Project :frontend
------------------------------------------------------------
compile - Dependencies for source set 'main'.
\--- project :backend
     \--- project :datamodel

I would expect the transitive dependency datamodel to be provided at runtime for the project frontend. Instead it is possible to compile against classes from the datamodel project.
Is this an intended feature? In case it is, can anyone explain why Gradle is setting the scope of transitive dependencies to compile?

To fix this problem, i added dependencies like this:

compile (project(path: ':backend')) {
    transitive = false
}

runtime project(path: ':backend', configuration: 'runtime')

Is there any other way to bypass this problem?


(James Justinic) #2

Yes, this is how the compile configuration works. Consumers see the default configuration, which extends runtime, which extends compile. Additional details are available in the user guide.

However, compile is considered a deprecated configuration. Instead you likely want to declare your dependencies as implementation, not compile, which will not leak these “implementation” details into the compile classpath of consumers.

Additional details about API and implementation separation are with the java-library plugin documentation although you do not need to apply this plugin if you just want to use implementation, and not api.