skip to content

Dependency Plugin Goals

The maven-dependency-plugin goals used to interrogate the graph — tree, analyze, go-offline, copy-dependencies, purge-local-repository. Knowing `dependency:tree -Dverbose` is the difference between diagnosing a conflict and guessing at it.

on this pageshow

questions

6

How do you inspect the full dependency graph of a Maven project, and what does dependency:tree show you?

level: juniorimportance: must knowfreq 80%

answer

  1. tree = resolved graph
  2. indent = who pulled it in
  3. -Dincludes filters branches
  4. -Dverbose shows omitted/conflicts
  5. group:artifact:type:version:scope

basics

~10 s

Run mvn dependency:tree. It prints every dependency your project pulls in, including transitive ones, as an indented tree showing which dependency brought in which, plus the scope and version of each.

solid answer

~40 s

`mvn dependency:tree` (the `tree` goal of the `maven-dependency-plugin`) renders the resolved dependency graph as an indented tree. Each node shows groupId:artifactId:type:version:scope, and indentation shows the parent that pulled it in transitively. It is the first tool you reach for to answer 'why is this jar on my classpath?' or 'which version actually won?'. You can scope output with `-Dincludes=groupId:artifactId` to show only the paths leading to a given artifact, and add `-Dverbose` to also see omitted/conflicting versions that mediation removed. It reflects the *resolved* graph after version mediation and scope rules, so it is the source of truth for what Maven actually puts on each classpath, not just what you declared in your pom.

code

bash · 1 line
bash
mvn dependency:tree -Dverbose -Dincludes=org.slf4j:slf4j-api

go deeper

for a junior

Knows to run mvn dependency:tree and read the indentation to find transitive deps.

for a middle

Uses -Dincludes and -Dverbose to isolate and debug a specific artifact and see conflicts.

for a senior

Treats the tree as authoritative resolved state and uses it to drive mediation/exclusion decisions.

for a principal

Standardizes graph-inspection workflows and teaches teams to debug classpath issues from the resolved graph rather than guessing from poms.

## What the dependency graph is Maven builds projects with declared dependencies, but each dependency can itself declare dependencies — these are **transitive dependencies**. The complete set forms a directed graph. Your classpath is determined by *resolving* that graph, applying version mediation and scope rules. ## dependency:tree `mvn dependency:tree` invokes the `tree` goal of the `maven-dependency-plugin`. It prints the resolved graph as an indented ASCII tree. The root is your project; children are direct dependencies; grandchildren are transitive ones. Each line has the coordinate form: `groupId:artifactId:type:version:scope` (e.g. `org.springframework:spring-core:jar:6.1.0:compile`). ## Key options - `-Dverbose` — also shows nodes that were *omitted* during resolution, annotated with reasons like `(omitted for conflict with 6.1.0)` or `(omitted for duplicate)`. This is how you see losing versions. - `-Dincludes=group:artifact` — filters to only the branches that lead to the matching artifact. Wildcards allowed, e.g. `-Dincludes=com.fasterxml.jackson.core:*`. - `-Dexcludes=...` — inverse filter. - `-DoutputType=dot` / `-DoutputFile=...` — emit a Graphviz/text file. ## Why it matters It answers the two most common dependency questions: *what is on my classpath* and *who pulled it in*. Because it shows the **resolved** graph (post-mediation, post-scope), it is authoritative — far more reliable than reading the pom by hand, which only shows what you declared, not what won. ```bash mvn dependency:tree -Dverbose -Dincludes=com.fasterxml.jackson.core:jackson-databind ``` This prints only the paths leading to jackson-databind and includes the conflicting versions that mediation discarded.

  • What does the -Dverbose flag add to the output?
    It shows dependency nodes that resolution omitted (e.g. losing versions in a conflict or duplicates), annotated with the reason, so you can see what mediation discarded.
  • Does dependency:tree show declared or resolved versions?
    Resolved — it reflects the graph after version mediation and scope filtering, which is why it's authoritative for what's actually on the classpath.

Like a family tree where each ancestor can bring relatives you never invited — the tree shows the whole bloodline and who introduced whom.

saying these in an interview costs you the question

  • Saying the tree shows only direct dependencies (it shows transitive too)
  • Claiming it reflects what you declared rather than what was resolved
  • Confusing -Dincludes (a filter) with adding a dependency

context

open as a page

A class works locally but throws NoSuchMethodError in another environment. How do you use the dependency plugin goals to diagnose and fix the likely version conflict?

level: seniorimportance: must knowfreq 55%

basics

~20 s

A NoSuchMethodError usually means two versions of a library are in play. Run mvn dependency:tree -Dverbose -Dincludes=group:artifact to see which versions exist and who pulled them in, then fix it with an exclusion, a direct declaration, or dependencyManagement.

open as a page

What does dependency:analyze do, and how do you act on its 'used undeclared' and 'unused declared' warnings?

level: middleimportance: should knowfreq 50%

basics

~10 s

mvn dependency:analyze byte-code-scans your classes to compare what you actually use against what you declare. It flags 'used but undeclared' (relied on transitively — should declare directly) and 'declared but unused' (candidates to remove).

open as a page

What problem does dependency:go-offline solve, and when would you use it in a build pipeline?

level: middleimportance: should knowfreq 45%

basics

~20 s

mvn dependency:go-offline pre-downloads every dependency and plugin your build needs into the local .m2 repository, so a later build can run with -o (offline) without hitting the network — ideal for Docker layer caching and air-gapped CI.

open as a page

When would you use dependency:purge-local-repository, and how does it relate to SNAPSHOT and corrupted-cache problems?

level: seniorimportance: should knowfreq 35%

basics

~10 s

mvn dependency:purge-local-repository deletes this project's dependencies from the local .m2 cache and re-resolves them. You use it to recover from a corrupted/partial download or to force a stale SNAPSHOT to be re-fetched fresh.

open as a page

What is dependency:copy-dependencies for, and how is it different from building a fat/shaded jar?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

dependency:copy-dependencies copies your project's resolved dependency jars into a folder (default target/dependency). Unlike a fat/shaded jar, it leaves them as separate files — useful for a Class-Path/-cp layout or for Docker images that cache deps separately from app code.

open as a page