javap
might be used to determine what level of debugging a particular Java class was compiled with.The Sun/Oracle javac implementation provides the -g option to control the level of debug support built into the compiled
.class
file. When -g
is not specified at all during the compilation process, the javac
default is that "only line number and source file information is generated." Specifying -g
by itself enables inclusion of "local variable debugging information" in addition to source code and line numbers. The -g
option can also be used to include only one of the three pieces of debugging information. The option -g:lines
includes line numbers, -g:source
includes source information, and -g:vars
includes local variable debugging information. More than one keyword (lines, source, and vars) can be specified with a single -g
option as long as the multiple keywords are separated by a comma.An obvious way to determine which of these types of debug has been included in a compiled class is to actually attempt to access debug information via a debugger or other tool that requires debug information to be available. However, in cases where we'd like to know before firing up such tools,
javap
provides an alternative approach for determining what types of debug information are included in a given .class
file.For the demonstrations of using
javap
to determine the types of debug supported in a given class, I'm using a very simple Java class called SimpleClass
.SimpleClass.java
import static java.lang.System.out; import java.util.Date; /** * Simple class whose primary reason for existence is to demonstrate how javap * can be used to determine if a class was compiled with debug options enabled. */ public class SimpleClass { private Date startDate; public SimpleClass() {} public void printTodaysDate() { out.println("Today is " + new Date()); } public static void main(final String[] arguments) { final SimpleClass me = new SimpleClass(); me.printTodaysDate(); } }
With a simple class defined in Java source code, I can now use
javac
with various -g
options to compile .class
files with correspondingly different debug support. I show the javap
output for each of these and use the differences to explain how to tell what levels of debug javap
is telling us the compiled class supports.Compiling with
javac
Without -g
OptionAs described above, using
javac
without explicitly specifying the -g
option leads to the default debug information of line numbers and source information being included in the compiled class. For this example, the command javac SimpleClass.java
generates a SimpleClass.class
file that javap
disassembles as shown next.Compiled from "SimpleClass.java" public class SimpleClass extends java.lang.Object{ public SimpleClass(); LineNumberTable: line 13: 0 public void printTodaysDate(); LineNumberTable: line 17: 0 line 18: 31 public static void main(java.lang.String[]); LineNumberTable: line 22: 0 line 23: 8 line 24: 12 }
The first line in the
javap
output above (Compiled from "SimpleClass.java") is evidence that the "source code information" was included in the debug. The several lines with line numbers (such as "line 22") are similar evidence of line numbers being included in the compiled class. As expected, javap
's output tells us that line numbers and source code information were compiled into the class.Compiling with
javac
and -g:none
OptionWhen the command
javac -g:none SimpleClass.java
is executed, there is no debug information included in the compiled class. The javap
output, which is shown next, is therefore not surprising:public class SimpleClass extends java.lang.Object{ public SimpleClass(); public void printTodaysDate(); public static void main(java.lang.String[]); }
The
javap
output proves that a Java class compiled with javac -g:none
has neither the source information (no "Compiled from") nor the line numbers that are provided by default.Compiling with
javac
and -g:source
OptionThe
javap
output for a class compiled with javac -g:source
has the beginning line that states where the .class
was compiled from:Compiled from "SimpleClass.java" public class SimpleClass extends java.lang.Object{ public SimpleClass(); public void printTodaysDate(); public static void main(java.lang.String[]); }
Compiling with
javac
and -g:lines
OptionThe
javap
output for a class compiled with javac -g:lines
is shown next. It has the line numbers as did the default case, but lacks the "Compiled from" source information of the default case.public class SimpleClass extends java.lang.Object{ public SimpleClass(); LineNumberTable: line 13: 0 public void printTodaysDate(); LineNumberTable: line 17: 0 line 18: 31 public static void main(java.lang.String[]); LineNumberTable: line 22: 0 line 23: 8 line 24: 12 }
Compiling with
javac
and -g:vars
OptionThe one type of debug output we have not yet seen is that for variable debugging information provided when
javac -g:vars
is used to compile the class. This javap
output is shown next. The LocalVariableTable
output here is the sign that the class in question was compiled with -g:vars
specified. The variables' names are also in the output.public class SimpleClass extends java.lang.Object{ public SimpleClass(); LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LSimpleClass; public void printTodaysDate(); LocalVariableTable: Start Length Slot Name Signature 0 32 0 this LSimpleClass; public static void main(java.lang.String[]); LocalVariableTable: Start Length Slot Name Signature 0 13 0 arguments [Ljava/lang/String; 8 5 1 me LSimpleClass; }
Conclusion
It is easy to use
javap
to determine what types of debug information were compiled into a generated .class
file. When the first line of the javap
output states "Compiled from," we know that source information was included. When we see various lines of the output with the keyword "line," we know that line number information was included. Finally, when we see "LocalVariableTable" in the javap
output, we know that the class was compiled with variable debugging information included.Additional Reference
There was a JDC Tech Tip called Getting Started with javap published on 29 August 2000 that apparently is no longer available in its original form. Fortunately, it is available in an Apache mail forum thread.
No comments:
Post a Comment