4 ready-to-try Java tools your team may not know about

Tell everyone about jdeprscan, jlink, jpackage, and Java Flight Recorder.

July 9, 2021

Download a PDF of this article

Get ready to add to your Java developer toolchain. There are a number of useful tools hidden in plain sight—and you’ll feel like you gained a superpower by using them. Mikael Vidstedt, director of software engineering for the Java Virtual Machine at Oracle, describes four ready-to-use tools that will let you

  • Discover out-of-date dependencies that might break in your class or JAR files
  • Create a slim, custom runtime for a container
  • Reveal why your network I/O is taking so long
  • Bundle your app and JDK into an operating system–specific package

Discover deprecated dependencies with jdeprscan

Java is all about a regular cadence of new features and functionality. As a result, people often ask what will break if they upgrade to a new release, says Vidstedt. And yes, there’s a tool that can put your mind at ease: jdeprscan performs static analysis by scanning a JAR file (or some other aggregation of class files) for uses of deprecated API elements.

“Point jdeprscan at a class name or a JAR file, and it will help you figure out what you may be depending on—things you may want to look into and potentially change, such as deprecated APIs,” says Vidstedt. “You get very helpful warnings and pointers to code that you have that you may want to look at upgrading or changing in some way.”

The deprecated APIs identified by jdeprscan are only those that are defined by Java SE. Deprecated APIs defined by third-party libraries aren’t reported. To scan a JAR file or a set of class files, you must first ensure that all of the classes that the scanned classes depend upon are present in the class path. Set the classpath using the --class-path option; typically, you would use the same classpath as the one that you use when invoking your application. If jdeprscan can’t find all the dependent classes, it will generate an error message for each class that’s missing.

Create a slim, custom runtime with jlink

“If you download the JDK today, it’s somewhere on the order of 300 megabytes,” says Vidstedt. “Half of that is actually the exact same data twice.” Why? Because the JDK contains modules packaged in two different ways: first, as a linked version containing the data your program actually runs, and second, as standalone modules. If you are including the JDK with your application, you’re including a lot more bits than you actually need.

With jlink, you can create a custom runtime that includes only what your application needs. “So, if you have a small application, maybe you need only a handful of the 60-something modules in the platform,” Vidstedt says. “This is especially useful if you have container environments, where you are building a Docker image and want to keep it slim and small.”

The other thing to know about jlink is that by using the class data sharing that’s built into the JVM, you can precompute some of the state and store it in the HotSpot JVM’s class data sharing (CDS) archive. “So, you do a training run, store that data to disk, and then, for subsequent runs, you can reuse that training data,” Vidstedt explains. “This gives your application a faster startup time and smaller memory footprint. That’s especially useful if you are running multiple processes on the same machine.”

Finally, Vidstedt notes that applications need not be module-aware to use this tool: “You can use jlink with your old 1990s Java applications, and everything will work just fine.”

If you use jlink, you need to ensure that your custom runtime images are updated with the latest updates. Unlike custom runtime images, web-deployed Java applications automatically download application updates from the internet as soon as they’re available using Java Auto Update. However, jlink’s custom runtime images don’t have built-in support for automatic updates.

Troubleshoot performance with Java Flight Recorder

Java Flight Recorder is a framework that can be turned on in production to record event data: lots of data. “All the data you can imagine, and then some,” Vidstedt says. That’s a testament, he believes, to Java’s superior serviceability, monitoring, and management story.

“If you’re curious what the runtime is up to, what you should do to improve on the performance, or what you should do if you’re running into some weird case and you’re wondering, ‘Why is my network I/O taking so long?’ Java Flight Recorder is likely going to be able to answer that question for you.”

It records data about events, that occur in the JVM or the Java application at a specific point in time. Each event has a name, a time stamp, and an optional payload. The payload is the data associated with an event, such as the current CPU usage, the Java heap size before and after the event, and the thread ID of the lock holder.

An easy way to use Java Flight Recorder is through JDK Mission Control, which gives you access to Java Flight Recorder functionality through a GUI.

You can run multiple recordings concurrently and configure each recording using different settings; in particular, you can configure different recordings to capture different sets of events.

Java Flight Recorder collects information about three types of events.

  • A duration event takes some time to occur and is logged when the event completes.
  • An instant event is logged right away.
  • Sample events (also called requestable events) are logged at regular intervals to provide a sample of system activity.

Java Flight Recorder monitors the running system at an extremely high level of detail. This produces an enormous amount of data. To keep the overhead as low as possible, limit the type of recorded events to those you actually need. In most cases, very short-duration events are of no interest, so limit the recording to events with a duration exceeding a certain meaningful threshold.

Bundle your app and JDK for a specific OS with jpackage

You can use jpackage to combine a Java application and a Java runtime image to produce a Java application image that includes all the necessary dependencies. The result is a native package in an operating system–specific format, such as a .exe file for Windows or a .dmg file for macOS. When combined with jlink (see above), jpackage gives you a complete end-to-end deployment system.

Vidstedt says, “If you use jlink and jpackage together, you can get a very nice result if you’re trying to deliver packaged applications. You can do that without even relying upon your end users having a particular JDK installed, because jlink gives them the subset of the JDK that they need, right there in your app installer.”

You can see how jlink and jpackage work together in a five-minute lab presented by Java Developer Advocate David Delabassée.


The JDK contains many powerful tools for Java developers, including jdeprscan, jlink, Java Flight Recorder, and jpackage. Try them, learn them, and add them to your Java developer toolchain.

Dig deeper

Alexa Morales

Alexa Weber Morales is director of developer content at Oracle. Morales is the former editor in chief of Software Development magazine and has more than 15 years of experience as a technology content strategist and journalist.

Share this Page