The Java Debugger

J includes a lightweight JPDA-based Java debugger whose main advantage is its integration with j. If you need a more powerful debugger, consider JSwat.


For the debugger to work, j must be able to load classes from tools.jar, which is normally found in the lib directory of your JDK installation. The simplest way to make this possible is to use a startup script that looks like this:

    java -Djava.ext.dirs=[path to dir containing tools.jar] -jar j.jar

There are several other ways to accomplish the same thing. I'll just mention one more:

    java -classpath [path to tools.jar]:[path to j.jar] Main
(On Windows, the ':' should be a ';', of course.)

Currently this second approach is used when you build j from source and do "make install" or "ant install".

The startup dialog

The command jdb (Alt X, "jdb") brings up the debugger's statup dialog.

"Main class" is the fully qualified name of the main class of your application. For example:


"Arguments for main class" should contain any command-line arguments to be passed to the application. For example:

    --force-new-instance --no-session

The value you enter for "Class path" will be passed to the debuggee Java VM as the "-classpath" option. Use the platform-specific path delimiter character (':' for Unix, ';' for Windows).

"Java home" is the value of JAVA_HOME for the debuggee VM. The default is usually acceptable, unless you have some particular axe to grind.

The "Java executable" is normally just "java".

"Arguments for Java executable" should contain any command-line arguments to be passed to the debuggee VM (for example, "-server"). Usually no arguments are required.

If the "Start suspended" checkbox is checked, the Java VM will initially be suspended, and you will need to use the "c" command (or the "Continue" button) to start it.

If the "Start suspended" checkbox is unchecked, the Java VM will start up normally. In this case, if you don't have any breakpoints set, a breakpoint will automatically be placed on the main() method of your application's main class.

"Source path" should contain a list of the directories in which to look for the Java source of the code being debugged. You should specify the root directory of each package tree that you care about. Use the platform-specific path delimiter character (':' for Unix, ';' for Windows). For example:


All of the textfields in this dialog remember their most recent contents, and, like most textfields in j, they have persistent history that can be navigated with the up and down arrows (or Ctrl P and Ctrl N).


When you finally click the startup dialog's "OK" button (or press Enter), the debugger process will start. You'll get a transcript buffer in the lower half of the current editor frame, and a modeless control dialog will appear as a separate, always-on-top top-level window (if you resize it to taste and put it somewhere convenient, j will try to remember where it belongs).

The transcript buffer is read-only. It receives stdout and stderr output from the application, as well as debugger messages. If you print the value of a variable, for example, the results will appear in the transcript buffer.

The control dialog has three panes, with tabs labelled "Stack", "Threads", and "Breakpoints".

When the VM is suspended, clicking on one of the stack frames in the stack pane will navigate to the corresponding location in an editor source window. (Clicking on the topmost stack frame is a good way to get back to the current location if you've ventured off into the weeds.)

When the VM is suspended, clicking on one of the threads in the threads pane selects that thread and updates the stack pane with the selected thread's current call stack (if available).

In the breakpoints pane, you can delete breakpoints by selecting them and pressing the Delete key. Breakpoints may be labelled "(deferred)"; this means that the VM has not yet resolved them. This is normal if the VM has not yet loaded the class containing the breakpoint in question, but it might also mean that the breakpoint is entirely bogus.

The buttons across the top of the control dialog do, for the most part, what their labels suggest.

"Next" executes the current line of code, stepping over method calls.

"Step" executes the current line of code, stepping into any method calls it may contain.

"Step Out" continues execution until just after the current method returns.

"Suspend" suspends execution of the application.

"Continue" resumes execution at the address where the program last stopped.

The "Command" textfield is used to enter debugger commands. If you're debugging a console application, you can use the "stdin" command in the "Command" textfield to send input to stdin of your application.