# finalizedBy tasks runs even though the original task is UP-TO-DATE

**URL:** <https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150>\
**Category:** Help/Discuss\
**Created:** [October 19, 2018, 2:07pm UTC](https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150 "2018-10-19T14:07:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![eekboom](https://avatars.discourse-cdn.com/v4/letter/e/35a633/32.png) [@eekboom](https://discuss.gradle.org/u/eekboom)\
**Post date:** [October 19, 2018, 2:07pm UTC](https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150/1 "2018-10-19T14:07:29Z")

</div>

gradle runs a task specified in “finalizedBy”, even though the original task is UP-TO-DATE!  
That seems contrary to the docs at  
[https://docs.gradle.org/current/userguide/more\_about\_tasks.html#sec:finalizer\_tasks](https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:finalizer_tasks)  
where it says

> On the other hand, finalizer tasks are not executed if the finalized task didn’t do any work, for example if it is considered up to date or if a dependent task fails.

For testing:  
Using gradle 4.10.2:  
mkdir testapp  
cd testapp  
gradlew init --type=application  
Then add this to the build.gradle:

```
check.finalizedBy("finalizeCheck")
task finalizeCheck {
    doLast {
        logger.warn('check has run')
    }
}

```

Now every execution of “gradlew build” will print “check has run” even if no files have been changed in between.

The build output (when started with “-i”) contains

> > Task :check UP-TO-DATE  
> > Skipping task ‘:check’ as it has no actions.  
> > :check (Thread[Task worker for ‘:’,5,main]) completed. Took 0.0 secs.  
> > :finalizeCheck (Thread[Task worker for ‘:’ Thread 7,5,main]) started.
> 
> > Task :finalizeCheck  
> > Task ‘:finalizeCheck’ is not up-to-date because:  
> > Task has not declared any outputs despite executing actions.  
> > check has run  
> > :finalizeCheck (Thread[Task worker for ‘:’ Thread 7,5,main]) completed. Took 0.0 secs.

---

<div class="post-metadata">

**Author:** ![hdecarne](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/hdecarne/32/7350_2.png) [@hdecarne](https://discuss.gradle.org/u/hdecarne)\
**Post date:** [October 20, 2018, 8:56am UTC](https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150/2 "2018-10-20T08:56:48Z")

</div>

The important detail is:

> [@eekboom](#):
>
> > …  
> > Task ‘:finalizeCheck’ is not up-to-date because:  
> > Task has not declared any outputs despite executing actions.  
> > …

Gradle cannot determine whether your finalizeCheck task is up-to-date. You either have to define a task output or a custom up-to-date check (e.g. via [onlyIf](https://docs.gradle.org/current/dsl/org.gradle.api.Task.html#org.gradle.api.Task:onlyIf(groovy.lang.Closure))).

---

<div class="post-metadata">

**Author:** ![eekboom](https://avatars.discourse-cdn.com/v4/letter/e/35a633/32.png) [@eekboom](https://discuss.gradle.org/u/eekboom)\
**Post date:** [October 22, 2018, 10:10am UTC](https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150/3 "2018-10-22T10:10:56Z")

</div>

Holger, I understand your answer and yes, if the “finalizeCheck” task would be up-to-date itself, then it would not be executed.

Still that does not make any sense in the context of the “finalizedBy” and makes the feature completely useless.  
If I want to have a task that _always_ runs when “check” is executed, I can just make check depend on my task - or in this case, just add the “doLast” to “check” itself.

And it still contradicts the documentation that says

> On the other hand, finalizer tasks are not executed if the finalized task didn’t do any work, for example if it is considered up to date or if a dependent task fails.

Note that it does **not** say that

> “finalizer tasks are not executed if **they are up-to-date themselves** and the finalized task didn’t do any work, for example if it is considered up to date or if a dependent task fails.”

So if the “finalizedBy” cannot be used to execute another task if-and-only-if a task has been executed, how can that be achieved by other means?

---

<div class="post-metadata">

**Author:** ![hdecarne](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/hdecarne/32/7350_2.png) [@hdecarne](https://discuss.gradle.org/u/hdecarne)\
**Post date:** [October 22, 2018, 8:07pm UTC](https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150/4 "2018-10-22T20:07:25Z")

</div>

Hi Stephen, you are right. The documentation implies another behavior.  
However the specific feature of finalizedBy from my point of view is that you can adapt the task chain without adapting one of the involved tasks (the finalized ones as well as depending ones).

Regarding your last point. To make sure the finalizer tasks runs only in case the finalized task run you can connect their upToDate states:

```
check.finalizedBy("finalizeCheck")
task finalizeCheck {
	outputs.upToDateWhen { check.state.upToDate }
    doLast {
        logger.warn('check has run')
    }
}
```

---

<div class="post-metadata">

**Author:** ![eekboom](https://avatars.discourse-cdn.com/v4/letter/e/35a633/32.png) [@eekboom](https://discuss.gradle.org/u/eekboom)\
**Post date:** [October 22, 2018, 9:54pm UTC](https://discuss.gradle.org/t/finalizedby-tasks-runs-even-though-the-original-task-is-up-to-date/29150/5 "2018-10-22T21:54:09Z")

</div>

Thanks a lot - that works nicely.  
You can see my actual use case in my next question at [Challenge: Seamless execution of both JUnit and TestNG tests?](https://discuss.gradle.org/t/challenge-seamless-execution-of-both-junit-and-testng-tests/29173)  
Unfortunately another problem remains to be solved, feel free to take a look 😁
