19

I'm running into the same issue as reported here:

I have a Java project A which depends on project B (module), and project B dependes on project C (another module). For project A I would like to setup "includeBuild ../projectB" and for project B I would like too setup "includeBuild ../projectC" so that I could develop everything in Eclipse + Buildship 2.0 without the need to run Gradle for every small change in each of the projecta A, B and C.

But if I setup this I get: "Included build '%s' cannot have included builds.".

Expected Behavior

Recursive "includeBuild" would recursively include dependent projects.

Current Behavior

I get "Included build '%s' cannot have included builds.".

Your Environment

Gradle 3.5, Buildship 2.0, Eclipse 3.6

How can I resolve / work around this issue? In my instance, I have utility project that includes email functionality (using JavaMail). The email functionality is needed in the data project and a UI project. The UI project also depends on the data project.

James
  • 2,876
  • 18
  • 72
  • 116

2 Answers2

23

Adding another answer for a different approach...

Each settings.gradle could add a check to before includeBuild to see if it's already inside a composite. If it's already inside a composite, it doesn't includeBuild.

See here for extra info on the composite check

Eg

project2/settings.gradle

boolean inComposite = gradle.parent != null
if (!inComposite) {
    includeBuild '../project1'
}

project3/settings.gradle

boolean inComposite = gradle.parent != null
if (!inComposite) {
    includeBuild '../project1'
    includeBuild '../project2'
}

project4/settings.gradle

boolean inComposite = gradle.parent != null
if (!inComposite) {
    includeBuild '../project1'
    includeBuild '../project2'
    includeBuild '../project3'
}

etc etc

Using this approach you could run gradle from wherever you like and it should behave as expected (ie substitute dependencies with local projects)

mkobit
  • 43,979
  • 12
  • 156
  • 150
lance-java
  • 25,497
  • 4
  • 59
  • 101
6

Have you considered

  1. Ensuring that none of the individual builds are composite builds
  2. Having an "uber" build which is a composite of everything

Note that the settings.gradle is itself a groovy script, so you could create a dynamic composite, eg all sub-folders with a build.gradle under a parent.

uber/settings.gradle

new File("c:/someFolder").listFiles().each { File f ->
    if (f.directory && new File(f, 'build.gradle').exists()) {
        includeBuild f
    }
}

Eg

c:/someFolder/project1/build.gradle
c:/someFolder/project1/src/main/java/**/*.java
c:/someFolder/project2/build.gradle
c:/someFolder/project2/src/main/java/**/*.java
c:/uber/settings.gradle (as above)
mkobit
  • 43,979
  • 12
  • 156
  • 150
lance-java
  • 25,497
  • 4
  • 59
  • 101
  • Actually it is a little confusing. Can you demonstrate with a folder structure. Taking above case as an example. Thanks in advance – The6thSense Sep 27 '17 at 13:38
  • See sample folder structure. Basically you would checkout all your individual projects to a common folder. Then the `uber` build would compose them all together. If you wanted to put the `uber` project in the same folder you could add an exclusion for it in `settings.gradle` to stop it including itself – lance-java Sep 27 '17 at 13:46
  • Thanks for the explanation. But by this way I cannot include project1 as a dependency for project2 right. – The6thSense Sep 27 '17 at 13:50
  • Yes, you can. project2 would reference project1 by `GAV `(group,artifact,version). As stated in the [documentation](https://docs.gradle.org/3.3/userguide/composite_builds.html#composite_build_intro) "If any build in the composite has a dependency that can be satisfied by the included build, then that dependency will be replaced by a project dependency on the included build" – lance-java Sep 27 '17 at 13:53
  • Note: You'd run all commands through the uber build to benefit from the composite. Running gradle from the individual builds would pickup dependencies from the repository, NOT the composite – lance-java Sep 27 '17 at 13:59