We look here at various approaches and techniques
for debugging your Java programs.
Print
Statements
A crude but quick, simple, and effective technique for debugging
is simply to place print statements before and after suspect code.
For example, if a program crashes and the error trace indicates
that an array index has gone out of range, then print out the
index as in
int i
= someMethod(y);
System.out.println(" index = "+i+" for y="+y);
double x = 3.3 * anArray[i]; // Getting
array index
//
error message here
From the output you can then work backwards and determine if
the y
value is invalid for the method someMethod(y)
or if someMethod(y)
has a bug, in which case you can place print statements in that
method to debug it.
Assertions
Assertion statements, which became effective with Java 1.4, allow
you to execute expressions
at points in your program to determine if they give the results
that you expect. They provide an effective way to debug both code
errors and the logic of your algorithm (that is, is the program
make sense!)
The two argument assertion statement goes as
assert
expression1 : expression2 ;
where a expression1
returns a boolean value. If the value is false, an AssertionError
will be thrown and expression2
will be evaluated and its return value (with any type allowed
except void)
will be used as an argument in one of the constructors for AssertionError.
The constructor will use the value in its error message.
If only expression1
is included, as in
assert
expression1 ;
then the default AssertionError()
constructor will simply indicate that the assertion failed.
In the above example, we could place an assertion as follows:
int i
= someMethod(y);
assert i < anArray.length : "index = "+i+"
for y="+y;
double x = 3.3 * anArray[index]; //
Getting array index
//
error message here
Here the string will indicate the values of i
and y. When testing only a single variable,
usually the single argument assertion will suffice.
With Java 1.4 you compile programs with assertions in them with
the -source 1.4
option:
> javac -source
1.4 MyProgram.java
Assertions should only execute during debugging (otherwise they
waste processing time) and so should be disabled when they are
not needed. (For this reason, your algorithms should never depend
on the results of assertions.) The -enableassertions,
or -ea,
option flag can turn off assertions for the whole program, for
particular classes and
> java -ea
MyProgram
See the ref.1. for more about programming with assertions.
Error
Trace Capture
When a run time programming error occurs, a dump of the trace
of methods called leading up to the point of the error will go
to the console if you are programming from the command line. This
typically looks rather messy and can be quite long if the error
occured deep into a set of multiple method invocations. However,
usually only the first two or three elements of the trace are
of interest (the first tells where the error actually happened).
With a long dump, the elements of interest can go easily go off
the display.
With Java 1.4 came the StackTraceElement
class. An array of instances of this class, holding information
on each element of the stack trace, can be obtained from an exception:
StackTraceElement
ste[] = e.getStackTrace();
You can then choose to dump only those elements that you want
to dump and to only dump the information, such as class and line
number where the error occured, that you wish.
Following ref. 4, Dumper.java
code allows you to capture the trace elements of interest and
print out only the significant parts of the trace element. Just
put the following try-catch statement:
try {
[method or code block where exception occurs]
} catch (Throwable e) {
Dumper.dumpTrace(e, 5);
}
around the code where you suspect the error is occuring and it
will print to the console only the first 5 elements of the trace.
jdb - Java Debugger Tool
The Java development kits include the jdb
debugger tool. It is a command line tool with a number of options
for adding breakpoints, stepping through a program execution,
evaluating field values, and others. See ref.4 for details of
running jdb.
IDE Debuggers
The various Java
integrated development environments invariably include a debugger.
They allow easy visual insertion of breakpoints into the code
and step through of the processsing.
JConsole
Java 5.0 greatly expanded the JVM monitoring and managment support
capabilites and included the Java Monitoring and Management
Console (JConsole) tool to take advantage of these capabilities.
JConsole provides real time viewing of the performance of applications
and shows their resource consumption. See this article
for details.
References & Web Resources
Most recent update: Oct. 15, 2005
|