Recompiling the Java runtime library with debug symbols

The JDK already comes with the sources for the Java runtime library (also known as “rt.jar”) and also the class files are compiled with “LineNumberTable” which makes it possible to set breakpoints on a specified line. However the class files are not compiled with “LocalVariableTable” which means that even when you’re stopped at a breakpoint, you can only look at the method parameters, not at the local variables (hint you can use javap to check if a certain class file contains LineNumberTable, LocalVariableTable, both or neither). Probably this was done to save space, which is understandable in the case of the JRE, but for the JDK it’s annoying.

Fortunately you can fix this! Just use the ant script at the end of this post (or get it here) to build rt_debug.jar. After having built it, you have multiple options to make use of it:

  • Put it in your jre/lib/endorsed directory (create it if doesn’t exists)
  • Specify it using -Xbootclasspath
  • Override jre/lib/rt.jar with it (after making a backup of course!)

I personally used the first method. The only downside is that classes appear twice in the Eclipse type explorer (once for rt.jar and once for rt_debug.jar. Perhaps in the future we will get the rt.jar for JDK compiled with full debug symbols by default.

Final note: the ant script relies on having the JAVA_HOME variable available, so you might need to specify it by hand in case it isn’t set. For example on Ubuntu 14.10 the full command to be run is:

JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 ant -f debug_jdk.xml

Ant script:

Credits for inspiration:

This post is part of the Java Advent Calendar and is licensed under the Creative Commons 3.0 Attribution license. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on!