Gradle cannot overwrite task with overwrite:true

i want to create a build.gradle file which will load another into it.

The second file just should have the "defaulttasks" which means that they should execute when the task doens't exist in the first one.

File one:

apply from ("..otherfile.gradle")
task "hello"(overwrite: true) {
  doFirst{
    println "hello from here"
  }
}

The second file:

task "hello" {
  doFirst{
    println "i am the old one"
  }
}

When I run this it, it fails

Caused by: java.lang.IllegalStateException: Replacing an existing task that may have already been used by other plugins is not supported. Use a different name for this task ('hello').

So i tried and changed the second file instead of task to tasks.register("hello")

After that it doesn't fail but it will execute the second also. How can i override a task so that the default task is not running anymore?


For me even shorter solution is working than @dpr suggested. You can avoid disabling the task and adding dependsOn task. With never version 6.8.2 I can confirm that that the solution provided by @tim_yates doesn't work out for me. Even if in script plugin task is added with .register() method the exception is thrown.

Now to overwrite method I reconfigure the existing task from script plugin like following:

tasks.hello.configure {
  actions.clear()
  doLast {
    println("")
    println("Action new")
    println("")
  }
}

Action list is cleared so all of the previous tasks are removed, and then you can define whatever you would like to be executed when the task will be triggered.


I tried the workaround proposed by @tim-yates to overwrite a task defined in a plugin. With gradle 6.6.1 I got this error:

Replacing an existing task that may have already been used by other plugins is not supported.

I was able to achieve the desired behaviour by skipping the respective task's execution and making it dependent on the new task:

task helloHere() {
  doFirst {
    println "hello from here"
  }
}

tasks.hello.configure {
  dependsOn helloHere
  onlyIf { false }
}

That is if the hello task is executed, the helloHere task runs first and the hello task is SKIPPED making it a noop.

Yes this is kind of hackish but might come in handy if needed.


Replacing tasks that were fully realised was deprecated in Gradle 5, and removed in Gradle 6 so I'm afraid this is no longer possible.

However, if you use the lazy register method of the tasks task container, you can do the following

build.gradle

apply(from: "otherfile.gradle")

tasks.replace("hello").configure {
    actions.clear()
    doFirst{
        println "hello from here"
    }
}

otherfile.gradle

tasks.register("hello") {
    doFirst{
        println "i am the old one"
    }
}

Not sure replacing tasks makes anything easier to reason about, so I'd avoid it if you can 🤔