In a settings script, where do dependencyResolutionManagement {} and pluginManagement {} sit relative to each other and to plugins/include, and why does ordering matter?
answer
- pluginManagement first (hard rule)
- before settings plugins {}
- DRM after pluginManagement, before include
- declare-before-consume lifecycle
- projects configured after settings
basics
~10 sBoth are top-level settings blocks. pluginManagement {} must come first (before the plugins {} block if used), and dependencyResolutionManagement {} comes before rootProject.name/include. Ordering reflects when each must be configured during settings evaluation.
solid answer
~40 sThe settings script is evaluated top-to-bottom, and Gradle imposes positional constraints. `pluginManagement {}` must be the **first** block — it has to be configured before any `plugins {}` block in settings can resolve, since it tells Gradle where settings plugins come from. `dependencyResolutionManagement {}` is also a top-level block; conventionally it follows `pluginManagement {}` and precedes the project structure (`rootProject.name`, `include(...)`). The reason is lifecycle: repositories, `repositoriesMode`, and version catalogs declared here must be in place *before* projects are included and configured, because every project inherits them. Putting `include(...)` first still works for the include itself, but the clean, idiomatic order is pluginManagement → (settings plugins) → dependencyResolutionManagement → rootProject.name → include. This isn't arbitrary style: pluginManagement genuinely must precede settings `plugins {}`, and resolution management must be established before project configuration consumes it.
code
kotlin · 10 lines// settings.gradle.kts — idiomatic ordering
pluginManagement { /* plugin repos */ }
plugins { /* settings plugins */ }
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { mavenCentral() }
versionCatalogs { create("libs") { from(files("gradle/libs.versions.toml")) } }
}
rootProject.name = "my-app"
include("app", "core")go deeper
Know both are top-level settings blocks and pluginManagement comes first.
Explain the canonical order and that settings evaluates top-to-bottom.
Distinguish the enforced pluginManagement-first rule from the lifecycle-driven (declare-before-consume) placement of dependencyResolutionManagement.
Codify settings-script conventions across many repos and explain the lifecycle reasoning to standardize team templates.
## Settings evaluation is ordered `settings.gradle.kts` runs once, top to bottom, on Gradle's `Settings` object. A few blocks have *hard* positional rules; others are convention driven by lifecycle. ## The hard rule: pluginManagement first `pluginManagement {}` configures where plugins are resolved from. If your settings script *also* applies plugins via a settings-level `plugins {}` block, Gradle needs the pluginManagement configuration already in place to resolve them. Therefore `pluginManagement {}` must appear **before** any `plugins {}` block — in practice, it is the first thing in the file. Violating this produces an error that pluginManagement must be the first block. ## dependencyResolutionManagement and lifecycle `dependencyResolutionManagement {}` is a top-level block too, but its constraint is softer and lifecycle-driven: everything it declares (centralized `repositories`, `repositoriesMode` policy, `versionCatalogs`) is consumed when *projects* are configured. Projects are configured after settings finishes, so technically the block can sit anywhere among the top-level statements. The **idiomatic** placement is right after `pluginManagement {}` and before `rootProject.name`/`include(...)`, so a reader sees policy first, structure second. ## Canonical order ```kotlin // settings.gradle.kts pluginManagement { repositories { gradlePluginPortal() mavenCentral() } } plugins { // settings plugins, e.g. id("org.gradle.toolchains.foojay-resolver-convention") } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() } versionCatalogs { create("libs") { from(files("gradle/libs.versions.toml")) } } } rootProject.name = "my-app" include("app", "core") ``` ## Why interviewers ask this It tests whether you understand that settings has a lifecycle, not just a bag of blocks. The load-bearing fact is the pluginManagement-first rule; the rest is idiomatic ordering driven by 'declare before consume.' ## Scope boundary This is about *structural placement* of the block within the settings script. The internals of pluginManagement's own repositories and of version-catalog data are owned by their respective topics.
- Which placement rule is actually enforced by Gradle versus conventional?pluginManagement {} must be first (enforced — it errors otherwise, and it must precede any settings plugins {} block). dependencyResolutionManagement {} placement is conventional/lifecycle-driven rather than hard-enforced, since projects consume it later.
- Why does dependencyResolutionManagement need to be in place before projects, not before include()?include() just registers a project path; the centralized repositories and catalogs are consumed when each project is configured, which happens after settings completes — so the declaration just needs to exist by then.
saying these in an interview costs you the question
- Saying dependencyResolutionManagement must literally be first (that is pluginManagement).
- Claiming order never matters at all (pluginManagement-first is enforced).
- Putting a settings plugins {} block before pluginManagement {}.