Build lifecycle issue in multi-project build


(Mike Meessen) #1

Given a root project “myproject” with 3 subprojects: “mylib”, “myappdist” and “mywebdist”. The mylib subproject produces a jar on which the two dist projects rely using:

dependencies {
    runtime (
        project(':mylib')
    )
}

myappdist produces a zip created using the gradle application plugin and the the mywebdist produces a war created using the gradle war plugin.

What I want is to add a “myDist” zip task to the “myproject” root project. That task should produce a single zip file that contains just the zip from myappdist and the war from mywebdist.

Here’s what I’ve done (I started with the “myappdist” subproject):

In the subproject, I addad:

apply plugin: 'application'
configurations {
    dist
}
artifacts {
    dist distZip
}

And here’s what I was trying to do in the root project:

task systemZip(type: Zip) {
    baseName = 'MyProject_Master_Archive'
    from project(':myappdist').configurations.dist.allArtifactFiles
}

Doing so results in the failure: “Could not find property ‘dist’ on configuration container.”

When I list myappdist’s configurations in the root project using “project(’:myappdist’).configurations.each { println it }”, “dist” is, indeed, not present. However, when I list the configurations in the myappdist subproject directly using “project.configurations.each { println it }”, my “dist” configuration is present in the configuration.

What am I missing? Why is the systemZip task in the root project being executed before the subproject has been configured?!

Thanks for your help!

Best Regards, Mike


(Luke Daley) #2

Hi Mike,

This section of the userguide covers this:

http://gradle.org/docs/current/userguide/multi_project_builds.html#multiprojectMessagesConfigDependencies

The problem is that in this point of the root build.gradle, the child projects have not yet been evaluated so there is indeed no ‘dist’ configuration.

This will solve it:

evaluationDependsOn ":myappdist"
task systemZip(type: Zip) {
    baseName = 'MyProject_Master_Archive'
    from project(':myappdist').configurations.dist.allArtifactFiles
}

(Peter Niederwieser) #3

By default, a parent project’s build script gets evaluated before the children’s build scripts. There are several techniques for deferring evaluation in Gradle. In your particular case, the simplest solution is to pass a closure to from:

task systemZip(type: Zip) {
    baseName = 'MyProject_Master_Archive'
    from { project(':myappdist').configurations.dist.allArtifactFiles }
}

(Mike Meessen) #4

Wow, thanks so much for the fast answers and explanations!

Of course, both solutions work.

Best regards, Mike