Empty dependency graph after upgrading from 6.8.3 -> 7.6.3

We have a multi module project, with one of those modules being a platform. In 6.8.3 we typically would do something like this in all of our projects:

dependencies {
    compile platform(project(":platform"))
    compile project(":common:java")
    // other dependencies as needed for the app/library
}

When I run dependencies on this, I can see it pulling in lots of dependencies from our platform and the :common:java project and everything builds fine (typically these are Spring Boot apps):

compileClasspath - Compile classpath for source set 'main'.
+--- project :platform
|    +--- org.springframework.boot:spring-boot-dependencies:2.7.14
|    |    +--- org.apache.logging.log4j:log4j-core:2.17.2 (c)
|    |    +--- org.apache.logging.log4j:log4j-slf4j-impl:2.17.2 (c)
|    |    +--- org.apache.logging.log4j:log4j-jul:2.17.2 (c)
...
\--- project :common:java
|    +--- <library 1>
|    +--- <library 2>
|    +--- <library 3>
...

However, after following the migration guide for Gradle 7.6.3, I changed the dependency from compile to implementation:

dependencies {
    implementation platform(project(":platform"))
    implementation project(":common:java")
    // other dependencies as needed for the app/library

And now the resulting dependency graph is basically empty, and nothing compiles because it cannot resolve any of the Java imports:

compileClasspath - Compile classpath for source set 'main'.
+--- project :platform
|    +--- org.springframework.boot:spring-boot-dependencies:2.7.14
\--- project :common:java

I did also try this with Gradle 8.4 using the api dependency, and get the same empty dependency graph. Any help on where to look next would be appreciated!

Do you still have the dependencies on “library 1-3” declared?
Just guessing that you might have commented them out to first get the platform dependency set up or something similar.
Because the constraints (the lines with " (c)" in the end) from the platform are only shown if the actual dependency is also there.
So it looks like the dependencies from :common:java are not declared.

Or if they are still declared, do you have implementation there and only tried api for the platform, or did you try api also for “library 1-3”?
If common:java declares them as implementation dependency it is natural that they do not appear hear as you declare them as only needed for the implementation, not for the api.
This means they are not leaking into the compile classpath of consumers, which is unclean and makes compilation slower and less reliable to future changes.

Typically, you should declare all dependencies you use directly and not use transitive dependencies.
And you should declare those as api that are part of your public API (parameter types, return types, super types, …) and are thus necessary to use your library and are necessary to be present in downstream compile classpath.

We never actually explicitly declared the dependencies for library 1 - 3 when using 6.8.3; we simply declared the common:java module and those other 3 were included (presumably as transitive dependencies).

It sounds like that may no longer be working in Gradle 7 and 8? Not a big deal if this is by design, I just wanted to make sure I wasn’t missing something before I go update 20-30 apps to explicitly declare all their dependencies :slight_smile:

Thanks for replying back!

Yes, the compile configuration - that is deprecated since many many years and finally removed in Gradle 7 - behaves more like api and leaks the dependencies into the compile classpath of consumers as I described.

If you would declare library 1-3 as api dependencies, not implementation dependencies, this would still be the case, but be unclean as described above. :slight_smile: