What causes task "class path has changed from" in up-to-date checks?

I have a couple tasks that I’m trying to set up as incremental using inputs and outputs. Following a clean, the task runs as expected, and produces the correct output. When I run it a second time using the -i flag it runs again, this time saying it’s due to “class path has changed from” with two hash strings.

This seems to be coming from TaskTypeTaskStateChanges, specifically taskClassLoaderHash.equals(previousExecution.getTaskClassLoaderHash(), but it’s not clear to me what’s changing about my classloader/class path that would cause this.

When it runs the third time, it correctly says it’s up-to-date. Any thoughts?

It’s even weirder than I thought. Sometimes I run a clean, then a regular build. Following that regular build I’ll re-run the build with the -i flag and gradle will re-run some tasks saying there’s no history. How can there be no history if I just ran the task?

Hi Mike,

the classpath for a task would change if you change for example the Gradle or Java version, edit a file in buildSrc or change a build script containing a Task class. The last class path is recorded when the task was last executed - so running a clean in between has no effect on what the last recorded class path was.
Regarding tasks with no history: could you give an example which task types are you talking about?


There were definitely no changes happening to the scripts during testing. My process was edit, clean, build, and build again, hoping that the second build would be up-to-date. That definitely wasn’t happening, but based on what you wrote it seems like it should. The tasks were consistently saying that the class path had changed. The ‘clean’ was because the edits I was making were to the inputs/outputs and I was testing them to make sure they were having the effect I wanted.

Interestingly, all the tasks suffering from this were of type ParallelExec which is a custom task I had defined inside that build file as follows:

class ParallelExec extends Exec {}

I moved that task type definition into buildSrc, and now that issue has gone away. I no longer get the “class path has changed” issue.

However, now I’m getting the “no history” issue more and more. All of these are the aforementioned ParallelExec task, which is still defined as shown above, but is now in buildSrc. All of these have inputs and outputs defined.

Very inconsistent, too. Sometimes it works exactly as you’d expect (everything’s up-to-date after one build) and sometimes one or two tasks will re-run due to gradle saying there’s no history.

I’ve disabled the parallel flags to get everything to run serially and that didn’t help. Same thing.

Hi Mike,

could you give me some logs or a reproducible example? Can you share the task implementations? For the task implementations the input/output declarations should be enough, I would not need the task action.


Thanks for the response.

I’m going to try to reduce this to a reproducible project and I’ll update this thread then.