How do you inspect the project dependency graph and confirm a cross-project edge like :app -> :lib?
answer
- :app:dependencies --configuration compileClasspath
- project :lib node = cross-project edge
- dependencyInsight = why this version
- --dry-run = task order
- gradlew projects = structure
basics
~10 sRun ./gradlew :app:dependencies. It prints each configuration's resolved tree; under compileClasspath you'll see a project :lib node, confirming the cross-project edge.
solid answer
~40 sThe primary tool is `./gradlew :app:dependencies`, which renders the resolved dependency tree per configuration. Scope it with `--configuration compileClasspath` (or `runtimeClasspath`) to avoid noise; a `project :lib` line confirms the inter-project edge and shows :lib's own transitive deps folded in. To understand *why* a particular version or edge is present, use `./gradlew :app:dependencyInsight --configuration runtimeClasspath --dependency <name>`. For task ordering (not module deps), `./gradlew :app:build --dry-run` lists tasks in execution order, so you can see `:lib:jar` precede `:app:compileJava`. For a holistic view, `./gradlew projects` shows the project tree, and the optional `build-dashboard`/`project-report` plugins emit HTML. Knowing which command answers which question — module graph vs task graph vs 'why this version' — is the real skill.
code
bash · 11 lines# Module graph for one configuration
./gradlew :app:dependencies --configuration compileClasspath
# Why a version/edge is present (reverse trace)
./gradlew :app:dependencyInsight --configuration runtimeClasspath --dependency guava
# Task execution order (no work performed)
./gradlew :app:build --dry-run
# Project structure
./gradlew projectsgo deeper
Know that ./gradlew :app:dependencies prints the dependency tree and shows project :lib.
Scope with --configuration, read (*), (c), and -> annotations, and pick dependencyInsight vs dependencies vs --dry-run for the right question.
Use dependencyInsight to debug cross-project version conflicts and explain resolved vs requested; tie report output to configuration variants.
Advocate report tooling (project-report, build scans) as standard diagnostics across a large module graph and in CI triage.
## Three different graphs, three different tools People conflate them; an interviewer wants you to separate: 1. **Module/dependency graph** (what artifacts a configuration resolves to). 2. **Task graph** (what tasks run, in what order). 3. **Project structure** (which subprojects exist). ## 1. The dependency report — `:app:dependencies` ```bash ./gradlew :app:dependencies --configuration compileClasspath ``` Prints the **resolved** tree for that configuration. A cross-project edge shows as: ``` compileClasspath \--- project :lib \--- com.google.guava:guava:33.0.0-jre ``` The `project :lib` node proves the inter-project edge and inlines :lib's exported (api) transitives. Resolution annotations appear here too: `(*)` = omitted (already shown), `(c)` = a dependency constraint, `-> 33.0.0` = version selected by conflict resolution. ## 2. Why is *this* edge/version here? — `dependencyInsight` ```bash ./gradlew :app:dependencyInsight \ --configuration runtimeClasspath --dependency guava ``` Reverse view: it traces *paths* that brought a module in (including via `project :lib`) and explains the selected version. Indispensable for conflict debugging. ## 3. Task ordering — `--dry-run` ```bash ./gradlew :app:build --dry-run ``` Lists tasks in the exact order they'd execute (each marked SKIPPED). You'll see `:lib:compileJava`, `:lib:classes`, `:lib:jar` ahead of `:app:compileJava` — direct evidence the artifact dependency induced the ordering. ## 4. Project tree — `projects` ```bash ./gradlew projects ``` Shows the `:` root and children like `:app`, `:lib`. The `project-report` plugin adds `htmlDependencyReport` for a browsable graph. ## Pitfalls - `:app:dependencies` with no `--configuration` dumps *every* configuration — verbose and slow to read; always scope it. - The report shows the **resolved** graph, so version conflicts are already decided; use `dependencyInsight` to see the pre-resolution candidates.
- The output shows guava -> 33.0.0 with an arrow. What does that mean?Conflict resolution selected version 33.0.0 over a requested lower version. The arrow marks a version substitution; dependencyInsight explains which path requested what and why 33.0.0 won.
- How would you see task order rather than the module tree?Use --dry-run (e.g. ./gradlew :app:build --dry-run); it lists tasks in execution order without running them, showing :lib:jar before :app:compileJava.
saying these in an interview costs you the question
- Confusing :app:dependencies (module graph) with the task graph.
- Running :app:dependencies without --configuration and getting lost in unscoped output.
- Believing the report shows pre-resolution candidates (it shows the resolved graph).