Recipe 1.15 Getting Readable Tracebacks


Problem

You're getting an exception stack trace at runtime, but most of the important parts don't have line numbers.

Solution

Be sure you have compiled with debugging enabled. On older systems, disable JIT and run it again, or use the current HotSpot runtime.

Discussion

When a Java program throws an exception, the exception propagates up the call stack until there is a catch clause that matches it. If none is found, the Java interpreter program that invoked your main( ) method catches the exception and prints a stack traceback showing all the method calls that got from the top of the program to the place where the exception was thrown. You can print this traceback yourself in any catch clause: the Throwable class has several methods called printStackTrace( ).

The traceback includes line numbers only if they were compiled in. When using Sun's javac, this is the default. When using Ant's javac task, this is not the default; you must be sure you have used <javac debug="true" ...> in your build.xml file if you want line numbers.

The Just-In-Time (JIT) translation process consists of having the Java runtime convert part of your compiled class file into machine language so that it can run at full execution speed. This is a necessary step for making Java programs run under interpretation and still be acceptably fast. However, in the early days of Java, its one drawback was that it generally lost the line numbers. Hence, when your program died, you still got a stack traceback but it no longer showed the line numbers where the error occurred. So we have the trade-off of making the program run faster, but harder to debug. Modern versions of Sun's Java runtime include the HotSpot Just-In-Time translator, which doesn't have this problem.

If you're still using an older (or non-Sun) JIT, there is a way around this. If the program is getting a stack traceback and you want to make it readable, you need only disable the JIT processing. How you do this depends upon what release of Java you are using. On JDK 1.2 and above, you need only set the environment variable JAVA_COMPILER to the value NONE, using the appropriate set command:

C:\> set JAVA_COMPILER=NONE # DOS, Windows setenv JAVA_COMPILER NONE                   # Unix Csh export JAVA_COMPILER=NONE # Unix Ksh, modern sh

To make this permanent, you would set it in the appropriate configuration file on your system; on recent versions of Windows, you can also set environment variables through the Control Panel.

An easier way to disable JIT temporarily, and one that does not require changing the setting in your configuration files or Control Panel, is the -D command-line option, which updates the system properties. Just set java.compiler to NONE on the command line:

java -Djava.compiler=NONE  myapp

Note that the -D command-line option overrides the setting of the JAVA_COMPILER environment variable.

As mentioned, Sun's HotSpot JIT runtime included in most modern Java releases generally provides tracebacks, even with JIT mode enabled.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net