Issue with multi project dependency order

(Alejandro Salas) #1

Hello everyone,

I have a multi-project build with 3 projects in a flat layout: A, Base, Social.

A depends on Base and Social. Social depends on Base.

So, project A has the this declaration in its build.gradle:

dependencies {
 compile project(':Base')
 compile project(':Social')

The rest of code is located in the master build.gradle file declared inside “subprojects {}”.

My problem is that if I’m inside project A, and run ‘gradle war’ for example, I see the execution of tasks for A, then for Base and then for Social. I’m expecting Base to be processed first (compiled, etc), then Social and A at last.

If someone could point to me what I’m doing wrong and how to fix it I would appreciate it.


(Peter Niederwieser) #2

In Gradle, execution dependencies are always between tasks, not between projects. To paraphrase, ‘compile project(’:Base’)’ means “add a compile dependency on the default outputs of project Base, and an execution dependency on the tasks producing these outputs”. It doesn’t mean that all tasks of Base need to run before any task of A.

If you do have two tasks that get executed in the wrong order (in the sense that the task that gets run first can’t operate correctly without the output of the other task), you are missing a task dependency. Often, Gradle can figure out task dependencies automatically, but sometimes it depends on how (well) the build script is written.

(Alejandro Salas) #3

Thank you Peter for answering so quickly.

I understand what you said about “the execution dependencies are always between tasks, not between projects”.

I was doing some research, I’m using a modified version of the aspectj plugin which overrides the compileJava task and found that an issue has been reported for that case:

I was going to test a suggestion given in the comments of the previous link, but afterwards I read the full comments on this gradle with aspectj article:

And found this: > 2. in each child project’s dependency section, you need to refer to any other projects it depends on for

both compile AND ajc. For example, if project foo depends on project bar, then you’d list the following

in foo’s dependencies section: > > compile project(‘:bar’) > ajc project(‘:bar’)

That solved the issue for me. If there’s a better way or a fix directly on the overwritten compileJava please comment. Thanks once again!

(Alejandro Salas) #4

============== UPDATE ============== Read the end to see the solution ============== UPDATE ==============

I thought I had the issue completely resolved but no ;-(.

With what I posted above, the script compiles the classes in the correct order (first the depended on projects, and the dependent projects last).

My issue now is that my overwritten compileJava depends on a task that pre-process the sourceFiles. I’m using lombok + aspectj, so I need to delombok the code before compiling with aspectj.

What I would like to do is to have my delombok task to behave like compileJava, which detects the dependency between projects and sorts out the execution order without me having to do it explicitly in the task.

Right now this is the output of running “gradle jar” on project A.

I would like for :a:delombok to run after :Base:delombok and :Social:delombok.

:a:delombok :a:processResources :Base:delombok

:Base:processResources :Base:compileJava :Base:classes :Base:jar :Social:delombok :Social:processResources :Social:compileJava :Social:classes :Social:jar :a:compileJava :a:classes :a:jar

Sorry for the long post. And thanks in advance for all the help.

============== UPDATE ============== I was able to solve this last issue using: dependsOn configurations.compile.getTaskDependencyFromProjectDependency(true, “TASK-NAME-HERE”)

Now everything is working as intended. :slight_smile: ============== UPDATE ==============