Gradle considers tasks up-to-date even if implementation of the task's type has changed

It seems that Gradle considers tasks up-to-date even if the implementation of the task’s type in buildSrc changed after the last task execution.

The following small example that illustrates this behavior: build.gradle:

import test.HelloWorldTask
task test(type: HelloWorldTask) {
 greetingFile = file('someFile')
 output = file('someDir')
}

HelloWorldTask.groovy in buildSrc (omitting imports and package declaration):

public class HelloWorldTask extends DefaultTask {
 @InputFile File greetingFile;
 @OutputDirectory File output;
   @TaskAction
 public void greet() {
  println "hello ${greetingFile.name}"
 }
}

After executing task ‘test’ once, it is considererd up-to-date in following Gradle executions even if HelloWorldTask.groovy is changed. Is this behavior intended?

My goal is that after every change of my task implementations, at least the corresponding tasks are no longer considered up-to-date. (The person executing the build might not know that buildSrc changed, and, hence, will probably not force Gradle to consider the task out-of-date.) Is it possible to achieve this goal, e.g., by specifying the buildSrc as a task input, such that the task will not be skipped after changing the implementation of the task’s type in buildSrc?

It’s a known limitation, and there isn’t currently an easy way to overcome it.

I’ve raised GRADLE-2936 for this issues: it’s been a known issue for a while but I couldn’t locate anything in Jira.

This issue will be fixed in Gradle 3.0.