War plugin causes continuous to run continuously

When I add in the war plugin, it causes the continuous build (-t) to watch the build directory so it runs over and over and over never ceasing.

Here are the exact steps to repeat this with as few variables as possible:

  1. Make a clean/empty/new directory (test_dir)
  2. In that directory run gradle init --type java-library
  3. Immediately run the wrapper in continuous mode: ./gradlew -t clean build
  4. This is successful
  5. Open the build.gradle and insert apply plugin: 'war' below the apply plugin: 'java' line.
  6. Run ./gradlew -t clean build and this time you should see it continuously run and never stop

Total time: 4.388 secs

Waiting for changes to input files of tasks... (ctrl-d to exit)
new directory: /path/to/test_dir/build/classes/test
new file: /path/to/test_dir/build/classes/test/LibraryTest.class
Change detected, executing build...

------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------

Build time:   2016-04-25 04:10:10 UTC
Build number: none
Revision:     3b427b1481e46232107303c90be7b05079b05b1c

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_66 (Oracle Corporation 25.66-b17)
OS:           Mac OS X 10.11.1 x86_64

Side note: This is my first post so I don’t know what tags to put here. Open to suggestions.

Hi,

Thanks for your well defined problem report.

There is a known limitation in continuous build that it might trigger a second build when the build directories are “clean”.
For your use case, the workaround is simply to not use “clean” in the targets of the continuous build.

We added the feature to watch for changes that happen during the build in Gradle 2.11 . The “second build getting triggered” problem appears with this feature.

When the task’s input directory doesn’t exist, Gradle cannot watch the directory directly. It has to watch for the directory to get created in the parent directory and if the parent directory doesn’t exist, it first has to wait for that to get created (and so on). This makes things complicated.

Some of the “second build getting triggered” problems appear only on Mac OS X, because the JDK WatchService implementation uses polling on Mac OS X. On Linux or Windows a native file watching implementation is used and the “delayed view” of the file system doesn’t cause problems there. Windows file watching has the ability to watch for a whole file tree (unlike the Linux WatchService) and that causes some other concurrency problems in the change detection.

The fix for the “second build getting triggered” problem in Gradle would be to not watch for intermediate task input directories for changes and only watch for “edge” input directories for changes. In this case the jar/war task are tasks that have intermediate input directories under the “build” directory. However this fix hasn’t been scheduled to be implemented yet.

Lari

The existing jira issue for the “second build getting triggered” problem is GRADLE-3425 .