Debugging Java programs
Debugging is the process of locating and fixing errors in your programs. JBuilder's integrated debugger enables you to debug applications or applets within the JBuilder environment.
The following topics are discussed in this chapter:
If your program uses a DataStore component, see the Designing and debugging a DataStore application topic for additional debugging information.
See also:
Context-sensitive help: The Debugger window
Overview of the debugging process
Modifying program data values during a debugging session provides a way to test hypothetical bug fixes during a program run. If you find that a modification fixes a program error, you can exit the debugging session, fix your program code accordingly, and recompile the program to make the fix permanent.
When the Debugger pauses your program, you can look at the current values of the program data items, including class, instance, and local variables; method parameters; and properties (getter/setter method pairs). You can examine and change the values of data items with the following:
Many debugger features are accessed through the Run and View menus.
The following is an overview of the complete process for debugging Java code. Your code must be compiled with debugging information before you can use the Debugger.
Compiling the project and starting the Debugger
To compile your project and start the Debugger,
- Open your project.
The project appears in the AppBrowser.
- Select File|Project Properties. On the Compiler page, check the Include Debug Information option.
- In the Navigation pane, select the .jpr project node. Choose Run|Debug or click the Debug icon
in the toolbar.
The node automatically compiles, using Build|Make. If the project or class compiles successfully, the Debugger appears.
The left side of the Debugger window now has additional tabs:
Note:
You are in the Debugger when the Source pane displays debug icons in the left margin and the Debug tabs are displayed. If the Debugger does not display after you choose Run|Debug, set a breakpoint on an executable statement and choose Run|Debug again.
Setting breakpoints and stepping through your code
To set breakpoints,
- In the Source pane, set a breakpoint on an executable statement (a statement with a blue dot
in the margin) by clicking in the margin to the left of the statement.
A red circle with a check mark
appears in the left margin, indicating that the breakpoint is valid.
- Choose Run|Debug or click the Debug icon
in the toolbar.
The class runs and stops at the breakpoint.
- To move through your code, select Run|Trace Into to trace into a method call or Run|Step Over to step over a method call.
- Look in the Threads and Stack pane to examine all the program's threads and the stack for each method called.
- Double-click on a method in the stack to display the associated source code.
Editing and recompiling
To edit and recompile your source code,
- When you have found lines of code to change, end the debugging session by clicking the red stop sign icon
in the upper left of the Navigation pane, or by choosing Run|Program Reset.
- Edit your code in the Source pane.
- Right-click the .java node, and select Build|Make on the main menu.
The affected files in your project are recompiled, and you can run the Debugger again.
Types of errors
The Debugger can help find two basic types of programming bugs: runtime errors and logic errors. (The compiler catches syntax errors.) If you find a program runtime or logic error, you can begin a debugging session by running your program under the control of the Debugger.
Runtime errors
If your program successfully compiles, but gives runtime exceptions or hangs when you run it, you've encountered a runtime error. Your program contains valid statements, but the statements cause errors when they're executed. For example, your program might be trying to open a nonexistent file, or it might be trying to divide a number by zero.
Without a debugger, runtime errors can be difficult to locate, because the compiler doesn't tell you where the error is located in your source code. Often, the only clues you have to work with are the results of the run, such as the screen appearance, and the error message generated by the runtime error.
Although you can find runtime errors by searching through your program source code, the Debugger can help you quickly track down these types of errors. Using the Debugger, you can run to a specific program location. From there, you can begin executing your program one statement at a time, watching the behavior of your program with each step. When you execute the statement that causes your program to fail, you have pinpointed the error. From there, you can fix the source code, recompile the program, and resume testing your program.
Logic errors
Logic errors are errors in design and implementation of your program. Your program statements are valid (they do something), but the actions they perform are not the actions you had in mind when you wrote the code. For instance, logic errors can occur when variables contain incorrect values, when graphic images don't look right, or when the output of your program is incorrect.
Logic errors are often the most difficult type of errors to find because they can show up in places you might not expect. To be sure your program works as designed, you need to thoroughly test all of its aspects. Only by scrutinizing each portion of the user interface and output of your program can you be sure that its behavior corresponds to its design. As with runtime errors, the Debugger helps you locate logic errors by letting you monitor the values of your program variables and data objects as your program executes.
Starting a debugging session
After program design, program development consists of cycles of program coding and debugging. Only after you thoroughly test your program should you distribute it. To ensure that you test all aspects of your program, it's best to have a thorough test and debug plan.
One good debugging method involves breaking your program down into different sections that you can systematically debug. By closely monitoring the statements in each program section, you can verify that each area is performing as designed. If you find a programming error, you can correct the problem in your source code, recompile the program, and then resume testing.
To closely examine part of your program, disable Trace Into for all files used in your project, then enable Trace Into on files you want to trace into in the Debugger.
See the Enabling and disabling tracing into classes topic in this chapter.
Compiling with debugging information
Before you can begin a debugging session, you need to compile your project with symbolic debug information. Symbolic debug information, contained in a symbol table, enables the Debugger to make connections between your program's source code and the Java bytecode that is generated by the compiler. These connections enable you to view the source code of your program while running the program through the Debugger, and view data in the Data pane.
By default, JBuilder includes symbolic debug information when you compile. To include symbolic debug information in your program:
- Select File|Project Properties to open the Project Properties dialog box.
- On the Compiler page, check the Include Debug Information option.
When you generate symbolic debug information, the compiler stores a symbol table in each associated .class file.
Note that you won't be able to debug the Java API classes because they were not compiled with debug information. You can, however, trace into the classes. To learn how to trace into these classes, see the Enabling and disabling tracing into classes topic.
Running your program
After compiling your program with debug information, you can begin a debugging session by running your program in JBuilder's debugger. The Debugger takes control whenever you select Run|Debug, Run|Trace Into, or Run|Step Over.
When you run your program under the control of the Debugger, it behaves as it normally would - your program creates windows, accepts user input, calculates values, and displays output. Additionally, the Debugger can pause your program, allowing you to use the Debugger panes to examine the current state of the program. By viewing the values of variables, the methods on the call stack, and the program output, you can ensure that the area of code you're examining is performing as it was designed to.
As you run your program through the Debugger, you can watch the behavior of your application in the windows it creates. Position the windows so you can see both the Debugger and your application window as you debug. To keep windows from flickering as the focus alternates between the Debugger windows and those of your application, arrange the windows so they don't overlap.
Sending command-line arguments to your program
If you are debugging a Java application, and it uses command-line arguments, you can specify those arguments from within JBuilder.
To specify command-line arguments for a Java application from within the IDE:
- Select Run|Parameters.
- Choose the Run/Debug page.
- In the Command Line Parameters box, enter the arguments you want to pass to your program when you run it under the control of the Debugger.
- Click OK.
- Select Run|Debug.
Debugging applets
To debug an applet,
- In the Navigation pane, select the .html file that contains the <APPLET> tag.
- Choose Run|Debug.
- When the Debugger is active, chooseRun|Step Over.
The applet starts in the Applet Viewer, in debug mode. The first line of executable code in your source file is highlighted. If the applet has an init() method, the applet will pause at that location.
Using an HTML file to store arguments
An applet obtains its display size and other parameters from the .html file in which it is stored. You use the PARAM tag to pass parameters to an applet. Note that parameter names are case sensitive.
The following is an example of an .html file file used to pass parameters:
<title>Test File</title>
<hr>
<applet code="Test3.class" width=500 height=120>
<param name=level value="8">
<param name=angle value="45">
<param name=delay value="1000">
<param name=axiom value="F">
<param name=incremental value="true">
<param name=border value="2">
</applet>
<hr>
<a HREF="#Test3.java">The source.</a>
Switching to debugging another project
You can debug one project at a time. To debug another project, if you are already in a debugging session:
- Click the red stop sign icon
in the upper left of the Navigation pane, or choose Run|Program Reset.
The Debugger window closes, and the AppBrowser appears for the current project.
- Use the View|Windows command to choose another AppBrowser.
- Begin a new debugging session.