Safeguard
Security Guides•

Is a vulnerable Java dependency actually reachable in my app?

Present means the library is on your classpath. Reachable means your code can call the vulnerable function. How to tell them apart in Java and what to fix.

Safeguard Security Team
3 min read

Present means the vulnerable library is on your classpath. Reachable means a call path from your application reaches the vulnerable function. Reachable findings come first, but a present, unreachable one is still worth fixing, because code changes and reflection can make it reachable later.

Definitions

Present. The component appears in your dependency tree or inventory at an affected version.

Reachable. Static analysis finds a path from your entry points to the vulnerable code. Some tools add runtime evidence.

Exploitable. Reachable, and an attacker can supply the input that triggers it in your deployment. That is the narrowest set.

LevelQuestionTypical effect on priority
PresentIs it on the classpath?Track
ReachableCan my code call it?Fix soon
ExploitableCan an attacker trigger it here?Fix first

Why Java makes this hard

Static call graphs struggle with features that Java frameworks rely on. Reflection, dependency injection, service loading and annotation-driven wiring create calls that are not visible in plain source. The Maven dependency plugin analyzes bytecode and ships options to correct false positives, which shows how often static analysis needs a human check. Libraries loaded by reflection or service lookup are the usual trouble, and the same weakness affects any static reachability method.

So a not reachable verdict in Java is evidence, not proof.

How to use reachability without fooling yourself

  1. Start with the full present list from your SBOM or tree.
  2. Use reachability to order the list, not to delete from it.
  3. For each not reachable finding, note why: library function never called, or optional feature disabled.
  4. Be careful with dependencies loaded by frameworks, like logging, serialization, web servers and database drivers. Treat those as reachable unless you can show otherwise.
  5. Re-evaluate when you add features or upgrade a framework.
  6. Keep the cheap fix. If a patched version is available and a bump is low risk, do it regardless.

An example of reasoning

Suppose an advisory affects a parsing function in a library. Your application pulls the library in transitively, never calls the parser, and does not enable the framework feature that would. That finding drops in priority. If another service passes untrusted input into that parser, it rises to the top. Same library, different answer per service.

Why this matters for backlogs

Large Java applications can carry hundreds of present findings. Reachability gives teams a credible order of work, so the urgent ones are fixed first and the rest follow in routine upgrades. See how to find vulnerable dependencies in your project.

Try it yourself

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

Compare the list before and after the reachable filter, and note which findings drop out.

Where Safeguard fits

Safeguard includes reachability analysis alongside SBOM and dependency scanning, so findings can be ordered by whether your code can reach them. The free scan is the quickest way to see a result.

Quick check

Can I ignore an unreachable vulnerability?

Deprioritise it, do not forget it. Keep it in the backlog and recheck when the code changes.

Is reachable the same as exploitable?

No. Exploitable also needs an attacker to be able to supply the triggering input in your deployment.

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.