onlyIf with TaskProvider and configuration cache


I wrote a Java plugin that registers a task “customTask” having an onlyIf spec that depends on another task.

project.getTasks.register("customTask", CustomTask.class, task -> {
    // ... define group, inputs, outputs, etc.
    task.setOnlyIf(t -> t.getProject().getTasks().named("anotherTask", <boolean predicate>).orElse(false));

Without the configuration cache, the task is executed or skipped as expected depending on the result of the onlyIf spec at execution time.
With the configuration cache, the build fails with the following error:

1 problem was found storing the configuration cache.
- Task `:aTask` of type `...`: cannot serialize object of type 'org.gradle.api.internal.tasks.DefaultTaskContainer', a subtype of 'org.gradle.api.tasks.TaskContainer', as these are not supported with the configuration cache.

How can I register a task with a conditional execution (onlyIf) that depends on a predicate based on another task, and compatible with the configuration cache?

Thanks in advance for your help.

Can you elaborate a bit on what you do with that other task / draw from that other task?
Your example is a bit too condensed to really be helpful in understanding your issue, especially as it does not look like it would be near to compilable. :slight_smile:

Hi @Vampire,

Thank you for your answer. I found another way to skip the task I was talking about without relying on an input/output of an other task.

I don’t understand why the configuration cache is sensitive/uses the onlyIf spec during its serialization. The javadoc about the onlyIf method states the spec is run at execution time, not at configuration. It appears inconsistent to me.

Am I missing something about the configuration cache and/or this spec?

You are right, that onlyIf is run at execution time, that’s exactly your problem.
If it would run at configuration time, the CC could just serialize the result.
But as it runs at execution time, it needs to serialize the action you give to it, the lambda.
And in serializing that action it also needs to serialize the things from outside that it refers to like the project or the tasks container and there you have things that are not CC-safe.

Ok, I think I understand my mistake. That may be obvious but that was not for me until now:

  • The onlyIfmethod is another configuration option, and as such, its value is serialized in the configuration cache.
  • But the onlyIf value (the spec) is run at execution time.

Thanks @Vampire for your help.

1 Like