ssindelar
ssindelar

Reputation: 2843

Transitive project dependencies not found

I have a flat project hierarchy with 4 projects. Lets call them B,C,D,M and they have the following linear dependencies :

B -> C -> M -> D

-> = "depends on"

Projects B,C and M have a build.gradle and settings.gradle. The settings.gradle always does a includeFlat on all dependent projects. In case of B would that be includeFlat('D', 'M', 'C'). The build.gradle defines the always defines the dependency to the project it depends on. In case of B that would be compile project('C').

If I try to build project B I run into the problem that after parsing B, gradle tries to parse the build.gradle of C and fails because it can't find M.

* What went wrong:
A problem occurred evaluating project ':C'.
> Project with path 'M' could not be found in project ':C'.

I think the relevant part of the debug output is:

Included projects: [root project 'B', project ':C', project ':D', project ':M']

It seems gradle sorts the include in alphabetical order, despite what is defined in the other settings.gradle files and in the build.gradle dependencies.

When I created C I also wondered why I need to include D into the includeFlat settings. But there it works because it orders the includes to D,M.

The only "solution" I currently see is that I remove the project dependencies in B and depend on the build jar of C. But this has the huge (game breaking) disadvantage, that when I change something in D I need a full build, publish and "refresh from nexus" cycle till the changes are visible. Because C, M and D are still in active development this isn't an option.

To fix that I would need to tell the eclipse plugin that when it discovers a jar dependency that is also an project that it adds a project dependency to the classpath instead of the jar dependency.

Upvotes: 0

Views: 581

Answers (2)

Peter Niederwieser
Peter Niederwieser

Reputation: 123996

You seem to have some misconceptions about how Gradle multi-project builds work. Here are some facts that might help you understand what's going on:

  • A Gradle build can only have a single settings.gradle.
  • The order of include statements in settings.gradle has no relevance.
  • Execution dependencies are always between tasks, not between projects. For example, depending on project(":M") is shorthand for depending on the default configuration of that project. Gradle translates this into a dependency on those tasks in M that are responsible for building the artifacts of its default configuration. Note that depending on a project does not mean that all tasks in that project will be run before any task in the depending project.
  • A multi-project build has a logical project hierarchy. ":M" is an absolute project path (: denotes the root project), whereas "M" is a relative project path. Relative paths are interpreted as relative to the current project.

To get a more in-depth understanding of multi-project builds, I recommend to study the "multi-project builds" chapter in the Gradle User Guide, and the multi-project build samples in the full Gradle distribution.

Upvotes: 2

ssindelar
ssindelar

Reputation: 2843

The whole mess was caused by a missing ':'. Gradle seems to differentiate between compile project('M') and compile project(':M'), when the project (in this case the line was in the C) is included by an other project. Just building C works fine with both version. gradle projects returns the same tree for project C in both cases.

I can't explain what exactly is the difference and I hope someone can explain it to me.

Upvotes: 0

Related Questions