I noticed that gradle doesn’t have any sort of locking mechanism when running multiple gradle processes (using the daemon) in parallel. So if I run ‘gradle build’ (using the daemon) for the same project in two different shells they interfere with each other. This is fine since it isn’t really a practical use case. However, I would like to know if I can build different projects simultaneously (for CI purposes) without the multiple gradle processes interfering with each other. Of course, this is assuming all dependent projects for the concurrent builds have been built. For example, let’s say I have ProjectA, ProjectB, and ProjectC which all depend on ProjectShared and ProjectShared has been built at this point. Can I build A, B, and C with 3 separate gradle processes without any issues in theory?
Hi Ahsan,
You can actually run two Gradle processes on the same project reasonably safely, as long as they don’t mess with what each other is doing (e.g. deleting created files). Gradle does lock around critical files and sections to make this safe. For example, you may have a long running build that is executing some tests and while that is happening you may want to regenerate your IDE metadata, and it is safe to do this in a separate process.
As for separate projects with separate processes, this is completely safe. We put a lot of work into making things like the Gradle dependency cache multi process safe.
That’s good to hear. However, I am seeing the below error frequently when building different projects simultaneously using the daemon. It doesn’t seem to happen when I don’t use the daemon.
Gradle build daemon disappeared unexpectedly (it may have been stopped, killed or may have crashed)
This happens before the tasks are actually run.
Daemon log: http://pastebin.com/nKsGWzLc
That’s not necessarily an error condition on its own. Is your build failing?
Yes - here’s some output from Jenkins. The particular job then fails because the project fails to build.
And this only happens when running concurrent builds?
Yes
This means that either the daemon process is crashing, or there’s a network communication failure. In the output you’ll see something like…
23:05:48.117 [INFO] [org.gradle.launcher.daemon.server.exec.ExecuteBuild] Executing build with daemon context: DefaultDaemonContext[uid=4171dd9d-b7fc-4dbe-af49-a48b5a818e7a,javaHome=/usr/local/jdk1.6.0_20,daemonRegistryDir=/home/NATPAL/arabbani/.gradle/daemon,pid=7570,idleTimeout=10800000,daemonOpts=-XX:MaxPermSize=256m,-XX:+HeapDumpOnOutOfMemoryError,-Xmx1024m,-Dfile.encoding=UTF-8]
Note the ‘pid=7570’, which gives the pid of the daemon process.
After a crash, can you please see if this process is around (which would indicate a network issue). This is unlikely, but ruling it out is a good place to start.
I just tried now and the process is not around after the crash. Could it be an out of memory error that’s just not being logged? Also, I noticed that a new daemon was being created for each job. So if three projects were being built I would see 3 gradle daemons which is strange since they’re all being built from the same workspace with the same gradle settings. See below.
arabbani 15797
1 62 15:38 ?
00:00:20 /usr/local/jdk1.6.0_20/bin/java -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=UTF-8 -cp /home/NATPAL/arabbani/.gradle/wrapper/dists/gradle-1.3-bin/6duudkdtsf89ftu9dh8bpgenv0/gradle-1.3/lib/gradle-launcher-1.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 1.3 /home/NATPAL/arabbani/.gradle/daemon 10800000 7d7c421e-46e6-4983-984a-ce29ce27f2bc -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=UTF-8
arabbani 15850 15828 65 15:38 ?
00:00:15 /usr/local/jdk1.6.0_20/bin/java -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=UTF-8 -cp /home/NATPAL/arabbani/.gradle/wrapper/dists/gradle-1.3-bin/6duudkdtsf89ftu9dh8bpgenv0/gradle-1.3/lib/gradle-launcher-1.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 1.3 /home/NATPAL/arabbani/.gradle/daemon 10800000 9cb11e56-9918-4275-b7b4-e948bfbe6e1e -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=UTF-8
arabbani 15902 15875 72 15:38 ?
00:00:04 /usr/local/jdk1.6.0_20/bin/java -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=UTF-8 -cp /home/NATPAL/arabbani/.gradle/wrapper/dists/gradle-1.3-bin/6duudkdtsf89ftu9dh8bpgenv0/gradle-1.3/lib/gradle-launcher-1.3.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 1.3 /home/NATPAL/arabbani/.gradle/daemon 10800000 c0b0bcab-3a2d-4292-bfe2-25248ddf68c6 -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=UTF-8
Here’s another error (NPE) I’ve seen sometimes when running concurrently.
Daemons never run more than one build. So I would expect three processes.
We experimented with concurrent builds in the same daemon, but found it too hard to completely isolate the different builds. For example, you can’t partition the system properties.
That’s very interesting.
What Gradle version are you running?
[arabbani@nyc-dev-bld1 YodleCoreCentral]$ ./gradlew --version
------------------------------------------------------------ Gradle 1.3 ------------------------------------------------------------
Gradle build time: Tuesday, November 20, 2012 11:37:38 AM UTC Groovy: 1.8.6 Ant: Apache Ant™ version 1.8.4 compiled on May 22 2012 Ivy: 2.2.0 JVM: 1.6.0_20 (Sun Microsystems Inc. 16.3-b01) OS: Linux 2.6.18-194.el5 amd64
How does gradle lock “critical” sections ? Is it per-task ? It seems we have an issue in our build where we start gradle from two sub-projects with a common dependency on another subproject that does some code generation. From time to time it seems that we have a collision.
Gradle 2.2.1 is out, but the problem persists so far.