How do you use the dependencyInsight task to find out why Gradle selected a particular version of a module?
answer
- dependencyInsight --configuration --dependency
- selected version + reason at top
- inverted/bottom-up requester tree
- 'by conflict resolution' reason line
- X -> Y means X lost
basics
~10 sRun ./gradlew dependencyInsight --configuration <cfg> --dependency <module>. It prints the selected version, every path that requested the module, and the reason for selection — e.g. 'by conflict resolution'.
solid answer
~40 s`dependencyInsight` is a built-in report task that explains the *resolution of one module* within one configuration. You invoke it as `./gradlew dependencyInsight --configuration runtimeClasspath --dependency guava`. It prints the **selected version** at the top, the **selection reason(s)** (e.g. `by conflict resolution: between versions 30.0 and 31.0`, `by constraint`, `forced`, `selected by rule`), and then an **inverted tree** showing every requesting path with the version each path *asked for* (`30.0 -> 31.0` meaning it lost). This is the go-to tool when highest-version-wins or `failOnVersionConflict()` surprises you: it answers both *which version won* and *who pulled it and why*. Compare with `dependencies`, which dumps the entire forward tree; `dependencyInsight` zooms into one module and adds reasons.
code
bash · 8 lines./gradlew dependencyInsight \
--configuration runtimeClasspath \
--dependency com.google.guava:guava
# Output highlights:
# com.google.guava:guava:31.0-jre (selected)
# Selection reasons: By conflict resolution: between 31.0-jre and 30.0-jre
# com.google.guava:guava:30.0-jre -> 31.0-jre (this requester lost)go deeper
Know the command exists and that it tells you the chosen version of a module.
Run it with --configuration and --dependency, read the selected version, the reason line, and the inverted requester tree.
Interpret all reason types (conflict resolution, constraint, forced, selected by rule) and combine with dependencies for full diagnosis.
Use it to set debugging conventions/runbooks for the team when resolution surprises occur in CI.
## Purpose Where `dependencies` prints the *whole* resolved graph top-down, `dependencyInsight` answers a focused question: **for this one module, what version was chosen, who requested it, and why?** It is the primary debugging tool for conflict resolution. ## Invocation ```bash ./gradlew dependencyInsight \ --configuration runtimeClasspath \ --dependency com.google.guava:guava ``` - `--configuration` (required in practice): which resolvable configuration to inspect (`compileClasspath`, `runtimeClasspath`, etc.). Resolution is per configuration, so you must say which. - `--dependency`: a substring or `group:name` matcher for the module of interest. - `--single-path` (optional): show just one requesting path instead of all. ## Reading the output Top of the report: the **selected** version and a **reason** block. Common reasons: - `by conflict resolution: between versions X and Y` — highest-wins picked this version. - `by constraint` — a dependency constraint influenced it. - `forced` — `force = true` / `resolutionStrategy.force(...)`. - `selected by rule` — a `resolutionStrategy.eachDependency` / substitution rule. Below that: an **inverted (bottom-up) tree** of every requester. A line like `com.google.guava:guava:30.0-jre -> 31.0-jre` means *this requester asked for 30.0 but the build resolved 31.0* (it lost the conflict). Each branch shows the chain of dependencies that led to the request. ## Worked example Suppose your build fails after enabling `failOnVersionConflict()` on guava. Run the insight: ``` > Task :dependencyInsight com.google.guava:guava:31.0-jre Selection reasons: - By conflict resolution: between versions 31.0-jre and 30.0-jre com.google.guava:guava:31.0-jre +--- some.lib:foo:1.0 com.google.guava:guava:30.0-jre -> 31.0-jre +--- project :app (requested com.google.guava:guava:30.0-jre) ``` Now you know: `foo` pulls 31.0, your app directly asks for 30.0, highest-wins chose 31.0. You can pin 31.0 (or upgrade your direct declaration) to resolve. ## Tips - If you omit `--configuration`, older Gradle errors out; pick the configuration that's actually failing. - For modules with the same name across groups, use the full `group:name`. - Pair it with `dependencies` for the big picture, then `dependencyInsight` to drill in.
- What does the arrow '30.0 -> 31.0' in the report mean?A requester asked for 30.0 but the build resolved 31.0 for that module — i.e. 30.0 lost the conflict and was upgraded to the selected version.
- How is dependencyInsight different from the dependencies task?dependencies prints the entire forward (top-down) resolved tree for configurations; dependencyInsight focuses on one module, shows the bottom-up requesters, and crucially prints the selection reason.
- Why do you usually pass --configuration?Resolution is per configuration, so the selected version can differ between compileClasspath and runtimeClasspath; you must tell the task which one to report.
saying these in an interview costs you the question
- Thinking dependencyInsight shows the whole graph — it's scoped to one module.
- Reading 'X -> Y' as a dependency edge rather than 'X was upgraded to Y'.
- Forgetting that the report is per configuration.