skip to content

Tasks and Task Graph

Tasks as the unit of work: how they are declared, how dependsOn, mustRunAfter, and finalizedBy shape the DAG, and how declared inputs and outputs drive up-to-date checks. The core Gradle topic, since everything else is layered on it.

on this pageshow

explore

questions

103 · 4 sections

What does the Gradle `init` task do, and how do you use it to scaffold a new project?

level: juniorimportance: must knowfreq 55%
basics
~20 s

gradle init is a built-in task from the build-init plugin that scaffolds a new Gradle project: it generates build/settings scripts, a sample source layout, and the Gradle wrapper, prompting you (or via flags) for project type, DSL, and test framework.

open as a page

What is Gradle's Configuration Avoidance API, and what problem does it solve?

level: juniorimportance: must knowfreq 60%
basics
~10 s

It's a set of lazy task APIs (TaskProvider, tasks.named, configureEach) that let Gradle skip creating and configuring tasks you don't run, cutting configuration-time cost.

open as a page

How do you define a task in Gradle that copies files from one directory into another, and what are the core DSL elements you use?

level: juniorimportance: must knowfreq 65%
basics
~10 s

Register a task of type Copy and configure from (source) and into (destination). Gradle copies the matched files into the target directory when the task runs.

open as a page

What is the difference between doFirst and doLast on a task, and in what order do multiple actions run?

level: juniorimportance: must knowfreq 60%
basics
~10 s

doLast adds an action to the end of the task's action list; doFirst adds one to the front. Both run in the execution phase. If you call doFirst twice, the later one runs first.

open as a page

What is an ad-hoc task in Gradle, and how do you define one?

level: juniorimportance: must knowfreq 70%
basics
~10 s

An ad-hoc task is an untyped task of type DefaultTask whose behavior you add inline with doLast { ... }. You register it with tasks.register("name") and put the action in the closure.

open as a page

What does the dependsOn declaration do for a Gradle task, and what is its effect on the build?

level: juniorimportance: must knowfreq 80%
basics
~10 s

dependsOn declares that another task must run before this one. Gradle adds the named task to the build's task graph and executes it first whenever this task is requested.

open as a page

What does finalizedBy do in Gradle, and when would you use it?

level: juniorimportance: must knowfreq 55%
basics
~10 s

finalizedBy declares that a finalizer task must run after a given task, even if that task fails. It's used for cleanup or teardown work, like releasing resources or generating a report after tests.

open as a page

How can you preview the ordered list of tasks Gradle will execute for a given command without actually running them?

level: juniorimportance: must knowfreq 60%
basics
~10 s

Run the build with the --dry-run (-m) flag, e.g. gradle build --dry-run. Gradle resolves and prints the full task execution order with each task marked SKIPPED, but executes nothing.

open as a page

What is the difference between an ordering rule (mustRunAfter/shouldRunAfter) and a task dependency in Gradle?

level: juniorimportance: must knowfreq 70%
basics
~20 s

An ordering rule only fixes the relative order of two tasks IF both already end up in the task graph. It never adds a task to the graph or forces it to run, unlike a dependency, which both pulls a task in and runs it first.

open as a page

What are the different ways to specify the argument to dependsOn, and why is passing a TaskProvider preferred over a task name string?

level: middleimportance: must knowfreq 65%
basics
~20 s

You can pass a task name string, a Task or TaskProvider reference, a Provider, a Collection, or a closure. A TaskProvider is preferred because it is lazy — it doesn't force the other task to be created/configured eagerly.

open as a page

Why would you declare inputs and outputs on an ad-hoc Gradle task using task.inputs and task.outputs?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Declaring inputs/outputs lets Gradle skip the task when nothing changed (up-to-date checking) and reuse cached results. Without them Gradle has no fingerprint, so the task always runs.

open as a page

What does the --rerun-tasks command-line flag do, and when would you reach for it?

level: juniorimportance: must knowfreq 60%
basics
~10 s

--rerun-tasks tells Gradle to ignore up-to-date checks for the whole build and re-execute every task in the requested task graph, even tasks it considers UP-TO-DATE. Useful to force a clean re-run while debugging.

open as a page

When you run a Gradle build and see a task labeled UP-TO-DATE in the output, what does that tell you and why did it happen?

level: juniorimportance: must knowfreq 78%
basics
~10 s

UP-TO-DATE means Gradle skipped running the task because its inputs and outputs haven't changed since the last run, so re-executing would produce identical results.

open as a page

How do you make a Gradle task always run (never be considered up-to-date), and when would you do that?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Add outputs.upToDateWhen { false } to the task. The predicate always returns false, so Gradle never treats the task as up-to-date and runs it every build. Useful for tasks with side effects Gradle can't track.

open as a page

What is the difference between inputs.property(...) and inputs.file(...) on an ad-hoc task, and when do you use each?

level: middleimportance: must knowfreq 55%
basics
~10 s

inputs.file declares a file/path whose contents are fingerprinted. inputs.property declares a non-file value (string, number, flag) compared by its serialized value. Use file for file inputs, property for config values.

open as a page

In a Gradle task definition, what is the difference between code in the configuration block and code inside doFirst{}/doLast{}, and when does each run?

level: juniorimportance: must knowfreq 80%
basics
~10 s

Configuration-block code runs during the configuration phase for every build invocation. doFirst{}/doLast{} are action closures that run only in the execution phase, and only if the task actually executes.

open as a page

What does task.onlyIf {} do in Gradle, and what happens to a task whose onlyIf predicate returns false?

level: juniorimportance: must knowfreq 70%
basics
~10 s

onlyIf {} attaches a predicate evaluated right before the task runs. If it returns false, Gradle skips the task's actions and reports it as SKIPPED. If true (or absent), the task executes normally.

open as a page

What is the difference between the tasks a user requested on the command line and the tasks Gradle actually schedules and executes?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Requested tasks are the names you type on the command line (e.g. gradle build). Executed tasks are those plus all their dependencies, which Gradle computes and runs in dependency order.

open as a page

What is gradle.taskGraph.whenReady{} and when does the closure it registers actually run?

level: juniorimportance: must knowfreq 55%
basics
~10 s

whenReady registers a callback that runs once Gradle has finished building the task execution graph for the build, after configuration but before any task executes.

open as a page

How do doFirst{} and doLast{} compose into a task's action list, and what is the execution order if you call them multiple times?

level: middleimportance: must knowfreq 65%
basics
~20 s

A task holds an ordered list of actions. doLast appends to the end; doFirst prepends to the front. Multiple doFirst calls stack so the last-added doFirst runs first; doLast actions run in the order added.

open as a page