7

example project (written in Gradle 8.1.1 with kotlin DSL):

https://github.com/tribbloid/scaffold-gradle-kts/tree/16bf3acffca7b83a7e64dbb248a9512caba87e71

This project has 3+ submodules:

include(":lightweight-dependency:core")
include(":lightweight-dependency:extra") // depends on :lightweight-dependency:core
include(":core") // depends on lightweight-dependency:extra
...

When being compiled, it gave the following error:

FAILURE: Build failed with an exception.

* What went wrong:
Circular dependency between the following tasks:
:core:compileJava
+--- :core:compileJava (*)
+--- :core:compileKotlin
|    +--- :core:compileJava (*)
|    +--- :core:compileKotlin (*)
|    \--- :core:compileScala
|         +--- :core:compileJava (*)
|         +--- :core:compileKotlin (*)
|         \--- :core:compileScala (*)
\--- :core:compileScala (*)

(*) - details omitted (listed previously)

This is problematic as :lightweight-dependency:core and :core should be different projects. How to ensure that Gradle can differentiate them?

Ken White
  • 123,280
  • 14
  • 225
  • 444
tribbloid
  • 4,026
  • 14
  • 64
  • 103
  • From the details of the ciruclar dependency error, the problem doesn't even involve the `:lightweight-dependency:*` modules at all. If you follow the "chart", it goes compileKotlin -> compileScala, which then loops back to the others. Look at the `build.gradle` of the main `:core` module, as that is likely where the problem lise. – User51 May 24 '23 at 17:34
  • Yeah I did, it is very clear and specific: https://github.com/tribbloid/scaffold-gradle-kts/blob/16bf3acffca7b83a7e64dbb248a9512caba87e71/core/build.gradle.kts – tribbloid May 24 '23 at 17:54

1 Answers1

1

Gradle has issues resolving dependencies when two subproject names are the same, even if the paths are different.

This is because Gradle differentiates between inter-subproject dependencies using the group and artifact ID of the subprojects.

There are three options:

  1. Update the subproject paths to be distinct. This is my preferred option.

    .
    └── my-project/
        ├── core/
        │   └── build.gradle.kts
        ├── lightweight-dependency/
        │   └── lightweight-dependency-core/
        │       └── build.gradle.kts
        ├── build.gradle.kts
        └── settings.gradle.kts
    
    // settings.gradle.kts
    
    include(
      ":core",
      ":lightweight-dependency:lightweight-dependency-core",
    )
    

    The result is more verbose, but it's more explicit, and I think it follows the principal of least astonishment most closely. It's nice that the subproject file directory matches the artifact ID, which helps with understanding the structure even without loading any Gradle config.

  2. Use a different group per subproject.

    // ./core/build.gradle.kts
    
    group = "my.project"
    
    // ./lightweight-dependency/core/build.gradle.kts
    
    group = "my.project.lightweight-dependency"
    

    Now the coordinates of the two subprojects are different.

    This is also a convenient solution, although it requires some care to make sure that subproject groups don't clash, or to be aware of the requirement if the subprojects IDs or groups are ever updated.

  3. Update the path of the project when they are included settings.gradle.kts by using the ProjectDescriptor

    // settings.gradle.kts
    
    include(":core")
    include(":lightweight-dependency:core")
    
    project(":core").name = "core"
    project(":lightweight-dependency:core").name = "lightweight-dependency-core"
    

    I do not recommend this approach. I think updating the project names in this way is confusing, and unconventional. It will likely lead to unexpected issues, because although it is valid, other Gradle plugins might not realise it is possible.

    This approach is also discouraged in the Gradle documentation:

    Keep default project names for subprojects: It is possible to configure custom project names in the settings file. However, it’s an unnecessary extra effort for the developers to keep track of which project belongs to what folders.

aSemy
  • 5,485
  • 2
  • 25
  • 51