How does exclusiveContent {} differ from a per-repository content {} block, and when would you choose it?
answer
- content = local to one repo
- exclusiveContent = global pin
- forRepository + filter
- auto-excludes from all others
- anti dependency-confusion
basics
~20 scontent {} only describes one repo; you'd still have to exclude the same group everywhere else. exclusiveContent {} declares a group is served by exactly one repo and auto-excludes it from all others in one place.
solid answer
~50 sA per-repository `content {}` block is **local**: it says what *this* repo may serve, but it does nothing to the other repositories. To truly pin a group to one repo with plain `content`, you must add `includeGroup` on the target repo **and** an `excludeGroup` on every other repo — error-prone and easy to forget when someone adds a new repository. `exclusiveContent {}` solves this declaratively: `forRepository { ... }` names the repo, and `filter { includeGroup(...) }` says those coordinates are served **exclusively** there. Gradle then automatically excludes those coordinates from all other repositories — including ones added later. Choose `exclusiveContent` when a set of modules (typically internal/private groups) must come from exactly one source, both for resolution speed and for dependency-confusion protection. Use plain `content` for looser hints like 'don't bother checking Central for my internal group' where you don't need the exclusive guarantee.
code
kotlin · 11 linesrepositories {
mavenCentral()
exclusiveContent {
forRepository {
maven { url = uri("https://repo.mycompany.com/internal") }
}
filter {
includeGroupByRegex("com\\.acme\\..*")
}
}
}go deeper
Know exclusiveContent means 'this group only from this repo'; details of forRepository optional.
Contrast local content vs global exclusiveContent and give the forRepository/filter structure.
Recommend exclusiveContent for internal groups as dependency-confusion mitigation and note auto-exclusion of future repos.
Mandate exclusiveContent for all internal namespaces in settings dependencyResolutionManagement as an org supply-chain control.
## The limitation of per-repo content `content {}` answers only one question: *may this repository serve coordinate X?* It says nothing about the others. So pinning a group exclusively requires bilateral declarations: ```kotlin repositories { mavenCentral { content { excludeGroup("com.acme") } } google() // oops — forgot to exclude here too maven { url = uri("https://repo.mycompany.com/internal") content { includeGroup("com.acme") } } } ``` If someone later adds `google()` without an `excludeGroup`, your internal group can again be searched (or served) by it. The invariant lives in many places. ## exclusiveContent centralizes the invariant ```kotlin repositories { mavenCentral() exclusiveContent { forRepository { maven { url = uri("https://repo.mycompany.com/internal") } } filter { includeGroup("com.acme") includeGroupByRegex("com\\.acme\\..*") } } } ``` Semantics: - `forRepository {}` defines (or references) the one repository that holds the filtered coordinates. - `filter {}` uses the same include/exclude DSL as `content {}` to describe the coordinate set. - Gradle guarantees those coordinates are served **only** by that repository and are excluded from **every other** declared repository automatically, present or future. ## Referencing an existing repository If the repo is already declared, you can reference it rather than redeclare: ```kotlin val internal = maven { url = uri("https://repo.mycompany.com/internal") } exclusiveContent { forRepositories(internal) filter { includeGroup("com.acme") } } ``` `forRepositories(...)` accepts one or more repositories that collectively (and exclusively) serve the filtered set. ## When to choose which | Need | Use | |------|-----| | 'This repo only serves my groups' | `content { includeGroup }` | | 'Don't look here for my group' | `content { excludeGroup }` | | 'My group comes ONLY from here, nowhere else, enforced globally' | `exclusiveContent {}` | ## Security angle `exclusiveContent` is the recommended primitive against **dependency confusion**: by pinning internal groups exclusively to the private repo, a malicious public artifact published under the same coordinates can never be resolved, because no public repo is even a candidate.
- Why is exclusiveContent safer than content for internal artifacts?It guarantees the coordinates are excluded from every other repo automatically — including newly added ones — so a same-named public artifact can never be a candidate, mitigating dependency confusion.
- Can exclusiveContent reference a repository declared elsewhere instead of creating one inline?Yes — use forRepositories(repoRef) (or forRepository {} to declare inline). You can pass multiple repos that exclusively serve the filtered set.
saying these in an interview costs you the question
- Claiming content {} alone pins a group exclusively — it doesn't touch other repos.
- Thinking exclusiveContent changes version resolution rather than just candidate repositories.
- Assuming you still need manual excludeGroup on other repos when using exclusiveContent — Gradle does it for you.