--no-daemon switch ineffective if JVM settings cause new fork

If I have the daemon enabled via a global property, and a project properties file that specifies a JVM argument that causes a fork to be required, for instance:


When I run the build, with --no-daemon I see:

To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/2.11/userguide/gradle_daemon.html.

And from ps -ef | grep Gradle:

1638392314 71140 79394   0 10:45AM ttys002    0:01.45 java -Xdock:name=Gradle -Xdock:icon=/usr/local/Cellar/gradle/2.11/libexec/media/gradle.icns -Dorg.gradle.appname=gradle -classpath /usr/local/Cellar/gradle/2.11/libexec/lib/gradle-launcher-2.11.jar org.gradle.launcher.GradleMain --no-daemon
1638392314 71213 71140   0 10:45AM ttys002    0:01.31 /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/bin/java -XX:MaxPermSize=128M -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -cp /usr/local/Cellar/gradle/2.11/libexec/lib/gradle-launcher-2.11.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 2.11

Are you saying Gradle started a new daemon process with the JVM argument declare in the project properties even though you provided the command line args --no-daemon? Did you potentially already have this daemon running before?

That’s right. Definitely no daemons running.

You’ll notice that the --no-daemon launcher is the parent process of the daemon…

It sounds like you’re concerned with an implementation detail that doesn’t have any effect on whether the functionality is working as intended.

If you specify JVM arguments that require forking, Gradle will fork a new JVM. Regardless of whether or not you want a daemon process, the class that runs is called GradleDaemon. The --no-daemon switch should cause the forked process to be single use instead of a long running daemon process, but it’s still going to run the GradleDaemon class.

If you can see the GradleDaemon process once that build completes, then that is a different issue, but not what you described.

1 Like

That’s not quite what I see here, I don’t see any fork in the --no-daemon case, when there aren’t jvm options. The reason I run into this is I set GRADLE_OPTS to debug and profile, and GRADLE_OPTS obviously don’t apply to the fork.

Without jvm options:

1638392314 36993 14375   0  3:39PM ttys001    0:02.78 java -Xdock:name=Gradle -Xdock:icon=/usr/local/Cellar/gradle/2.12/libexec/media/gradle.icns -Dorg.gradle.appname=gradle -classpath /usr/local/Cellar/gradle/2.12/libexec/lib/gradle-launcher-2.12.jar org.gradle.launcher.GradleMain build --no-daemon

With jvm options:

1638392314 36827 14375   0  3:38PM ttys001    0:01.23 java -Xdock:name=Gradle -Xdock:icon=/usr/local/Cellar/gradle/2.12/libexec/media/gradle.icns -Dorg.gradle.appname=gradle -classpath /usr/local/Cellar/gradle/2.12/libexec/lib/gradle-launcher-2.12.jar org.gradle.launcher.GradleMain build --no-daemon
1638392314 36876 36827   0  3:38PM ttys001    0:00.95 /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/bin/java -client -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -cp /usr/local/Cellar/gradle/2.12/libexec/lib/gradle-launcher-2.12.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 2.12

There’s four permutations of the two relevant settings here. I only directly addressed the two permutations that were covered in the original post which was whether the daemon options were behaving correctly when there are JVM arguments. You’re not seeing anything different with the added examples, but just now including additional permutations for without JVM arguments. So for completeness, we can look at all of them.

The below table indicates a true/false value for the two relevant variables (jvmargs and daemon). It doesn’t matter how you have arrived at these values, either through defaults or explicitly setting/overriding the values. The next few values indicate whether a process with the java class name GradleMain or GradleDaemon will start when you start your build and die when your build completes. In these permutations, I’m ignoring the fact that a compatible daemon could already be running for simplicity (and because you said that there isn’t one in your case).

    | jvmargs | daemon | GradleMain starts | GradleDaemon starts | GradleMain dies | GradleDaemon dies |
    | true    | true   | yes               | yes                 | yes             | no                |
 ** | true    | false  | yes               | yes                 | yes             | yes               | **
    | false   | true   | yes               | yes                 | yes             | no                |
  * | false   | false  | yes               | no                  | yes             | n/a               | *

In both of your latest examples, you are specifying --no-daemon, so that’s the second and fourth row of the table. In your first example without JVM options (*), GradleMain will start, but GradleDaemon will not because there’s no need for it. In your second example with JVM options (**), GradleMain will start and GradleDaemon will start with the specified JVM options. This matches what you are showing in your running processes.

1638392314 36827 14375   0  3:38PM ttys001    0:01.23 java -Xdock:name=Gradle -Xdock:icon=/usr/local/Cellar/gradle/2.12/libexec/media/gradle.icns -Dorg.gradle.appname=gradle -classpath /usr/local/Cellar/gradle/2.12/libexec/lib/gradle-launcher-2.12.jar org.gradle.launcher.GradleMain build --no-daemon
1638392314 36876 36827   0  3:38PM ttys001    0:00.95 /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/bin/java -client -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -cp /usr/local/Cellar/gradle/2.12/libexec/lib/gradle-launcher-2.12.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 2.12

Your second line is the forked JVM with your specified JVM options. It is running GradleDaemon (the class), but it is not a daemon process. Once your build completes, both it and GradleMain will die. If you instead specified that you wanted the daemon (first row of the table), the GradleDaemon that you see would continue running as a daemon background after your build completed, and GradleMain died, waiting for the next GradleMain with compatible options to provide some work.