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 pageshowhide
explore
- Build Lifecycle Phases27 questions
- Initialization Phase5 questions
- Configuration Phase5 questions
- Execution Phase6 questions
- Task Graph (DAG) Construction6 questions
- Configuration Avoidance API5 questions
- Lifecycle Hooks and Listeners20 questions
- Project Evaluation Hooks5 questions
- Build Completion Hooks5 questions
- Lifecycle and Task Listeners5 questions
- BuildService for Shared State5 questions
- Command-Line Invocation31 questions
- Task Selectors and Matching5 questions
- Project and System Properties5 questions
- Execution Control Flags6 questions
- Logging and Diagnostic Flags5 questions
- Diagnostic Report Tasks5 questions
- Continuous Build and File Watching5 questions
- Daemon Invocation15 questions
- What Is the Gradle Daemon5 questions
- Daemon Discovery and Spawning5 questions
- Daemon Management Commands5 questions
questions
93 · 4 sectionsDuring which build phase does the cost of eager task configuration occur, and how does the Configuration Avoidance API reduce that cost?
basics
~10 sThe 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.
What happens during Gradle's configuration phase, and what is its output?
basics
~20 sGradle 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.
What happens during Gradle's Execution phase, and how does it differ from the Configuration phase?
basics
~20 sExecution 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.
What happens during Gradle's initialization phase, and how does it differ from the configuration phase?
basics
~10 sInitialization 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.
What is the task execution graph in Gradle, and at what point in the build lifecycle is it constructed?
basics
~10 sIt'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.
How do you run code after a Gradle build finishes, and what does gradle.buildFinished give you access to?
basics
~20 sRegister 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.
At a high level, what is the build configuration phase, and where do project evaluation hooks like afterEvaluate fit within it?
basics
~20 sThe 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.
How does a BuildService perform cleanup at the end of a build, and what makes this a lifecycle hook?
basics
~10 sMake 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.
What is a Gradle BuildService, and why would you use one to hold state that is shared across tasks during a build?
basics
~20 sA 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.
What is project.afterEvaluate used for, and why would you defer configuration logic into it instead of writing it directly in the build script?
basics
~20 safterEvaluate 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.
What is Gradle's continuous build (-t/--continuous), and how does it differ from running a task once?
basics
~10 sContinuous 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.
What does the built-in `dependencies` task do, and how do you scope it to a single configuration?
basics
~10 sgradle 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.
How do you exclude a specific task from a Gradle build invocation, and what exactly does excluding it do to its dependencies?
basics
~10 sUse -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.
Which command-line flags control Gradle's log verbosity, and how do they relate to one another?
basics
~10 sUse --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.
What is the difference between passing -Pname=value and -Dname=value on the Gradle command line?
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.
When you run a Gradle command, how does Gradle decide whether to reuse an existing daemon or start a new one?
basics
~10 sThe 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.
What is the Gradle Daemon, and why does Gradle use it by default?
basics
~20 sThe 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.
How do you inspect which Gradle daemons are running and how do you stop them from the command line?
basics
~10 sRun 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.
What makes a running daemon 'compatible' with an invocation? Which factors must match?
basics
~10 sCompatibility 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.
Describe the client/daemon split in a Gradle invocation. What does each side do?
basics
~20 sEvery 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.