skip to content

Where can repository content filtering be declared, and how does it interact with centralized dependencyResolutionManagement and pluginManagement?

level: seniorimportance: should knowfreq 25%

answer

  1. build repos / settings DRM / pluginManagement
  2. repositoriesMode: PREFER_*/FAIL_ON_PROJECT_REPOS
  3. settings = org-wide policy
  4. plugins resolve separately + earlier
  5. FAIL_ON_PROJECT_REPOS enforces it

basics

~10 s

The same content {}/exclusiveContent {} API works in a project's repositories {}, in settings.gradle under dependencyResolutionManagement.repositories {}, and in pluginManagement.repositories {} for plugin resolution. Settings-level filtering applies project-wide.

solid answer

~50 s

Content filtering uses the same DSL everywhere repositories are declared. In a build script's `repositories {}` it affects that project. In `settings.gradle(.kts)` under `dependencyResolutionManagement { repositories { ... } }`, it applies to **all** projects centrally — the recommended place for multi-module builds, and where `repositoriesMode` (PREFER_PROJECT / PREFER_SETTINGS / FAIL_ON_PROJECT_REPOS) governs whether project-level repos are even allowed. Plugin resolution uses a separate graph: `pluginManagement { repositories { ... } }` in settings declares where plugins come from, and the same filtering API applies there — useful to pin the Gradle Plugin Portal vs. an internal plugin repo. Because plugins resolve before normal dependencies and from different repos, you generally filter the two independently. Putting exclusive filters at the settings level gives you one enforceable, org-wide policy that every project inherits, which is exactly what you want for dependency-confusion protection and consistent, fast resolution.

code

kotlin · 20 lines
kotlin
// settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
    repositories {
        mavenCentral()
        exclusiveContent {
            forRepository { maven { url = uri("https://repo.mycompany.com/internal") } }
            filter { includeGroupByRegex("com\\.acme\\..*") }
        }
    }
}
pluginManagement {
    repositories {
        gradlePluginPortal()
        maven {
            url = uri("https://repo.mycompany.com/plugins")
            content { includeGroupByRegex("com\\.mycompany\\..*") }
        }
    }
}

go deeper

for a junior

Aware that filtering lives in the repositories {} block; settings/plugin nuances are stretch.

for a middle

Know it also works in dependencyResolutionManagement and pluginManagement with the same API.

for a senior

Explain repositoriesMode trade-offs and why plugin vs dependency graphs are filtered independently.

for a principal

Design org-wide policy: settings-level exclusiveContent + FAIL_ON_PROJECT_REPOS, plus pinned internal plugin repo, as a supply-chain standard.

## Three places, one API The `content {}` and `exclusiveContent {}` DSL is identical wherever a repository is declared: ### 1. Project build script ```kotlin // build.gradle.kts repositories { mavenCentral { content { excludeGroup("com.acme") } } } ``` Scope: just this project. Fine for single-module builds; discouraged for large multi-module ones where it drifts per project. ### 2. Centralized in settings (recommended) ```kotlin // settings.gradle.kts dependencyResolutionManagement { repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS repositories { mavenCentral() exclusiveContent { forRepository { maven { url = uri("https://repo.mycompany.com/internal") } } filter { includeGroupByRegex("com\\.acme\\..*") } } } } ``` Scope: every project in the build. `repositoriesMode` decides project-repo handling: - `PREFER_PROJECT` (default) — project repos override settings. - `PREFER_SETTINGS` — settings win; project repos ignored with a warning. - `FAIL_ON_PROJECT_REPOS` — build fails if any project declares its own repos, forcing all filtering policy into one file. ### 3. Plugin resolution ```kotlin // settings.gradle.kts pluginManagement { repositories { gradlePluginPortal { content { excludeGroupByRegex("com\\.mycompany\\..*") } } maven { url = uri("https://repo.mycompany.com/plugins") content { includeGroupByRegex("com\\.mycompany\\..*") } } } } ``` Plugins are resolved through a **separate** repository set and resolved earlier than project dependencies, so their filtering is configured independently of `dependencyResolutionManagement`. ## Why centralize - **One policy, many modules:** internal-group exclusivity declared once is inherited by every subproject — no per-project drift. - **Enforceability:** combine settings repositories with `FAIL_ON_PROJECT_REPOS` so no subproject can quietly add an unfiltered repo and reopen a dependency-confusion hole. - **Performance at scale:** in a 50-module build, settings-level filters mean every module benefits from the pruned search space. ## Interaction notes - Settings-level and project-level filters do not 'merge' across modes — `repositoriesMode` chooses which repository set is authoritative. - `exclusiveContent` at settings level still auto-excludes the coordinates from the other settings repositories. - Plugin filtering and dependency filtering are independent; pinning an internal plugin group in `pluginManagement` does not affect normal dependency resolution and vice versa.

  • Why filter plugin repositories separately from dependency repositories?
    Plugins resolve through pluginManagement's own repository set, earlier and independently of dependencyResolutionManagement, so each graph needs its own filtering to be pinned correctly.
  • How do you make sure no subproject bypasses your centralized filters?
    Set repositoriesMode = FAIL_ON_PROJECT_REPOS in dependencyResolutionManagement so the build fails if any project declares its own repositories.

saying these in an interview costs you the question

  • Assuming project-level and settings-level repositories always merge — repositoriesMode decides which set is used.
  • Filtering only dependency repos and forgetting plugin repos still need their own pins.
  • Believing pluginManagement filtering affects normal dependency resolution.

context