Debugging in JBuilder
Christopher M. Judd - Judd Solutions, LLC.
http://www.juddsolutions.com
Introduction
One of Java's many benefits is freedom of choice. Organizations and developers
are not confined by the choice of operating system, application server,
architecture or development tool. Many successful Java projects have been
written using tools like notepad, emacs and even vi. While such tools
are capable and even extremely productive in the right hands, they are
all missing a debugger. Developers often have to revert to displaying
debug messages with System.out.println(). Using a debugger
can increase productivity and stability. Borland's award winning
JBuilder IDE includes a precedent setting integrated debugger capable
of helping developers with locating errors in all forms of
applications including client/server, web and J2EE.
JBuilder's debugger like most Java debuggers uses the Java Platform Debugger
Architecture (JPDA), a standard debugging architecture provided by Java
Virtual Machines. The JPDA is separated in to the Java Virtual Machine
Debugger Interface (JVMDI), Java Debug Interface (JDI) and Java Debug
Wire Protocol (JDWP) specifications. The Java Virtual Machine Debugger
Interface (JVMDI) defines the service level interface implemented by compliant
Java Virtual Machine. The Java Debug Interface (JDI) defines the
interfaces used by UI debuggers like JBuilder. Java Debug Wire Protocol
defines the communications between the two (see resources).

Figure 1 - Java Platform Debugger Architecture (JPDA)
JBuilder provides features to locate and resolve syntax, logical, runtime
and threading errors. Because this paper is intended for an intermediate
audience it will not spend a lot of time detailing each debugging menu
item or button. Instead it will cover beginner topics I receive
the most questions about or find most interesting. The remainder
of the paper will cover intermediate debugging techniques for client/server,
web J2EE and OpenTool debugging. If you desire a detailed explanation
of beginner debugging features please see the JBuilder Documentation
links in the resource section.
Syntax
Syntax errors are caused by introducing incorrect syntax such as forgetting
a semicolon at the end of a statement. Syntax errors prevent code
from being compile and are typically located at compile time. JBuilder
continually compiles the code in the source code editor to provide notification
of syntax errors prior to compiling time. This early feedback increases
productivity by allowing you to resolve syntax errors while you are in
the same vicinity and by reducing the number of compiling attempts.
The notification is provided as error nodes in the Structure Pane (figure
2). Double clicking on the node navigates the editor to the offending
line. I have also found the SyntaxChecker OpenTool (see resources)
valuable in locating syntax errors early. The SyntaxChecker OpenTool
adds an icon to the gutter and underlines offending code with a Microsoft
Word style squiggly (figure 3). SyntaxChecker also provides the
error message as a flyby hint when the cursor hovers over the icon or
squiggly. I have heard some developers complain that SyntaxChecker
works to well and identifies errors on lines before they are even finished
typing it.

Figure 2 - Structure Pane lists errors while JBuilder is passing the
code in the background

Figure 3 - The SyntaxChecker OpenTool provides more obvious indications
of errors while typing
Logic/Runtime
Logic errors are errors that produce unexpected results while runtime errors
are errors that prevent an application from executing normally. Most of
JBuilder's debugging features are intended at locating and resolving logic
and runtime errors since they are more challenging to locate than syntax
errors.
Question #1 - What is the difference between run ( )
and debug ( )?
Run executes the program normally ignoring breakpoints and other debugging
indicators. While debug enables debug features such as step into,
step over and resume program. Debug also stops on lines that include
break points and provides valuable information about threads, call stacks
and watches. Under the covers JBuilder includes the following VM
parameters when the debug option is chosen:
-classic -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_shmem,address=javadebug,suspend=y.
The -classic parameter turns off hotspot which can cause unusual behavior
in the debugger because the native code produced at run time is cache
and executed on subsequent executions giving the appearance the debugger
did not step though the Java code properly. The rest of the parameters
enable debugging. They will be discussed in detail in the J2EE
Debugging section where remote debugging is discussed.
Question #2 - Why does the Runtime Properties dialog popup when I try
to run my application?

