Composite Build fails with Circular Dependency when using own platform depedency created by java-platform plugin

Hello,
I hope someone can share some light on this problem we have with our own platform dependency.
In our very simple Proof-of-Concept project we have 3 dependent projects, where ci_poc_gitflow_a is the lowest with the sub project Utils,
then comes the ci_poc_gitflow_b with the sub project Common,
and on top of the the ci_poc_gitflow_c project with the sub project Application.
All gradle project use the newest gradle version 5.6.2 (we also tried some older versions and had the same problem)
The java-platform project has therefore this very simple entry:

dependencies {
    constraints {
        api 'net.mycompany.gitflow.ci_poc_gitflow_a:Utils:3.0-SNAPSHOT'
        api 'net.mycompany.gitflow.ci_poc_gitflow_b:Common:3.0-SNAPSHOT'
        api 'net.mycompany.gitflow.ci_poc_gitflow_c:Applications:3.0-SNAPSHOT'
    }
}

So now each subproject can use a platform dependency to determine the version numbers and does not need to specify them on the dependency itself.

So in the c project we have this dependency:

dependencies {
api platform(‘net.mycompany.gitflow.ci_poc_gitflow_platform:ci_poc_gitflow_platform:1.0’)
api ‘net.mycompany.gitflow.ci_poc_gitflow_b:Common’
}

While in the b project this dependency is used:

dependencies {
api platform(‘net.mycompany.gitflow.ci_poc_gitflow_platform:ci_poc_gitflow_platform:1.0’)
api ‘net.mycompany.gitflow.ci_poc_gitflow_a:Utils’
}

This scenario works perfectly correct and all project are building fine, when you do NOT use includeBuild in any settings.gradle file to create a composite build. So a gradlew build on each folder works correctly and the artifacts can be published.

Once you add an

includeBuild ‘…/ci_poc_gitflow_a’

to the c project and connect so the two project directly with each other, then the build fails with this message:

FAILURE: Build failed with an exception.

  • What went wrong:
    Circular dependency between the following tasks:
    :ci_poc_gitflow_a:Utils:compileJava
    -– :ci_poc_gitflow_a:Utils:compileJava (*)

For a strange reason you can simply fix this problem (and all other kind of circular dependency problems) by just adding another

includeBuild ‘…/ci_poc_gitflow_platform’

line to the settings.gradle of the top c project, which points to the folder of the platform project. (But this would mean that every developer who needs to use a composite build must also checkout the platform project, which we would like to avoid)

You can also fix this problem by adding an exclude of the subproject itself to the platform in the project a in this way:

api platform(‘net.mycompany.gitflow.ci_poc_gitflow_platform:ci_poc_gitflow_platform:1.0’) {
exclude group:‘net.mycompany.gitflow.ci_poc_gitflow_a’,module:‘Utils’
}

When you add this kind of exclude of the same subproject from the platform also to the b subproject common, you can includeBuild this b project in the top c project:

api platform(‘net.mycompany.gitflow.ci_poc_gitflow_platform:ci_poc_gitflow_platform:1.0’) {
exclude group:‘net.mycompany.gitflow.ci_poc_gitflow_b’,module:‘Common’
}

But when you try then to have both subproject a and b in the includeBuild of c it fails again:

includeBuild ‘…/ci_poc_gitflow_a’
includeBuild ‘…/ci_poc_gitflow_b’

with this other kind of circular dependency error:
FAILURE: Build failed with an exception.

  • What went wrong:
    Included build dependency cycle: build ‘ci_poc_gitflow_a’ → build ‘ci_poc_gitflow_b’ → build ‘ci_poc_gitflow_a’

This can be fixed when you add in the a project more excludes:

api platform(‘net.mycompany.gitflow.ci_poc_gitflow_platform:ci_poc_gitflow_platform:1.0’) {
exclude group:‘net.mycompany.gitflow.ci_poc_gitflow_a’,module:‘Utils’
exclude group:‘net.mycompany.gitflow.ci_poc_gitflow_b’,module:‘Common’
exclude group:‘net.mycompany.gitflow.ci_poc_gitflow_c’,module:‘Applications’
}

This ‘exclude’-solution is not feasible for us, as it would require, that we would need to analyse each project and adapt the platform dependency accordingly with the necessary excludes. (Also these excludes do not change the generated pom and are therefore not necessary for any kind of standard build = non-composite-build)

So the question is, whether we did not understand/use the platform mechanism correctly or whether there is a limitation in the usage with includeBuild/composite Builds?
Another question is, why does any kind of circular dependency problem goes away without any exclude, when you just add the orignal platform gradle project to the composite build?
We would appreciate any kind of help/insight into this topic. If necessary we can also share the whole scenario as a zip file.
Best regards

Reza Labude

This issue is most likely fixed by https://github.com/gradle/gradle/pull/13804 that will be part of 6.7 (nightly available at https://gradle.org/nightly/).