skip to content

What is jdeps, and what kinds of problems does it help you diagnose in a Java codebase?

level: juniorimportance: should knowfreq 45%

answer

  1. Static bytecode dependency analyzer in the JDK
  2. --jdk-internals finds sun.*/jdk.internal.* usage + suggests fixes
  3. --generate-module-info bootstraps modularization
  4. Misses reflection / dynamic dependencies
  5. -s = summary, package & module level edges

basics

~10 s

jdeps is a JDK command-line tool that analyzes the dependencies of compiled Java classes and JARs. It shows which packages and modules your code depends on, and can flag use of internal JDK APIs.

solid answer

~40 s

jdeps is the JDK's static dependency analyzer. You point it at compiled classes, a JAR, or a module and it prints the package- and module-level dependencies found in the bytecode. Its most valuable mode is --jdk-internals, which reports use of internal, non-standard JDK APIs (like sun.misc.Unsafe) that may be removed or strongly encapsulated in newer Java versions, and suggests supported replacements. It also helps modularization: --generate-module-info produces a draft module-info.java, and -s/--summary gives a high-level module view. Because it reads bytecode, it sees only static dependencies, not reflective ones. Teams run it in CI to catch internal-API usage before a JDK upgrade.

code

java · 12 lines
java
// Find internal-API usage in a dependency before upgrading the JDK:
//   jdeps --jdk-internals some-library.jar
//
// Example output:
//   some-library.jar -> JDK removed internal API
//   com.lib.Foo  -> sun.misc.Unsafe  JDK internal API (JDK removed internal API)
//
// Bootstrap a module descriptor for a plain JAR:
//   jdeps --generate-module-info out/ some-library.jar
//
// High-level module dependency summary of an app:
//   jdeps -s app.jar

go deeper

for a junior

Knows jdeps is a JDK tool that lists what packages/JARs depend on, and that you run it from the command line on a JAR.

for a middle

Can run --jdk-internals to find internal-API usage before a JDK upgrade and read the package/module dependency output, and knows it is static-only.

for a senior

Integrates jdeps into CI for upgrade readiness, uses --generate-module-info to bootstrap modularization, and understands the reflection/static-analysis blind spot and how to compensate.

for a principal

Sets organization-wide policy for detecting encapsulated-API usage across the dependency graph, weighs jdeps against runtime/agent-based tooling, and plans multi-service JDK migration strategy around its limits.

## What jdeps is `jdeps` is a **command-line tool shipped with the JDK** that performs **static dependency analysis** on compiled Java code. "Static" means it reads the **bytecode** (compiled `.class` files in a folder or inside a `.jar`) and works out what other code that bytecode refers to, *without running the program*. Terms: - **Class file / bytecode**: the compiled form of a `.java` file; the JVM runs bytecode, not source. - **Package**: a namespace grouping classes, e.g. `java.util`. - **Module (Java 9+)**: a named, self-describing set of packages declared in `module-info.java`; it states what it `requires` and what it `exports`. - **Internal/non-standard JDK API**: classes in packages like `sun.*`, `com.sun.*`, or `jdk.internal.*` that were never meant for outside use. They can change or vanish between releases. ## What it reports By default `jdeps app.jar` lists, per source package, which target packages and modules it depends on, e.g. `your.pkg -> java.util java.base`. Useful options: - `-s` / `--summary`: condensed, module-to-module view. - `-verbose:class`: class-level (finer than package) edges. - `-R` / `--recursive`: follow transitive dependencies through the classpath. - `--jdk-internals`: the headline feature — flags any use of encapsulated internal JDK APIs and prints a suggested replacement when one exists. - `--generate-module-info <dir>`: emits a first-draft `module-info.java` for a JAR, to bootstrap modularization. - `--multi-release <version>`: pick which version's classes to analyze in a multi-release JAR. - `-cp` / `--module-path`: tell jdeps where to find dependencies so it can resolve them. ## Why it matters The big practical use is **JDK upgrade readiness**. Modern Java *strongly encapsulates* internal APIs (JEP 396/403), so code that compiled fine on Java 8 can fail at runtime on Java 17+ with `InaccessibleObjectException` or fail to start. Running `jdeps --jdk-internals` across your dependency JARs surfaces those landmines *before* you upgrade. ## Limits Because it analyzes bytecode, `jdeps` only sees **static, compile-baked references**. Dependencies pulled in via **reflection**, `Class.forName(name)`, service loading, or dynamic proxies are invisible to it. So a clean jdeps report is necessary but not sufficient — runtime testing still matters.

  • Why can a clean jdeps report still hide a JDK-upgrade break?
    jdeps only sees static bytecode references. Reflection, Class.forName, ServiceLoader, and dynamic proxies resolve names at runtime, so internal-API access through those paths is invisible to jdeps.
  • How would you use jdeps to start modularizing a legacy JAR?
    Run `jdeps --generate-module-info <outdir> legacy.jar` to get a draft module-info.java listing the requires/exports it inferred, then hand-edit it (tighten exports, add transitive requires, handle reflective access with opens).

saying these in an interview costs you the question

  • Claiming jdeps runs the program or does runtime analysis — it is purely static
  • Thinking jdeps can detect reflective or service-loaded dependencies
  • Confusing jdeps (analysis) with jlink (image building) or jmod (packaging)
  • Believing a clean jdeps report guarantees the code runs on a new JDK

context