Figure 4 - Runtime Properties dialog
The Runtime Properties dialog pops up because there can be multiple executable
classes, classes with a main method, in a project. JBuilder needs
to know which one it should run or debug. Use the ... button to
choose a class containing a main method. Now the Run and Debug buttons
in the speed bar will invoke the main method of that class. This
is similar to creating an executable jar by setting the Main-Class property
in the manifest file to a specific executable class.
Question #3 - Do I have to change the Main class to run another executable
class?
No, as a matter of fact I rarely if ever use the Run and Debug buttons
on the speed bar. Most of my projects have multiple executable classes
that I might want to run. Instead of changing the Main class, I
prefer to run a specific class. The context menu of an executable
class (see figure 5) includes the run and debug options for that specific
class. The ability to execute specific classes is also advantageous
when debugging multiple classes such as in a client/server environment
discussed in the Client/Server Debugging section.

Figure 5 - Run and Debug options are available from the Java file node
context menu
Question #4 - Why do my changes to the project properties not
take effect?
When a program is run or debugged it basically makes a copy of the project
properties at the time of invocation. After project properties
have been changed, the debug window in the message view should be closed
and the executable class should be run or debugged again.

Figure 6 - Message view debugging window
Client/Server Debugging
JBuilder supports debugging multiple processes. This is vital for
debugging applications that include the writing of a client and server
piece. Examples include socket and Java Message Service (JMS) applications.
Using a Run Configuration or the executable class context menu, two separate
processes can be started. Two separate debug windows will appear
in the message view, each having their own debug toolbar.

Figure 7 - Multiple processes appear as multiple tabs in the Message
View each with its own debug toolbar
Web Debugging
Web applications in Java usually involve JavaServer Pages (JSP) and Servlets.
Debugging these can be a challenge because they are managed by a separate
process, a web container. JBuilder simplifies JSP and Servlet debugging
by integrating the popular Apache open source web container, Tomcat (see
resources).
The first step in debugging a web application is to create a web application
using the Object Gallery. Then add customized JSP and/or Servlets
to the project. After placing break points in strategically located
positions, start the debugging process by using the Web Run or Web Debug
from the JSP and Servlet context menu (see figure 8). This starts
an instance of Tomcat listening on port 8080 by default. If port
8080 is already being used by another process it increments the port by
2 until it finds an available port. The debug tab name indicates
the URL available to test the application. The URL can be used by
browsers such as Microsoft Internet Explorer to test your application.
After the Tomcat process is started, Web View and Web View Source tabs
are added to the content pain. The Web View is a web browser that
immediately makes a HTTP request to the web component selected for debugging.
If break points are encountered, the debugger will perform normal debugging.
The Web View Source provides debugging support by displaying the resulting
HTML that the Web View renders. The Web View can provide valuable
information about how the page was generated.
NOTE: Making some changes to JSPs may require the debug process to be
terminated and restarted. JBuilder recompiles the JSPs to determine
executable lines.

Figure 8 - JSP and Servlet debugging is started from the context menu
of JSP and Servlet nodes

Figure 9 - Instance of Tomcat listening to port 8084

Figure 10 - Web View browsing JSP generated page
J2EE Debugging
This section could also be labeled Remote Debugging, the techniques described
here are not specific to J2EE. Remote debugging is the process
of debugging a separate running process that may or may not be separated
by physical machine boundaries. The example for this section is
a Message-Driven bean managed by the open source JBoss application server
(see resources). J2EE debugging requires
remote debugging because J2EE applications are managed and run within
an application server process such as the Borland Application Server or
JBoss.
J2EE Debugging requires configuration in JBuilder indicating which process
to debug and which protocol to use. In addition, the application
server's virtual machine has to be told to enable remote debugging and
to use the same protocols that JBuilder was configured for. JBuilder's
remote debugging properties are available on the Project | Project Properties...
| Debug or the Run | Configuration | Debug tab (see Figure 11).
Enable remote debugging with the associated check box. There are
two choices for remote debugging. Launch requires the installation
of JBuilder's remote debug server so typically I use the Attach option
that allows JBuilder's debugger to attach to an already running process.
The host name indicates the name of the computer running the application
server. Currently there are two choices of Transport (inter-process
communications). The dt_socket is a socket based communications
mechanism and is available on both Windows and Solaris. dt_shmem
on the other hand is a Windows specific mechanism that requires that both
the debugger and debuggee are running on the same machine. As mentioned
above the difference between running and debugging is JBuilder starts
the debuggee process using a dt_shmem transport. Because of dt_shmem's
remote debugging limitations this example uses the dt_socket. The
address indicates which port the VM process is listening to.

