javagradlegradle-dependencies

Gradle multi project transitive dependency


I have three gradle projects. Say ProjectA, ProjectB and ProjectC.

ProjectC is dependent on both ProjectA and ProjectB. While ProjectB is dependent on ProjectA.

So ProjectC's build.gradle has the following lines:

dependencies {
  implementation project(':ProjectA')
  implementation project(':ProjectB')
}

And ProjectB's build.gradle has the following:

dependencies {
  implementation project(':ProjectA')
}

My question is why do I need explicit implementation declaration for ProjectA in ProjectC's build file?

Since, I am adding ProjectB, shouldn't ProjectA be included automatically since ProjectB is dependent on ProjectA ?

In other words, why the following does not work for ProjectC ?

dependencies {
  implementation project(':ProjectB')
}

I am new to gradle and thus trying to understand how dependency management between Project's work.


Edit:

So I want to change ProjectB's build.gradle to below:

dependencies {
  api project(':ProjectA')
}

So that I can simplify ProjectC's build.gradle to:

dependencies {
  implementation project(':ProjectB')
}

However, I get the following error:

A problem occurred evaluating project ':ProjectB'.
> Could not find method api() for arguments [:ProjectA] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

Am I missing something?


Solution

  • Because implementation is precisely for that: it tells that ProjectA is needed for the code of ProjectB to work (internally), but is not part of its API (i.e. you don't want clients of ProjectB to rely on the fact that it uses ProjectA internally).

    If you want ProjectA to be part of the API of ProjectB, then use the api configuration rather than implementation.

    See the guide for more details.