Pramati Technologies

Debugging Application

EJB applications are complex in nature and the user typically writes the business logic and would want to debug only the business logic. Traditional debuggers cannot handle this but Studio debugger can.

Studio offers a smart debugger designed to help the developer find and fix bugs across all tiers of an enterprise application. Use the debugger to:

The Debugger and its features have been explained using a series of examples. To know how to use the debugger, read the entire chapter. The examples used are:

iBank to understand the Debugger in general and

Game of Eight to understand Conditional Debugging.

JSP Debugging assumes that the application has been deployed on the in-built Pramati Server.

Starting the Debugger

Follow the given steps to know how to start the debugger:

  1. Open the BankDesk sample from the following location <install_dir>/samples/ejb11/BankDesk/BankDesk.dsk. This brings up the sample Desk.
  2. To debug the application, you will need to start it in the debug mode. Access this using: Debug > Start from the main menu.

This brings up the Debugger Settings dialog with two tabbed panes: Debug and Source.

The first pane is where the Debug options are to be set. The three options provided are - Applications for J2EE, Remote Application and Other.

Application for J2EE This option is selected when the application being debugged is a J2EE application. This option is selected when deployed application is to be debugged on any one of the configured servers from inside Studio.

Remote Application This option is selected when the application is to be debugged remotely. Enter the IP Address and Port number before debugging the application remotely. For more details the section - Remote Debugging.

Other This option is selected for any other application. Enter the main class name in the Main Class field.

JVM Options To debug the application using some special JVM options, use this field. This field is optional.

  1. In this panel, select the option Application for J2EE, and leave the JVM Options blank.
  2. Click on the tab Source.

This panel lists the sources to be debugged. The following are the paths that can be edited:

Source Path Decide all the sources to be debugged. If you remove a specified source path using the button with the subtract icon, the Debugger does not debug the particular file. You can also add Java sources using the Add button.

Class Path This helps add any additional classes required for debugging the application and the same can then be removed.

  1. The source path and class path are already set here. Click OK.

This starts the Server in the debug mode. The next step for the user is to explicitly deploy the application or modules whichever is required.

Troubleshooting

While starting the Debugger, if the error message "no `classic' JVM at <jdk_install_dir>/jre/lib/sparc/classic/libjvm.so'. Server Stopped" is displayed, then follow the given steps and restart the Studio:

  1. Open the file runstudio.bat from under the Studio installation directory
  2. Set the system property, com.pramati.useClassicVM to false by typing -Dcom.pramati.useClassicVM=false after the command java

Deploying the application

The following section describes how to deploy applications that are to be debugged in Studio.

  1. To deploy the application, right click on the Desk tree node in the Explore Panel > Deploy.

This deploys the Desk using Express Development. If there are references to be added or any mappings to be completed, the Deploy tool comes up.

Managing Breakpoints

The next step to perform is to set breakpoints in the application. To know all about breakpoints, read the following sections.

How does a Breakpoint Work

While large enterprise applications are typically multi-threaded in nature, even simple Java programs do have many threads executing.

Once the execution of a thread in a program being run in debug mode reaches a breakpoint in the code, it stops. At this point, the thread is suspended and the stack for this thread can be inspected. Other threads execute asynchronously but are not shown in the combo box.

When To Set a Breakpoint

Breakpoints should be inserted on an executable line of code either before or after the Debugger has been started.

Where to Set a Breakpoint

Breakpoints can be set on any executable line of code in Java or JSP file. The execution is stopped when the control flow reaches the line on which the breakpoint has been applied. The JSP file can be debugged only when the application has been deployed on the in-built Pramati Server.

A breakpoint on a comment line or a blank line is ignored, as the control flow in a program does not pass through such lines.

Inserting Breakpoints

Debug > Insert Breakpoint

The above-mentioned method inserts the breakpoint at the specified line. Alternatively, right click the line on which the breakpoint is to be set and choose on Insert Breakpoint. This can be performed using the keyboard shortcut, F9.

  1. In the sample BankDesk, insert the breakpoint in the jsp file transfer.jsp on the following executable line of code, t.transfer(fromAccID, toAccID, amount);
  2. Go back to the browser and click on Transfer in the browser and transfer account from account number 101 to 102 an amount of 100.