Figure 11 - JBuilder remote debugging options
Telling the application server to listen for remote debugging commands
involves passing it the appropriate VM parameters. The following
are examples of the VM parameters passed to the JBoss VM:
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=5000,suspend=y
Debug enables the debugger and noagent disables the old sun.tools.debug
agent. Setting java.compiler to NONE disables the JIT compiler.
Runjdwp starts the JDWP described in the introduction.
JDWP includes options to tell it how to communicate with the JDI.
The transport and address must be set to the same values as the JBuilder
debug properties. In addition, server tells the VM that it is the
process being debugged and suspends tells the VM to start and then wait
for the remote debugger to tell tell it to begin.
@echo off
@if not "%ECHO%" == "" echo %ECHO%
@if "%OS%" == "Windows_NT" setlocal
set JBOSS_CLASSPATH=%JBOSS_CLASSPATH%;run.jar
REM Add all login modules for JAAS-based security
REM and all libraries that are used by them here
set JBOSS_CLASSPATH=%JBOSS_CLASSPATH%
REM Add the XML parser jars and set the JAXP factory names
REM Crimson parser JAXP setup(default)
set JBOSS_CLASSPATH=%JBOSS_CLASSPATH%;../lib/crimson.jar
set JAXP=-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
set JAXP=%JAXP% -Djavax.xml.parsers.SAXParserFactory=org.apache.crimson.jaxp.SAXParserFactoryImpl
set REMOTE_DEBUG=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=5000,suspend=y
echo JBOSS_CLASSPATH=%JBOSS_CLASSPATH%
java %JAXP% %REMOTE_DEBUG% -classpath "%JBOSS_CLASSPATH%" org.jboss.Main %1 %2 %3 %4 %5 %6 %7 %8 %9
pause Listing 1 - Entire remote debugging enabled
JBoss script
OpenTool Debugging
OpenTools are extensions to JBuilder. Setting up OpenTool debugging
requires configuring some libraries and setting some project properties.
Create a library configuration named JBuilder containing the following
jars from JBuilder's lib directory: jbuilder.jar, gnuregexp.jar, jbcl.jar
lawt.jar, xml4j.jar, xerces.jar, parser.jar, jdom.jar, help.jar. Every
jar in JBuilder's lib directory could be added but it is not necessary
and just slows down the loading of JBuilder during debugging. If during
the debugging process other existing OpenTool are needed, added them from
JBuilder's lib/ext directory.
NOTE: Including all the jars in the lib directory will prevent JBuilder
6 and 7 from prompting for a license.
NOTE: If Borland Enterprise Server has been installed and configured
the jars referenced in the lib/ext/bes.properties file may be required
to be on the classpath.
Debugging an OpenTool involves starting a new JBuilder process from within
JBuilder. In the new process the OpenTool is loaded for testing. Enabling
OpenTool debugging requires setting the project properties' Main Class
and Application Parameters. Select Project | Project Properties... Run
tab, set the Main Class to com.borland.jbuilder.JBuilder and the Application
Parameters to -verbose -nosplash. Now pressing the Run Project or Debug
Project buttons will start another instance of JBuilder. Breakpoints and
other debugging techniques work as normal.
NOTE: Notice that JBuilder is nothing more than a collection of
OpenTool APIs. Oops, what was that!!! Yes, JBuilder does throw
a lot of exceptions during the start up process.
Summary
Becoming familiar with JBuilder's debugger can increase productivity
and improve application stability.
Resources
Download Code
Java Soft (www.javasoft.com)
JBuilder Documentation
JBuilder OpenTools (codecentral.borland.com/codecentral/ccweb.exe/prodcat?prodid=3&catid=11)
Open Source
Copyright © 2002 Judd Solutions LLC
|