Resetting Property Value Between Gradle Tasks in Custom Plugin

Hi everyone,

I’m writing a custom Gradle plugin and have encountered an issue with storing properties between tasks. I have created an object within my plugin to store properties that can be modified by tasks. Here’s a simplified version of my code:

class MyPlugin : Plugin<Project> {
    companion object {
        var myProperty: String = ""
    }

    override fun apply(project: Project) {
        ...

One of the task change this object’s property “myProperty” using option

abstract class MyTask1 : DefaultTask(){
 @Option(
        option = "sub-path",
        description = "some-description",
    )
    fun setSubPath(subPath: String) {
        myProperty = subPath
    }
     @TaskAction
     fun action(){
         println(myProperty) 
   }
        ...

No other task depends upon above Task.
Now suppose, I have other task which do something.

abstract class MyTask2 : DefaultTask(){
  
     @TaskAction
    fun action(){
         println(myProperty) 
   }
        

When I run MyTask1 with the option --sub-path=pizza, it prints pizza, as expected. However, when I subsequently run MyTask2, it also prints pizza but I would like MyTask2 to use an empty string instead of the property set by MyTask1.
What I want is to if they run together then it should be behave as exactly like they are supposed to do but if one of task run separately (most probably Task2) , it should use default value.
How can I ensure that MyTask2 uses an empty string (or any default value) for myProperty instead of the value set by MyTask1? Is there a way to reset the property or achieve this behavior within the Gradle plugin framework?

Having such a property in a companion object is effectively having static state.
Static state is very often a very bad idea in the JVM world.
For Gradle plugins this is especially bad, as this means that the state is preserved throughout build executions and could even pollute other projects built on the same Gradle daemon that use the same plugin.

If you really need state that is shared between tasks at execution time and should be scoped to one build execution, you should use a shared build service to hold the state: Using Shared Build Services

But actually, often such a need is more a sign of doing something fishy. :slight_smile:

Thanks for the reply. For such requirement my thought process was. As all tasks need to do something at start. So instead of doing same thing again and again its better to my first does and store it in the plugin object and other tasks access this object to get the calculated value. I tried tasks’s input and output but couldn’t succeed actually, couldn’t understand fully from the docs. I ain’t doing fishy just learning :slight_smile:

To do it with task output and inputs, the result has to be a file output that can then be consumed by the other tasks’ inputs.

For non-file, as I said, a shared build service would be the proper state holder.
Or if it does not have to be done by a task, the service could also do the actual calculation, depending on what has to happen there.