Removing Breakpoints

Debug > Remove Breakpoint

The above-mentioned method removes the breakpoint from the specified line. Alternatively, right click on the line on which the breakpoint set is to be removed, and choose on Remove Breakpoint.

Launching the JSP

This section describes how to launch the JSP.

  1. Right Click on the jsp file bank.jsp > Run.

This will directly launch the JSP in a browser set by you. The specified browser comes up with the following URL: http://127.0.0.1:8181/bankWeb/bank.jsp where bankWeb is the context root for the application.

Parts of the Debugger

After accessing the application, go back to Studio again. Studio now looks

like this:

The Debugger is composed of the following parts:

Editor

The editor contains the pop-up menus for toggling breakpoints set in Java or JSP code. The editor highlights the line where the control is paused.

Output Tab

The Output tab comprises a TextField and a TextArea. The TextField is used for entering command line inputs. The status and error messages from the debugger and the program output are displayed in the TextArea. In case of remote debugging or J2EE debugging, the Output Tab is not displayed.

ControlFlow Tab

This tab contains two combo boxes, two buttons, and the list displaying the ControlFlow:

VM Combo

It displays the different VMs in which the applications are being debugged.

Thread Combo

It lists the user threads that are suspended, and also shows the thread hierarchy.

Enable

This button allows debugging of the application. It is enabled by default. When the button is disabled, it disregards all breakpoints and continues execution.

GO

This button continues execution until it reaches the next breakpoint.

ControlFlow

This button displays the flow of control. It is not the complete stack trace, but is filtered to show only those entries for which the source files are available.

The list shows the stack trace at the point where the execution of the program has been paused at some line due to a debug event. Like when a breakpoint is reached or after executing a step. It displays how the control has reached this point. Clicking on one item will open the file in the editor, with the particular line number highlighted.

A debug event is when program execution pauses at a breakpoint or watchpoint. The debugger displays the stack only for those threads that are suspended. So, if two threads reach a breakpoint, separately, their stacks would be shown separately. All suspended threads are shown in the Thread Combo. When a suspended thread from this combo is selected, the trace for this thread is shown.

Variable Viewer Tab

It shows the stack at the point of execution. Variables are classified as Class Level (applicable throughout the class) and Local Level (applicable in a local scope). The name and value of each of the type of variable is displayed in the Variable Viewer in two separate panes. If the variable is an Object or an array, the contents are displayed in the tree format.

The values of variables in the Variable Viewer tab can be changed while the application is being debugged. These variables have to be primitive variables or Strings. To change the value of the variable, click on the variable value in the Variable Viewer tab and enter a valid value for that data type.

Viewing Stack

The Variable Viewer shows the stack at the point of execution. Variables are classified as Class Level (applicable throughout the class) and Local Level (applicable in a local scope). The name and value of each of the type of variable is displayed in the Variable Viewer in two separate panes.

Drilling Down into Arrays and Objects

If a variable is an array (or an object), its name is shown in red (or blue). By double clicking on it, the internal structure of the object can be seen.

What's a Stack Frame

VM maintains the local variables on the stack separately for each namespace. This is called the Stack Frame. When the control flows from one namespace to another, variables in the new namespace are maintained separately on a different Stack Frame.

Frames Stack up to form Stack Trace

VM maintains stack frames in an order called the Stack Trace. The frames are arranged with the latest one on top (control flow is bottom up). So by studying the stack, one can see how the control reached a point.

Reading a Stack Trace

The stack trace shows only those frames for which the code is present. Therefore, while debugging Enterprise JavaBeans, those frames maintained for the containers, for instance, are not shown. This makes the stack trace easy to infer.

By single clicking on a stack frame, you can bring up the file into the editor, with the line number highlighted. In the output panel, the Variable Viewer shows class and local variables at that location.

Thread scheduling is fully dependent on the Operating System. Potential dead lock situations cannot be predicted. Thread scheduling is different when the application is run in the debug mode. So it is possible that the application executes as expected when you trace it step by step in debug mode but not when run in non-debug mode.

Controlling Program Execution

Once you have set the breakpoint and started the debugger, the following functions can be performed after the first breakpoint is reached:

Stepping In, Over and Out of Methods

