'Multi-project' setup help when main project has dependencies on a dependent project's sub projects


(Andrew Beckwith) #1

I need a little help tackling an existing multi-project structure (that I can’t change the structure of). I have searched around and tried a number of things, but I am coming up dry, so I will do my best to describe my scenario here:

Project A (main project)

  • build.gradle

  • settings.gradle

  • src/main/java (web)

  • layers/

    • business/
      • build.gradle
      • src/main/java
    • services/
      • build.gradle
      • src/main/java

Project B (shared project)

  • build.gradle

  • src/main/java (web)

  • layers/

    • business/
      • build.gradle
      • src/main/java
    • services/
      • build.gradle
      • src/main/java

Project C (shared component)

  • build.gradle

  • src/main/java

Project B’s web and business layers depend on Project C Project B’s business layer depends on its own services layer

Project A’s web and business layers depend on Project C Project A’s web layer depends on Project B’s web and business layer Project A’s business layer depends on its own services layer.

This seems to get things building OK (but I should mention I don’t know how to represent the layers subdirectory and seems incorrect):

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

Though this seems to work, I want to know if this is a sound approach? Also, it has surfaced some things I am unsure of, such as:

from projectA/build.gradle:

dependencies {
    compile project(':projectC'),
            project(':projectA:layers:business'),
            project(':projectB:layers:business'),
            project(':projectB'),
            . . .

from projectA/layers/business/build.gradle:

dependencies {
    compile project(':projectC'),
            project(':projectB:layers:business').sourceSets.main.output,
// <-- WHY can't I just refer to projectB:layers:business?
            . . .

If I use just project(’:projectB:layers:business’) as a dependency in the above code, Gradle doesnt complain, but clearly it gets the dependencies wrong as projectA won’t compile because it is missing the deps from projB:layers:business. If I tack on the sourceSets.main.output - it works fine. (just like I would add for testCompile dependencies - e.g. projectB.sourceSets.test.output). Is this expected and normal? (note that projectB:layers:business works fine for the root-level project)