Safeguard
Security Guides•

How do you find unused Maven dependencies to cut risk?

Run dependency:analyze to list declared but unused and used but undeclared libraries. Fewer components means fewer advisories to triage. Steps and limits.

Safeguard Security Team
3 min read

Run the Maven dependency plugin's analyze goal. It classifies libraries as used and declared, used but undeclared, or unused but declared. Remove the unused ones, declare the undeclared ones, and your build carries fewer components that can attract advisories. Treat results as leads to verify, not orders.

Why removal is a security task

Every library on your classpath is something to patch, track and answer questions about. A dependency nobody calls still shows up in scans and SBOMs, and still costs triage time when an advisory lands. The cheapest vulnerability to fix is the one in a library you removed.

What the goal reports

The plugin documentation describes dependency:analyze as analyzing the dependencies of a project and determining which are used and declared, used and undeclared, and unused and declared. By default it uses the maven-dependency-analyzer, which works at the bytecode level, and the page notes this brings limitations.

It always runs the test-compile phase, because it is meant to be used standalone. For use inside your normal lifecycle, the same page points to the analyze-only goal.

Steps

  1. Run the analysis.
mvn dependency:analyze
  1. Read each group in the output.
  2. For unused but declared, check why it is there before deleting: runtime reflection, service loading, annotation processors and plugins are loaded without a direct bytecode reference.
  3. For used but undeclared, add a direct declaration. Relying on a transitive path is fragile and hides what you really depend on.
  4. Rebuild, run tests, and run the analysis again.

What the analyzer cannot see

Because it inspects bytecode, it can flag a library as unused when it is loaded by name at runtime, or needed only at runtime, such as a database driver or logging backend. The plugin offers options to handle this: ignore runtime scope in the unused check, ignore specific dependencies, or exclude class patterns.

OptionUse
ignoreUnusedRuntimeSkip runtime scope in the unused check
ignoredDependenciesList libraries to leave alone
failOnWarningFail the build when a warning is found (default false)
ignoreNonCompileSkip runtime, provided, test and system scopes in the unused check

Turning on failOnWarning in CI keeps the list from growing back, once the existing warnings are cleared.

Unused is not the same as unreachable

This is a different question from reachability. dependency:analyze asks whether your code references a library at all. Reachability analysis asks whether a vulnerable function in a library you do use can be called from your code. Both reduce noise and they complement each other. Also, trimming a dependency can change the transitive tree, so check why Maven picks older versions after you remove one.

Try it yourself

Click through it at your own pace, or open it full screen. See how findings are sorted by whether the vulnerable code can be reached, the next step after you have removed what is unused.

Safeguard's dependency scanning and reachability analysis work together on Java projects, and its SBOMs show what remains after cleanup. Free scan: gold.safeguard.sh/scan.

Quick check

Is it safe to delete everything flagged as unused?

No. Libraries used through reflection or loaded at runtime can be flagged. Check each one and run your tests.

Does this replace a vulnerability scan?

No. It reduces what there is to scan. You still need scanning for what remains.

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.