JoJota
JoJota

Reputation: 35

Gradle multiproject multiple dependencies

I have a gradle project like this:

root
  |
  |---- projectA
  |
  |---- projectB
 ...

My root build.gradle contains dependencies which are needed for projectA and projectB. I have defined them like this:

subprojects {
    repositories {
        jcenter()
        mavenCentral()
        mavenLocal()
    }
    dependencies {
        compile 'com.google.guava:guava:23.0'
        compile group: 'com.google.code.gson', name: 'gson', version: '2.8.2'

Now I am trying to add a dependency on projectA from projectB so my projectB build.gradle looks like this:

dependencies {
    implementation project(':projectA')
}

and projectB settings.gradle:

include ':projectA'
project(':projectA').projectDir = new File(settingsDir, '../projectA')

This is currently failing, as projectA and B do not depend on root to get their needed dependencies.

Can I add another dependency from projectA on root or what is the default gradle approach to share same dependencies from one root project?

Upvotes: 1

Views: 2015

Answers (2)

Daniele
Daniele

Reputation: 2837

Your modules (A and B) are not correctly setup as child modules of the root project. In your base folder, create if necessary the settings.gradle file, and add the child modules definition:

root/settings.gradle

include 'projectA', 'projectB'

The build.gradle file of projectB is ok as it is, then you need to remove the root/projectB/settings.gradle file; child-modules and their locations are specified in the parent build file.

Upvotes: 1

gothamgreen
gothamgreen

Reputation: 25

Specifying dependencies with the "compile" keyword is being deprecated. The new keyword to use is "implementation". (See this SO question for an example of explanation.) The difference between "compile" and "implementation" as it relates to your case, is that "compile" propagates the dependency to all connected modules, while "implementation" is single-level. So, if you have

root
  module A
  module B

and module B has a depandency brought in with "compile", then root has access to that dependency. But if you now change B to bring the dependency in with "implementation", then you'll still need to add the dependency to the root project's build.gradle.

Why is this relevant? Because a child module isn't allowed to know who its parent is. So, while A and B both see the dependencies you brought into root, they really shouldn't -- seeing those dependencies is a quirk of how Studio works. This is also why the answer to "Can I add another dependency from projectA on root" is "no, you're out of luck there, it'd create a circular dependency and that's not allowed".

The dependencies I'd try are:

In both module A and module B:

dependencies {
  implementation 'com.google.guava:guava:23.0'
  implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.2'

Then in Module B, you do:

implementation project(':projectA')

Then in root, you depend on both A and B.

Upvotes: 1

Related Questions