Explain the difference between the settings (initialization) phase and the build (configuration/execution) phases. When does the settings script run relative to build scripts?
answer
- init → configuration → execution
- settings = init phase, once, first
- settings can't see tasks/configurations
- include only works in settings
- settingsEvaluated / projectsLoaded hooks
basics
~10 sGradle runs in three phases: initialization, configuration, execution. The settings script runs in initialization — first, before any build.gradle. It decides which projects exist; build scripts then configure each project during configuration.
solid answer
~40 sA Gradle build has three lifecycle phases. **Initialization** comes first: Gradle finds the build root, evaluates the **settings script** to build the `Settings` object, and creates the `Project` instances for the root and every included project. **Configuration** runs next: every `build.gradle(.kts)` is evaluated to configure its `Project` and register tasks (this happens for all projects, even ones you didn't ask to build). **Execution** runs last: only the tasks needed for the requested goals (and their dependencies) actually run. The key consequence: the settings script executes exactly once, *before* any build script, so it cannot reference task outputs or project configuration — it only declares structure. Anything that depends on which projects exist must live in settings; anything that configures a project lives in its build script.
code
kotlin · 5 lines// settings.gradle.kts — initialization phase
rootProject.name = "shop"
include(":api")
gradle.settingsEvaluated { logger.lifecycle("INIT: settings parsed") }
gradle.projectsLoaded { logger.lifecycle("INIT: ${rootProject.allprojects.size} projects") }go deeper
Name the three phases in order and know settings runs first.
Explain what each phase does, that settings runs once before all build scripts, and why include must live in settings.
Distinguish configuration-time vs execution-time code, cite the lifecycle hooks, and relate the phase model to configuration avoidance.
Discuss how the phase model drives performance strategy (configuration cache, project isolation, configuration-on-demand) across a large monorepo.
## The three phases Every Gradle invocation moves through three phases in strict order: 1. **Initialization phase** — Gradle locates the build root (the directory whose `settings.gradle(.kts)` is in effect), evaluates the **settings script**, and from the resulting `Settings` object instantiates a `Project` for the root project and each `include`d/`includeBuild` project. No build script has run yet. 2. **Configuration phase** — Gradle evaluates **every** project's `build.gradle(.kts)`, building the task graph by *registering* tasks and applying plugins. Crucially this happens for all projects in the build, not just the one you targeted (unless configuration-on-demand or project isolation narrows it). 3. **Execution phase** — Gradle determines the subset of registered tasks required by the requested task names, orders them by dependencies, and runs their actions. ## Where the settings script sits The settings script is the *only* thing that runs in the initialization phase. Therefore: - It runs **exactly once**, **before** any `build.gradle`. - It cannot see tasks, configurations, or anything a build script sets up — those don't exist yet. - It is the *only* place to change the **set of projects** (`include`, `includeBuild`, relocation). You cannot add a project from a build script. ```kotlin // settings.gradle.kts (initialization phase) rootProject.name = "shop" include(":api", ":web") gradle.settingsEvaluated { println("settings done") } // init hook gradle.projectsLoaded { println("projects created") } // end of init // api/build.gradle.kts (configuration phase) — runs LATER tasks.register("hello") { doLast { println("exec phase") } } ``` ## Lifecycle hooks tied to the boundary Gradle exposes hooks at the seams: `gradle.settingsEvaluated` (settings script finished), `gradle.projectsLoaded` (Project objects created — end of init), `gradle.beforeProject`/`afterProject` (around each configuration), and `gradle.buildFinished`. These let you observe the transition from init to configuration. ## Why it matters practically Because settings runs first and once, expensive or environment-sensitive *structure* decisions (which modules to include, where they live) belong there. Conversely, never try to read a project property or task output in settings — it hasn't been configured. Mixing these up is a classic source of "cannot get property" or null errors. ## Configuration vs execution distinction A subtle but commonly tested point: code in the *body* of a build script runs at **configuration** time (for every build, regardless of whether the task runs); code inside `doLast {}` / `doFirst {}` runs at **execution** time, only when the task is actually executed. The settings script body is earlier still — pure initialization.
- Why can't you call include() from a build.gradle?include adds a project to the build, which must happen during initialization while the project set is still being built. By the time a build.gradle runs, the configuration phase has started and the Project instances already exist — the set is frozen.
- Does code in a build script body run during configuration or execution?The script body runs at configuration time, for every build, even if the task never executes. Only code inside task actions (doFirst/doLast) runs at execution time, and only when that task is actually run.
- Which hook fires right after the settings script finishes?gradle.settingsEvaluated fires once the settings script is fully evaluated; gradle.projectsLoaded fires slightly later, after the Project objects are created — both are still in the initialization phase.
saying these in an interview costs you the question
- Saying the settings script runs alongside or after build scripts — it runs strictly before, in initialization.
- Claiming configuration only happens for the targeted project — by default all projects are configured.
- Trying to access task outputs or project properties from the settings script.