Safeguard
Developer Tools•

Why is this dependency on my Java classpath? Maven and Gradle commands

Use mvn dependency:tree and Gradle's dependencies and dependencyInsight tasks to find which library pulled in a dependency and why that version won.

Safeguard Security Team
3 min read

Run mvn dependency:tree with the includes filter in Maven, or the dependencyInsight task in Gradle. Both show every path from your project to the library and, in Gradle's case, why a particular version was selected. You need that path before you can choose a fix.

Maven

mvn dependency:tree -Dincludes=org.apache.logging.log4j
mvn dependency:tree -Dverbose=true -Dincludes=com.google.guava:guava
mvn dependency:tree -DoutputType=json -DoutputFile=target/deps.json

The includes filter takes groupId, artifactId, type and version, each optional, with wildcards. The verbose flag adds the nodes Maven omitted during conflict resolution, which is where the losing versions show up. The outputType option supports text, dot, graphml, tgf and, since plugin 3.7.0, json. The JSON file is handy for feeding other tools.

Gradle

./gradlew dependencies --configuration runtimeClasspath
./gradlew dependencyInsight --dependency jackson --configuration runtimeClasspath

The dependencies task prints the tree with selected versions. Marks help: an asterisk marks a repeated subtree, c marks a constraint, n marks a configuration that cannot be resolved. The dependencyInsight task needs a dependency and a configuration. For Java projects the configuration defaults to compileClasspath, so name runtimeClasspath when you care about what ships.

Its Selection reasons section is the useful part. Typical entries: by conflict resolution, by constraint, by ancestor, selected by rule, forced. If you see forced or by rule, someone changed the default on purpose.

The buildscript classpath is separate. Use the buildEnvironment task for it.

Reading the answer

What you seeWhat it meansNext step
One path, directYou declared itUpgrade it
Several paths, one versionShared transitivePin or constrain once
Several versions, one winsConflict resolutionCheck the winner is the safe one
Not present in runtime treeTest or compile onlyLower priority

For how Maven picks a winner, read Maven dependency mediation.

Common mistakes

  • Checking the compile tree when the question is about what ships.
  • Running the tree in one module of a multi-module build and missing the others.
  • Trusting the IDE view. Use the build tool, because that is what CI uses.

Try it yourself

Click through it at your own pace, or open it full screen.

Look at how a transitive component is traced back to the direct dependency that introduced it.

Where Safeguard fits

Safeguard's SBOM and dependency scanning records the dependency graph for each project, so you can search for a library across repositories. The free scan is a quick way to see it.

Quick check

How do I show only one library in the Maven tree?

Use -Dincludes with a groupId, or groupId and artifactId, for example -Dincludes=com.google.guava:guava.

How do I learn why Gradle chose a version?

Run dependencyInsight for the dependency and configuration, then read Selection reasons.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.