Tuesday, February 19, 2008

Line numbers in Java Exception Stack Trace

This post is almost like a note in my java diary. I came across this problem while using the ant javac task. My javac task looked like this:

<javac srcdir="${src.dir}" destdir="${build.dir}">
<classpath>
<fileset dir="${lib.dir}">
<include name="*.jar" />
</fileset>
</classpath>
</javac>


No real problems right? Except the fact that when an exception occured in the code compiled using this task I usually got something like this:

Exception in thread "main" java.lang.NullPointerException: Null
at SampleTrace.main(Unknown Source)

See that "Unknown Source" thing? It makes debugging an unusually hard task. So whats the problem here? The problem is the two attributes of the javac task debug and deubglevel.
These options translate into the -g command line option for javac. These options relate to how much debugging information will be present in class files generated. You can give a combination of three values for this option

  • lines - Line number debugging information.
  • vars - Local variable debugging information.
  • source - Source file debugging information.
Of course, more the debugging information the bigger your class files become. So what do these options really mean in terms of getting an exception stack trace in my program to show me line numbers. My initially understanding was that all I needed was line so that I could get line number information. Right? Wrong! If you are just looking for solution without knowing about the why of it, the answer is:
lines,source - i.e. Make debug="on" and debuglevel="lines,source" in you javac task.

The most important thing to understand is what does the combination of these options do:
  • lines,vars,source - Include all debugging information
  • lines,vars - Include line number information, preserve variable names for method local variables. Line number information is especially useful if you are going to use a debugger to debug your programs.
  • lines,source - line number information and source file information. This is what is required for exception stack trace to work properly.
  • vars,source - Preserve method local variable names as well as source file information.
The source option is what still remains a confusion point. I have tried compiling my class files without that option, but no apparent changes are reflected in my class file as viewed in the decompiler. So any comments are welcome :-)