Lifecycle tasks not calling overwritten tasks

It looks like there is a bug in the lifecycle tasks in the Java plugin, specifically the “build” task. If I overwrite the “test” task from the Java plugin and execute “gradle test”, Gradle correctly calls my overwritten version of the task. However, if I execute “gradle build” my overwritten version of the “test” task is not called.

That’s how it’s currently designed to work, although it would sometimes be useful if dependencies were rebound to the overwriting task.

This changed from 1.2 to 1.3 and blew our entire system out of the water. It should probably not work this way.

That’s surprising. I don’t think I’ve ever seen it rebind dependencies.

I’ve investigated this some more, and found the commit responsible for the changed behavior between 1.2 and 1.3. Bottom line is, it all depends on when the task dependency gets resolved, and it was never safe to rely on it being bound to the overwriting task. It would probably make a good feature, though.

As of today, the only way to make sure that task dependencies stay intact is to replace the task’s actions, rather than the task itself. Of course this means that the task type can’t be changed, but often that won’t matter.

If you control the code that adds the task dependency, you can make sure that it gets resolved late by using a ‘String’ (‘foo.dependsOn(“bar”)’) rather than a ‘Task’ (‘foo.dependsOn(bar)’).

I think Gradle should provide a predictable experience when overwriting a task, either always or never rebinding dependencies to the new task (or making it configurable). Hence I’ve created GRADLE-2607.

On a separate note, it would be easy to bring back the 1.2 behavior when overwriting the ‘test’ task. But as things stand today, I consider this an implementation detail that shouldn’t be relied upon. I’ll get a discussion going on how to proceed.

This doesn’t appear to work, so I’m not sure how to fix this in 1.3:

test.actions.clear() test << {

System.err.println(“Testing”) }

The same behavior occurs where if you call test directly, it works fine. However, if I call build, the now always says “:test UP-TO-DATE” and doesn’t execute the test task. Some seriously strange behavior that is not obvious or easy to fix using the documentation (both the manual and the DSL reference).

It’s simply the up-to-date behavior of a ‘Test’ task. You’d have to unset properties like ‘test.classpath’, but it won’t be fun. It’s best to avoid overwriting altogether.