You’re getting an exception stack trace at runtime, but most of the important parts don’t have line numbers.
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 catches it 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 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, until recently 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 tradeoff of making the program run faster, but harder to debug. The latest 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. In the JDK 1.2 (Java 2), you need only set the environment variable JAVA_COMPILER to the value NONE, using the appropriate set command.
C:> set JAVA_COMPILER=NONE # DOS, MS-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 Windows NT, you could also set this in the System Control Panel. You might well wish to make this setting the default, since using the JIT does take longer for startup, in return for faster execution. I ran JabaDex, my personal information manager application (see http://www.darwinsys.com/jabadex/) six times, thrice with JIT and thrice without; the results appear in Table 1-1.
Table 1-1. JIT and NOJIT timings
With JIT |
NOJIT |
---|---|
46 seconds |
34 seconds |
37 seconds |
28 seconds |
34 seconds |
29 seconds |
Average: 39 seconds |
Average: 30.3 seconds |
As you can see, the average startup times are nearly 25% faster without JIT. Note that this includes reading a 500-line file and scanning it; that part of the code would definitely benefit from a JIT. Ideally we’d have selective control over JIT.
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.
On earlier releases, there was a command-line flag
-nojit
, but this was discontinued in favor of the
more verbose -D
option.
As mentioned, Sun’s new HotSpot JIT -- included in many JDK 1.2 and JDK 1.3 releases -- generally provides tracebacks even with JIT mode enabled.
18.227.10.45