Sunday Monday Tuesday Wednesday Thursday Friday Saturday
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2

Saturday, December 6, 2014

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!

5 comments:

  1. Keep in mind that rt.jar does not exist in JDK 9. See JEP 220 (http://openjdk.java.net/jeps/220) for more details.

    ReplyDelete
  2. Thanks. It helped me. I re-compiled Src.zip with -g which allowed debugging classes of rt.jar with local variables.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. I have the latest JDK jdk-8u66. When I used this script, I get some 100 errors of missing classes, packages and warnings.

      Ex:
      error: package sun.reflect.misc does not exist
      [javac] import sun.reflect.misc.ReflectUtil;

      : error: package sun.util.locale.provider does not exist

      The same when I tried cmd

      javac -Xdiags:verbose -g -d "F:\Java\BuildJar\tmp\out" -J-Xmx512m -cp "F\Java\BuildJar\rt.jar";"F\Java\BuildJar\tools.jar" @list.txt

      Delete
    2. Never mind. Thanks a ton. I verified the built rt_debug.jar in JAD. The jar is valid inspite of throws errors.
      Worked like charm. :-)

      Delete