skip to content

Lifecycle and Execution Model

Gradle's execution model end to end: the initialization, configuration, and execution phases, the lifecycle hooks around them, command-line invocation, and the daemon that runs everything. Interviewers ask because almost every Gradle mistake is really a phase mistake.

on this pageshow

explore

questions

93 · 4 sections

During which build phase does the cost of eager task configuration occur, and how does the Configuration Avoidance API reduce that cost?

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

The configuration phase runs every build and configures all tasks. Configuration Avoidance (tasks.register) defers a task's configuration until something actually needs it, so unused tasks are never configured.

open as a page

What happens during Gradle's configuration phase, and what is its output?

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

Gradle evaluates every project's build script top to bottom, running the build-script code to register and configure tasks. The output is the task model — the set of tasks Gradle knows about and how they depend on each other.

open as a page

What happens during Gradle's Execution phase, and how does it differ from the Configuration phase?

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

Execution is the third (last) phase. Gradle runs the @TaskAction methods of the selected tasks in dependency order. Configuration, the earlier phase, only builds task objects and wires their dependencies — it does no actual work.

open as a page

What happens during Gradle's initialization phase, and how does it differ from the configuration phase?

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

Initialization runs first: Gradle evaluates settings.gradle(.kts) to learn which projects exist (via include), then creates a Project object for each. Configuration runs next, executing each project's build.gradle to register tasks.

open as a page

What is the task execution graph in Gradle, and at what point in the build lifecycle is it constructed?

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

It's a directed acyclic graph (DAG) of the tasks Gradle will run for the requested build, ordered by their dependencies. Gradle builds it after the configuration phase finishes and before execution starts.

open as a page

How do you run code after a Gradle build finishes, and what does gradle.buildFinished give you access to?

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

Register a callback with gradle.buildFinished { result -> ... }. It runs once the build ends and gives you a BuildResult with result.failure, so you can do cleanup or reporting whether the build passed or failed.

open as a page

At a high level, what is the build configuration phase, and where do project evaluation hooks like afterEvaluate fit within it?

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

The configuration phase is when Gradle reads every project's build script and registers tasks (but doesn't run them). Project evaluation hooks like afterEvaluate run at the tail of this phase, right after a project's script has been read.

open as a page

How does a BuildService perform cleanup at the end of a build, and what makes this a lifecycle hook?

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

Make the service implement AutoCloseable. Gradle calls close() automatically when the build finishes, so you can stop a server or flush a buffer there. You never call close() yourself.

open as a page

What is a Gradle BuildService, and why would you use one to hold state that is shared across tasks during a build?

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

A BuildService is an object Gradle creates lazily and shares across tasks in a build. It holds state (a counter, a connection pool) safely, lives for the whole build, and Gradle closes it at build end.

open as a page

What is project.afterEvaluate used for, and why would you defer configuration logic into it instead of writing it directly in the build script?

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

afterEvaluate registers a callback that runs after a project's build script has finished being evaluated. You use it when your logic depends on values (like extension properties) that are only set later in that script.

open as a page

What is Gradle's continuous build (-t/--continuous), and how does it differ from running a task once?

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

Continuous build runs gradle -t <task> (or --continuous). Gradle stays alive, watches the task inputs, and automatically re-runs the requested tasks whenever a relevant input file changes, instead of exiting after one run.

open as a page

What does the built-in `dependencies` task do, and how do you scope it to a single configuration?

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

gradle dependencies prints the resolved dependency trees for each configuration. Use --configuration <name> (e.g. runtimeClasspath) to limit the output to one configuration instead of dumping every one.

open as a page

How do you exclude a specific task from a Gradle build invocation, and what exactly does excluding it do to its dependencies?

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

Use -x or --exclude-task with the task name, e.g. gradle build -x test. Gradle removes that task — and any task needed only by it — from the execution graph for this run.

open as a page

Which command-line flags control Gradle's log verbosity, and how do they relate to one another?

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

Use --quiet (-q) for less output, --info (-i) for more, and --debug (-d) for everything. They set the log level; only one applies, with --debug the most verbose and --quiet the least.

open as a page

What is the difference between passing -Pname=value and -Dname=value on the Gradle command line?

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

-P sets a Gradle project property, read via project.property("name"). -D sets a JVM system property, read via System.getProperty("name"). -P is Gradle-specific; -D is standard JVM.

open as a page

When you run a Gradle command, how does Gradle decide whether to reuse an existing daemon or start a new one?

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

The Gradle client looks for an idle, compatible daemon already running. If it finds one, it reuses it; otherwise it spawns a fresh daemon process and connects to that.

open as a page

What is the Gradle Daemon, and why does Gradle use it by default?

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

The Gradle Daemon is a long-lived background JVM that stays running between builds. Your gradle command is a thin client that hands the build to it. It speeds up builds by reusing a warm, already-started JVM instead of starting a fresh one each time.

open as a page

How do you inspect which Gradle daemons are running and how do you stop them from the command line?

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

Run gradle --status to list daemons and their state, and gradle --stop to gracefully stop all idle and compatible daemons started by the current Gradle version.

open as a page

What makes a running daemon 'compatible' with an invocation? Which factors must match?

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

Compatibility is mainly about the JVM: the daemon must use the same Java home (JAVA_HOME) and have JVM arguments that satisfy the request. The Gradle version must also match.

open as a page

Describe the client/daemon split in a Gradle invocation. What does each side do?

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

Every gradle run has two parts: a short-lived client that parses arguments and forwards the build request, and a long-lived daemon JVM that actually runs the build. The client streams console output back; the daemon does the work and stays alive afterward.

open as a page