You try to resolve `implementation` and get an error that it cannot be resolved. Why, and what should you resolve instead?
answer
- implementation = bucket, not resolvable
- isCanBeResolved = false
- resolve compileClasspath / runtimeClasspath
- extendsFrom inherits the bucket
- declare vs resolve roles
basics
~10 simplementation is a declaration bucket — isCanBeResolved is false — so it has no resolution result. Resolve compileClasspath or runtimeClasspath, which extend from it.
solid answer
~40 s`implementation` is a **dependency-scope bucket**: both `isCanBeResolved` and `isCanBeConsumed` are false. Its only job is to *hold* declared dependencies, not to produce a file set, so asking for its resolved artifacts errors with 'Resolving configuration 'implementation' directly is not allowed'. The configurations you actually resolve are `compileClasspath` and `runtimeClasspath`, which are resolvable and `extendsFrom` the relevant buckets (`implementation`, `compileOnly`/`runtimeOnly`, `api`). So if you need the files, ask the right resolvable configuration — e.g. `configurations.runtimeClasspath.get().resolve()` or wire a task input to it. This protects you from accidentally resolving a half-defined set and from the classic mistake of treating one configuration as both the place you declare and the thing you resolve.
code
kotlin · 5 lines// WRONG: implementation is a bucket
// configurations.implementation.get().resolve() // ERROR
// RIGHT: resolve the resolvable sibling
val runtimeFiles = configurations.runtimeClasspath.get().resolve()go deeper
Recognize that buckets can't be resolved and name compileClasspath/runtimeClasspath as the right targets.
Explain the flag mechanics and the extendsFrom inheritance that feeds the classpath.
Push toward lazy wiring (Provider as task input) instead of eager .resolve(); tie to configuration cache.
Use this to justify role discipline in convention plugins so build authors never resolve buckets across the org.
## The error Gradle refuses `configurations.implementation.get().resolve()` (or `.files`) with a message like *'Resolving configuration 'implementation' directly is not allowed'*. This is by design. ## Why Every configuration has two booleans: - `isCanBeResolved` — may Gradle compute artifacts for it? - `isCanBeConsumed` — may other projects depend on it? A **bucket** (dependency-scope) like `implementation` has *both false*. It exists only so you can write `dependencies { implementation("...") }`. Resolving means running dependency resolution + variant selection to get concrete files — a bucket deliberately has no such result. ## What to resolve instead The Java plugin creates resolvable configurations that inherit the buckets: - `compileClasspath` — resolvable; `extendsFrom(implementation, compileOnly, api, ...)`. - `runtimeClasspath` — resolvable; `extendsFrom(implementation, runtimeOnly, api, ...)`. So declare in the bucket, resolve the classpath: ```kotlin val files = configurations.runtimeClasspath.get().resolve() // OK ``` ## Wiring into tasks (preferred) Rather than calling `.resolve()` eagerly, wire the resolvable configuration as a task input so resolution is lazy and cache-friendly: ```kotlin tasks.register("listRuntime") { val cp = configurations.runtimeClasspath doLast { cp.get().forEach { println(it.name) } } } ``` ## Takeaway 'Cannot be resolved' is not a bug — it tells you that you reached for the *declaration* role when you wanted the *resolution* role. Pick the resolvable sibling.
- How does `runtimeClasspath` get the dependencies you declared in `implementation`?Through `extendsFrom`: `runtimeClasspath` extends `implementation` (and `runtimeOnly`, `api`, etc.), so declarations in the bucket flow up into the resolvable configuration.
- Is there a downside to calling `.resolve()` directly in configuration scripts?Yes — it triggers eager resolution at configuration time, hurting performance and configuration cache. Prefer wiring the configuration (a Provider) as a lazy task input.
saying these in an interview costs you the question
- Claiming the error is a Gradle bug or a missing dependency.
- Trying to flip `isCanBeResolved = true` on `implementation` to 'fix' it instead of resolving the right configuration.