A Beginner's Guide to Java Debugging


This is intended as a reference guide as well as a tutorial on how to get started with debugging Java programs. For beginners, we assume you have some basic knowledge of Java syntax and the JVM and memory model, and we recommend you start from the beginning. Here is a handy list of links in the document for quick-reference:


Throwables and Reading Stack Traces


Common Exceptions and Errors

There are three distinct classes of error messages Java gives you: checked exceptions, unchecked exceptions, and error messages (generally checked and unchecked fall under the "Exceptions" vs. "Errors" category and is further refined, but since they provide different kinds of information, and involve different debugging styles, we'll treat them separately).

A BRIEF INTERLUDE - DEBUGGING BY println()

When you are running a Java program, as far as we know, we cannot stop it. It either runs to completion or till an error/exception kills it. But what if we need to find out information while the program is running? What if we want to know the contents of a variable at any particular time?

The answer that may already have occurred to you is to use System.out.println(). You can print out the contents or toString() of any variable (this is why it's useful to override toString()). When the program reaches your statement, it will, quite simply, print out what you ask it to. It is generally useful to also print out some sort of label along with your variable so you know what's being printed and don't get confused. If you're printing out the index of a for loop, you may want something like:

System.out.println("i = "+i);
If your program is dying somewhere though and you don't even know where to look or what variables to print out, you can still use the println() debugging method. Take one line, such as:


System.out.println("I'm still alive!");

and place it smack before the return statement or end of the method/piece of code you suspect is causing the error. Run your program. If the words "I'm still alive!" are printed out, you know that your program executes till that point, and you may be looking at the wrong method (you may want to repeat the process one level higher in the call stack). If they aren't printed out, you know the program dies somewhere between the "start" of the program and the "end" of that method.

Now, we need to narrow our scope of where the error could be. Cut and paste the println() statement and put it in another place: right in the middle of the method. Run your program again.

If "I'm still alive" is printed out, you know that the first half of your method runs well, and the problem probably lies in the second half. Repeat the method by placing the println statement in the middle of the second half. If "I'm still alive" is not printed out, the problem lies in the first half. Repeat on the first half. This is called the divide-and-conquer approach, and is a great basic way to start debugging programs (and is how most programmers start out debugging).