Tuesday, March 8, 2011

Debugging Java

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.

123passportphoto is a very easy to use passport photo website that provides six enhanced photos. I have never had an issue while using this ...