Stripping debug information from jlink runtime images

David Delabassee
Oct 2, 2019 · 2 min read
Photo by Nuno Silva

Using jlink, one can easily create a custom Java runtime image that will only contain the modules required to run a given application. jlink also comes with some additonal plugins, some of which will help to additionaly reduce the size of the produced custom runtime image — namely the compress and the strip-debug plugins.

As its name implies, the strip-debug plugin will remove debugging information out of the output runtime image. With JDK13, this plugin was only stripping Java debug attributes from classes of the output image. Starting JDK13, it has been updated to be more granular and is now, in addition to Java debug attributes, also able to remove native debug symbols from the output custom image.

To invoke it, just append your jlink command with one of the strip*debug* flags but do note the behaviour difference in JDK13.

E.g.jlink --module-path mlib --strip-debug --add-modules com.greetings --output myappruntime

Pre-JDK13 behaviour

  • —-strip-debug : strips out Java debug attributes.

JDK13+ behaviour

  • —-strip-debug : combined debug stripping, i.e. removes the Java debug attributes ( —-strip-java-debug-attributes) *and* the native debug symbols (--strip-native-debug-symbols).
  • —-strip-java-debug-attributes : strips out the Java debug attributes.
  • —-strip-native-debug-symbols : strips out the native debug symbols.

To remove native debug symbols, the strip-debug plugin relies on the native Linux objcopy utility. If it is not installed (ex. on Alpine Linux) or installed in a non-standard location, you will get the following exception:

java.io.IOException: Cannot run program “objcopy”: error=2, No such file or directory

You can solve that by specifying the path of objcopy :

jlink … --strip-native-debug-symbols objcopy=/usr/bin/objcopy …

This is particularly useful when targeting a different platform.

Caveats

  • Some builds (e.g. Oracle OpenJDK builds and Oracle JDK builds) are already stripping the Java debug attributes so —-strip-java-debug-attributes will be of little use with those.
  • objcopy=<path> only works with --strip-native-debug-symbols not with —-strip-debug.
  • —-strip-native-debug-symbols and —-strip-debug are exclusive.
  • Stripping native debug symbols is platform-dependent and is as of now only supported on Linux.

Conclusion

Improved runtime size is especially important when running Java applications in containers as keeping container images small is key. Moreover, it is always a good practice to avoid carrying bits that will never be used. jlink is a tool that every Java developer should consider leveraging to achieve this.

Thanks to Chad Arimura

David Delabassee

Written by

@Java DevRel at @Oracle. Previously @FnProject @JakartaEE & @Java_EE. See also https://delabassee.com

More From Medium

Top on Medium

Ed Yong
Mar 25 · 22 min read
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade