Problem with clean in parallel mode

When we run ‘gradlew clean build --parallel’ open leafs in task graph are sometime executing before clean finishes.

We have a task within build which outputs environment property file in build directory and it does not depend on any other task (so its a open leaf in task graph). At times clean runs after this task and hence deleting the generated file.

Is there a way to force clean before anything else run?

P.S. This started happening with 1.5. It used to work well with 1.4.

Hey,

The parallel build cannot execute tasks sequentially as provided via command line because that would defeat the purpose of the parallel build. Open leafs in the task graph may be executed before ‘clean’ task that belongs to other subproject. E.g. within a given subproject, clean will be always executed first (if it is first at the command line).

The problem you describe may have started happening with 1.5 because in 1.5 we improved the utilization of the parallel threads to reduce the idle time.

The problem might happen because your build dir overlaps with build dirs for other subprojects. Can you confirm? If this is the case, you might need to wait for Gradle 1.6 to fix this problem. 1.6 contains new feature: task ordering rule “mustRunAfter”: http://www.gradle.org/docs/nightly/release-notes#force-a-task-to-run-after-another-task,-without-adding-a-dependency Alternatively, you could configure your build directories differently.

Hope that helps!

No, we do not share build dirs in projects.

As you talked about subprojects, we have many such open leafs in subprojects as well but problem is only with open leafs for root project.

Here is one such output:

03:01:08 …/*.java@756340 - no differing files. 03:01:11 :check.ui:clean 03:01:11 :api:clean 03:01:11 :car.ui:clean 03:01:11 :atol.ui:clean 03:01:12 :cr.ui:clean 03:01:12 :cx.expedia:clean 03:01:12 :dataaccess:clean 03:01:12 :domain:clean 03:01:12 :fli.ui:clean 03:01:12 :grou.ui:clean 03:01:12 :hot.ui:clean 03:01:13 :infosite.ui:clean 03:01:13 :integration.test:clean 03:01:13 :marketing.ui:clean 03:01:13 :mobile.ui:clean 03:01:13 :packages.ui:clean 03:01:13 :platform:clean 03:01:13 :scratchpad.ui:clean 03:01:14 :selfserv.ui:clean 03:01:14 :shared.ui:clean 03:01:14 :stcs:clean 03:01:14 :stub:clean 03:01:14 :tools.ui:clean 03:01:14 :traides.ui:clean 03:01:15 :udp.ui:clean 03:01:15 :compileJava UP-TO-DATE 03:01:15 :processResources UP-TO-DATE 03:01:15 :classes UP-TO-DATE 03:01:15 :createStartupProperties 03:01:15 :dataaccess:fixXSDNamespace 03:01:15 :createJRebelXML SKIPPED 03:01:15 :createLegacySettingsFile 03:01:16 :domain:processResources 03:01:16 :dataaccess:generateGlobalXSDTypes 03:01:17 :platform:compileJava 03:01:18 :clean 03:01:20 :shared.ui:processResources 03:01:20 :api:processResources

I does look wrong that :compileJava runs before :clean

Can you run with --info put the results in a gist? Also, include the exact command line you used.

Thanks!

Ah, I see this for root project:

task clean(overwrite: true, dependsOn: subprojects.clean) << {

ant.delete(dir: buildDir, quiet: ‘true’) }

Do you think this might be the issue? We had to do this because there are few files created by sudo started tomcat instance inside build dir and non-sudo gradlew clean fails to delete such files. We don’t want build to fail when this happens.

Yes, this is the issue. Since ‘:clean’ has to wait for the dependencies to execute, an idle worker may pick up other task from root project.

Why does ‘:clean’ depend on subprojects.clean ?

I see. That dependsOn was an oversight on my part. I guess clean on trunk will by default call clean on all sub projects. Right?

Correct. This is called ‘name matching execution’. Running ‘clean’ from root will execute ‘clean’ task from every subproject, too.

Hope that helps!

Cool. Thanks.