The JDK includes a command-line-based debugger, jdb, and there are any number of IDEs that include their own debugging tools. If you’ve focused on one IDE, learn to use the debugger that it provides. If you’re a command-line junkie like me, you may want to learn at least the basic operations of jdb.
Here is a buggy program. It has intentionally had bugs introduced so that you can see their effects in a debugger.
/** This program exhibits some bugs, so we can use a debugger */ public class Buggy { static String name; public static void main(String[] args) { int n = name.length( ); // bug # 1 System.out.println(n); name += "; The end."; // bug #2 System.out.println(name); // #3 } }
Here is a session using jdb to find these bugs:
ian> java Buggy Exception in thread "main" java.lang.NullPointerException at Buggy.main(Compiled Code) ian> jdb Buggy Initializing jdb... 0xb2:class(Buggy) > run run Buggy running ... main[1] Uncaught exception: java.lang.NullPointerException at Buggy.main(Buggy.java:6) at sun.tools.agent.MainThread.runMain(Native Method) at sun.tools.agent.MainThread.run(MainThread.java:49) main[1] list 2 public class Buggy { 3 static String name; 4 5 public static void main(String[] args) { 6 => int n = name.length( ); // bug # 1 7 8 System.out.println(n); 9 10 name += "; The end."; // bug #2 main[1] print Buggy.name Buggy.name = null main[1] help ** command list ** threads [threadgroup] -- list threads thread <thread id> -- set default thread suspend [thread id(s)] -- suspend threads (default: all) resume [thread id(s)] -- resume threads (default: all) where [thread id] | all -- dump a thread's stack wherei [thread id] | all -- dump a thread's stack, with pc info threadgroups -- list threadgroups threadgroup <name> -- set current threadgroup print <id> [id(s)] -- print object or field dump <id> [id(s)] -- print all object information locals -- print all local variables in current stack frame classes -- list currently known classes methods <class id> -- list a class's methods stop in <class id>.<method>[(argument_type,...)] -- set a breakpoint in a method stop at <class id>:<line> -- set a breakpoint at a line up [n frames] -- move up a thread's stack down [n frames] -- move down a thread's stack clear <class id>.<method>[(argument_type,...)] -- clear a breakpoint in a method clear <class id>:<line> -- clear a breakpoint at a line step -- execute current line step up -- execute until the current method returns to its caller stepi -- execute current instruction next -- step one line (step OVER calls) cont -- continue execution from breakpoint catch <class id> -- break for the specified exception ignore <class id> -- ignore when the specified exception list [line number|method] -- print source code use [source file path] -- display or change the source path memory -- report memory usage gc -- free unused objects load classname -- load Java class to be debugged run <class> [args] -- start execution of a loaded Java class !! -- repeat last command help (or ?) -- list commands exit (or quit) -- exit debugger main[1] exit ian>
There are many other debuggers available; a look in the current Java magazines will inform you of them. Many of them will work remotely, since the Java debugging API (that which the debuggers use) is network-based.
Get Java Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.