Debug > Step In/ Step Over/ Step Out

The debugger will pause at the breakpoint. You can then step into the method, step out of method, step over a method, and resume the thread that has been suspended.

STEP IN

Case #1: Next line of code is not a method call.

In such a case, the debugger simply executes the code and stops immediately after.

Case #2: Next line of code is a method call.

The debugger, in this case will stop in the first line of code of the method that has been called, provided you have the source code for it.

If you do not have the source code for the method called, then the debugger just executes that method and stops

Stepping into Java core classes and Pramati classes is not allowed. This way you step into classes for which the source code has been written.

  1. Click on the Step In button on the tool bar. As the next line of code is a method call, the control shifts to the line Object obj = ic.lookup("java:comp/env/ejb/MyChecking");in the bean file TransferBean.java. This is called transparent debugging, where the control smoothly flows from JSP files to EJB files and back. Note that this happens only when the application has been deployed on the in-built Pramati Server.
  2. View all the class variables and local variables by clicking on the Variable Viewer tab. This displays the values of the variables.

STEP OVER

Irrespective of the next line of code being a method call or not, the debugger executes the line of code, and the control stops at any breakpoint it encounters, or immediately after. This is conditional on the availability of the source for the next line of code to be executed. The debugger does not stop if the next line of code to be executed is in another class for which you do not have the source.

  1. Click on the Step Over button on the tool bar. As the next line of code is not a method call, the debugger stops at the next line of code CheckingHome home = (CheckingHome)(obj); and highlights that line.

STEP OUT

The debugger executes the current method and the control

This is conditional on you having the source code. When execution of a logical block of code ends, if you step in or step over, then the execution stops at the beginning of the logical block and highlights that point.

  1. Clicking on the Step Out button on the tool bar returns the control to the calling method - transfer.jsp, and highlights the line transferred = true;

If you step in or step over a line of code that is not a "break" or a "return" statement, then

Step In/Step Over at
Highlight Position
Last line in a try block
The beginning of the try block
Last line of method
Declaration of method
Last line of condition
The condition

The above is true of any JPDA compliant debugger. If a line of code has multiple statements (implicit or explicit), and you step in, the debugger still highlights the same line. This happens because the debugger is trying to step into the method calls it encounters and bounces back because you do not have the source for it.

Example

Consider this line of code: System.err.println("The value of object x is "+x); Here the '+' overloaded operator actually is a method call to the append() method of class StringBuffer and the call to the toString() method of object x is not so obvious.

A breakpoint cannot be set on a line that contains a non-executable line of code. While debugging, this location will display a message saying no executable line of code there.

GO

Click on the button GO in the ControlFlow tab to resume a thread. When this command is used, the debugger executes the code till it reaches the next breakpoint.

Changing Current Thread

Use the combo box in the ControlFlow tab, which displays a list of all threads that exist in the application. Using this list, select the thread.

  1. After performing all the steps, you can Step In, Step Over or Step Out as many times as required, to debug the application further.

Conditional Breakpoints

To understand when to use conditional breakpoints, open the samples jspDesk from the following location <install_dir>/samples/ejb11/jspDesk/jspDesk.dsk. This brings up the Desk, jspDesk in Studio.

  1. Double click and open the file JavaHelloWorld.java from the following location jspDeskWeb.
  2. Click on Debug > Conditional Breakpoint on the main menu. This brings up the Conditional Breakpoint dialog.

Conditional breakpoints are set when the breakpoint should stop the control flow at the executable line of code, only when the condition is true. The following properties have to be set here:

The conditional statement supports conditions only when the variable is of the number type. At runtime, if the Debugger is unable to understand the condition, then the breakpoint is treated like any other breakpoint.

  1. In the dialog that comes up, set the following conditions:
    • File Name <install_dir>/samples/ejb11/jspDesk/jspDeskWeb/JavaHelloWorld.java
    • Line No 19
    • Condition i > 3

This stops the execution of the debugger when the value of i is greater than 3.

  1. To start debugging the application, use Debug > Start form the main menu. This brings up the Debugger Settings dialog box. In the Debug tab,
  2. Choose Other
  3. Enter the Main Class as JavaHelloWorld and
  4. Click OK.

