Usually yes. Every library you ship is code you must patch, so removing declared but unused dependencies shrinks what you track. Run dependency:analyze to find candidates, but verify each one, because bytecode analysis can mislabel libraries loaded by reflection or at runtime.
Definition
The Maven dependency plugin's analyze goal sorts dependencies into groups:
| Group | Meaning | Action |
|---|---|---|
| Used and declared | Correct | None |
| Used but undeclared | Classes are referenced but the artifact is not in your POM, so it arrives transitively | Declare it directly |
| Unused but declared | In the POM but no referenced classes | Often removable |
It also flags dependencies that only test code uses but that are not declared with test scope.
Why it matters for security
An unused declared library still gets shipped and still shows up in scans. A used but undeclared library is riskier in a quieter way. You depend on a transitive path you do not control. When the parent library changes its dependencies, your code can break or silently move to a different version.
Declaring what you use makes version decisions explicit, which makes pins and fixes easier.
Run it
mvn dependency:analyze
mvn dependency:analyze -DfailOnWarning=true
The standalone goal runs test-compile first. In a lifecycle build, use analyze-only. FailOnWarning defaults to false, so warnings are reported without failing the build.
False positives to expect
The default analyzer works on bytecode. The plugin offers settings to correct what it gets wrong. Common culprits are libraries loaded through reflection or service lookup, and runtime-only dependencies such as database drivers. Use usedDependencies to mark one as used, and the ignored options to filter by coordinates. IgnoreUnusedRuntime relaxes unused checks for runtime scope.
Never delete a library purely because the report says unused. Remove it on a branch, build, run the full tests, and exercise startup.
Steps
- Run analyze and save the report.
- Sort entries into obviously unused, suspicious, and runtime-loaded.
- Remove the obvious ones first.
- For used but undeclared, add the declaration at the version you already resolve.
- Add the persistent exceptions to the plugin configuration so the report stays quiet.
- Turn on failOnWarning once it is clean.
For finding what is actually reachable at runtime, see Is a vulnerable Java dependency actually reachable?.
Try it yourself
Click through it at your own pace, or open it full screen.
Count how many components are transitive. That is the part dependency:analyze helps you make explicit.
Where Safeguard fits
Safeguard's dependency scanning and SBOMs give you the full component list to compare with the analyze output. Reachability analysis helps you see which findings sit in code your application calls. Try the free scan.
Quick check
Will dependency:analyze fail my build by default?
No. FailOnWarning defaults to false, so it reports but does not fail.
Why might a needed library show as unused?
The analysis is bytecode based, so reflection, service lookup and runtime-only use can be missed.
Sources
Last reviewed: 19 October 2026.