Persistent data in daemon mode when accessed by metaclass method

Gradle Version: 2.14.1
Operating System: Debian Linux x64
Is this a regression? If yes, which version of Gradle do you know it last worked for? Not that I know of. Originally tried in 2.12, happened there too.


I’m not certain this is a bug, but it seems like it. The following script when run in daemon mode retains the value of test, so each execution increases it:

def test = 0

Task.metaClass.bar = {
    println test++
}

defaultTasks 'foo'
task foo {
    bar()
}

When run:

$ /tmp/gradle-2.14.1/bin/gradle --daemon
Starting a new Gradle Daemon for this build (subsequent builds will be faster).
0
:foo UP-TO-DATE

BUILD SUCCESSFUL

Total time: 6.04 secs
$ /tmp/gradle-2.14.1/bin/gradle --daemon
1
:foo UP-TO-DATE

BUILD SUCCESSFUL

Total time: 1.675 secs
$ /tmp/gradle-2.14.1/bin/gradle --daemon
2
:foo UP-TO-DATE

BUILD SUCCESSFUL

Total time: 1.573 secs

Obviously this doesn’t happen without the daemon. It also doesn’t happen if bar is a regular function instead of a method attached to Task. If I print test from the task, it stays 0, so it seems like bar is accessing some copy of the data that persists from run to run. I don’t know enough Gradle/Groovy to understand exactly what’s happening

Gradle caches classloaders across invocations for increased performance. Therefore any static state needs to be handled with caution.