This starts the debugger and the control stops at the line of code, where the conditional breakpoint has been set.

  1. To continue debugging the application further, execute Step Over on each line of code and view the local variables change its value in the Local Variables tab. The variables in this tab can also be changed manually while the application is being debugged.

Remote Debugging

The process of running code on one computer from another computer is called Remote Debugging. Remote debugging should be used in cases, where an application encounters a problem on one networked computer that cannot be duplicated on other computers.

The computer where the application is debugged from is known as the Client Computer. The computer where the application to be debugged is running is known as the Remote Computer.

To debug applications remotely using Studio the application the following steps need to be followed:

  1. The Desk which contains the files to be debugged has to be opened in Studio.
  2. The next step is to launch the application on the remote virtual machine in the debug mode. This starts the Virtual Machine where the application is to be debugged.
  3. Next, the user has to go back to Studio and insert breakpoint using Debug > Insert Breakpoint at any executable line of code.
  4. The application can then be debugged from the Client Computer using Debug > Start. This brings up the Debugger Settings dialog box, where the user fills in the following information:
    • Check the checkbox Remote Application.
    • Enter the IP Address. Example: localhost.
    • Enter the Port number. Example: 1234.
    • Click OK.
  5. This starts the Debugger on the Client Virtual Machine and connects to the Remote Virtual Machine.
  6. Running the file to be debugged by right clicking on it in the Explore Panel and selecting Run starts debugging the application remotely and the control flow stops at the line where the breakpoint was set.
  7. To continue debugging the application, use Step In, Step Out and step over as explained before.

Options for Remote Debugging

Option
Description
portNumber
a port number between 1024 (1k) and 65536 (64k)
-Xdebug
Start application in debug mode. An application can be debugged only if it is started in the debug mode. While the default support is set to sun.tools.debug agent, it supports the new JPDA too.
-Xnoagent
Sun's classic VM supports both sun.tools.debug interface and the new JPDA. This option inhibits sun.tools.debug and turns on only JPDA. HotSpot VM does not support these options.
Djava.compiler=NONE
JDK 1.3 ignores this option. The option disables the JIT (Just In Time) compiler and the byte code is interpreted the first time and cached for subsequent calls. If this option is disabled, the VM acts as a simple interpreter.
Xrunjdwp:<sub-options>
Loads the JPDA reference implementation of JDWP according to the sub-options.
transport
The JPDA reference implementation provides a socket transport for both Solaris and Win32 platforms. The socket transport uses standard TCP/IP sockets to set communication links between debugger applications and target VM.
Server
If "y", listen for a debugger application to attach; default value is 'n'.
Address
If server=y, listen for a connection at this port.-Xdebug -Xnoagent -Djava.compiler=NONE - Xrunjdwp:transport=dt_socket,server=y,address=portNumber,suspend=n

Some Limitations

Disconnecting the Debuggee

Use the Debug > Disconnect from the main menu to disconnect the debuggee. This functions differently for different types of debugging.

Debugging on Oracle and WebLogic Servers

Applications deployed on Oracle and WebLogic Servers can also be debugged from inside Studio. Refer subsequent chapters for details on working with WebLogic Server 6.1 and Oracle 9iAS.

JSP debugging

JavaServer Pages are converted into Servlets and Servlets are compiled to get the .class file. The Debugger maintains a one-to-one map of lines in the Servlet to lines in the JSP that is created at compilation time. Thus when a breakpoint is set in a JSP, The Debugger reads the map and sets the breakpoint in the corresponding line in the Servlet. Subsequently, breakpoint or step-in events return the appropriate lines in the JSP. This makes JSP debugging smooth.

JSP Debugging requires that the application has been deployed on the in-built Pramati Server.

EJB debugging

Enterprise JavaBeans allow developers to write complex business components in a single-threaded fashion. Though, inside the application Server, the EJB runs in a multi-threaded environment.

A bean call actually invokes a function on a stub. Studio Debugger auto-discovers calls made to bean methods and sets implicit breakpoints in the bean code.

Subsequently, a thread re-directed from a breakpoint in the JSP to the bean code hits the implicit breakpoint and pauses. This control flow to the method seems like any other Java step-into process.


Pramati Technologies  © Copyright   TOCPREVNEXTINDEX