This chapter describes how to debug Service Bus pipelines and split-joins by setting breakpoints in the message flow and using the JDeveloper debugger. It includes the following sections:
JDeveloper provides a comprehensive integration debugger to help you assess and solidify your Service Bus project components. The debugger reduces the development cycle by providing troubleshooting capability directly in the development environment. This means you do not need to build a Service Bus application in JDeveloper, run it, and then return to JDeveloper to fix any issues and repeat these steps. Instead, you can set breakpoints directly in JDeveloper for troubleshooting on pipelines and split-joins.
The debugger can handle Java callouts and supports multi-threaded debugging on split-joins that use parallel processing. Note the following guidelines when using the debugger:
Debugging is limited to design view in JDeveloper.
You cannot debug most cross-language features, such as a Java callout action, XQuery transformations, and so on. Support for debugging XSLT maps is new for the 12.2.1 release. See XSLT Editor Debugging Support for more information.
Only one client at a time can connect to the debugger.
You can only debug if the server is in development mode.
The debugger cannot be enabled in production mode or when the server is part of a cluster or an Administration Server plus one or more Managed Servers in a non-clustered domain.
See Introduction to the SOA Debugger in Developing SOA Applications with Oracle SOA Suite for additional guidelines for using the SOA debugger.
For general information about the debugger windows, see "Running and Debugging Java Projects" in Developing Applications with Oracle JDeveloper.
You can debug the Service Bus components that are deployed on an integrated or standalone WebLogic Server. JDeveloper can manage the lifecycle for a local integrated WebLogic server instance. When you configure a local integrated server, you can select Let JDeveloper Manage the lifecycle for this server instance. With this configuration, JDeveloper starts the server when you select the Run or Debug command. If the integrated server is not configured to be managed by JDeveloper, you need to manually start and stop the server; however you can still use the Run command to deploy the service to be tested to the server. If the integrated server is remote, do not select Let JDeveloper Manage the lifecycle for this server instance.
When you use a standalone server for debugging, the configuration is the same whether it is local or remote. You do not need to configure the server in the application properties. With a standalone server, you cannot use the Run command from the Application Navigator. Instead, you need to manually deploy the Service Bus application to the server using the Deploy command, and you need to start the test console manually.
Debugging can be performed on either a local or remote WebLogic server. A local debugging session is started by setting breakpoints in source files, and then starting the debugger. When debugging a Service Bus component, you have complete control over the execution flow and can view and modify values of variables.
Remote debugging requires two JDeveloper processes: a debugger and a debugee. The debugee is a running server that may or may not be defined in JDeveloper and may reside on a different platform. A Service Bus application must be deployed on the debugee server. In order to perform remote debugging, you must configure a run configuration in the project properties, as described in How to Create Run Configuration for Remote Debugging.
A breakpoint marks a point in a pipeline or split-join where message processing pauses. This lets you examine the values of some or all of the message variables. By setting breakpoints in potential problem areas of your message flow, you can run data through a message flow until it reaches a location you want to debug. When a breakpoint is encountered, message processing pauses and the debugger focuses on the action containing the breakpoint in the source editor. You can then use the debugger to view the state of your program. Breakpoints are flexible in that they can be set before you begin debugging or at any time while you are debugging.
Breakpoints can be added to the following nodes on a pipeline:
Pipeline pair path (request or response)
Stage (both in pipeline pairs and error handlers)
Stage action (both in pipeline pairs and error handlers)
You can add breakpoints to all split-join actions, but toggling a breakpoint on an If node toggles the breakpoint for the If condition within the If node and not the If node itself.
Conditional breakpoints stop code execution when a specified condition is true. Conditional breakpoints are supported in this release of Service Bus and JDeveloper. You can add conditions to any breakpoint used for debugging Service Bus applications.
You can also use pass counts to stop code execution when the breakpoint has been passed the number of times you specify without triggering. You can use conditional expressions and pass counts together.
See the following topics for additional information:
How to Edit Breakpoint Options to edit a breakpoint’s Conditions tab to add a conditional expression or a pass count
Conditional Expression Behavior for conditional expressions behavior in JDeveloper
About Pass Counts for pass count behavior in JDeveloper
Using a Conditional Expression and a Pass Count Simultaneously for using conditional expressions and pass counts at the same time
Follow these guidelines when creating conditional expressions for breakpoints when debugging Service Bus components in JDeveloper.
The expression may reference only data values in the top-most stack frame. Consider the example in Figure 57-1:
Figure 57-1 Data Values in JDeveloper
In this example, any of the following expressions are valid conditional expressions:
$inbound.security.transportClient.username == “fred”
$messageID.indexOf(“8087”) > -1
Many data values in Service Bus are of an XML type; it is possible that multiple items with the same name reside under a single parent. Treat this type of structure as an array in conditional expressions. Consider the structure of
$inbound.security.transportClient.principals in Figure 57-1. There are four elements in that location. The following conditional expressions can be used to access a specific element in this group:
$inbound.security.transportClient.principals == “AdminChannelUsers”
$inbound.security.transportClient.principals == “Monitors”
In Figure 57-1, the
$outbound variable has a value of
null. In this case,
null is a string value. The correct conditional expression representing the
null string value is
$outbound == “null”. If there were no value present for the
$outbound variable, the correct conditional expression is
$outbound == “”.
Spaces are not allowed as characters in variable names in conditional expressions. Spaces within variable names must be changed to underscores (_). Using the
Java Repository variable from Figure 57-1 as an example, the variable is referenced in a conditional expression in the following manner:
Java_Repository.jcid:null == “ref”, replacing the space in the variable name (
Java Repository) with an underscore (
You are notified if a conditional expression fails to evaluate because it is an invalid expression (logically or syntactically) or if it cannot be evaluated as a boolean value for any reason.
If you do not clear these notifications they are available for the remainder of your JDeveloper session. In addition to the notification, JDeveloper logs any conditional expression evaluation errors.
Thread options are not supported when debugging Service Bus applications.
A pass count is a value that specifies how many times the breakpoint should be passed over during execution before stopping. When this value is reached, code execution is stopped at this breakpoint. Pass counts are supported for breakpoints in this version of Service Bus and JDeveloper.
When the execution process comes to a breakpoint where Pass Count is set, the debugger reduces the count value by 1 and compares it to zero. If the result is not zero, execution continues without stopping at this breakpoint. If the result is zero, execution stops at this breakpoint. After the pass count has been met, execution will stop at the breakpoint every time for the remainder of the current process.
After a pass count reaches zero, execution stops at the breakpoint every time until the pass count is reset or cleared, as described below.
The pass count is reset in the following cases:
The debugging session is terminated and restarted.
You update the value in the Pass Count field on the Edit Breakpoint dialog.
You can clear a pass count from a breakpoint by setting its value to zero from the Edit Breakpoint dialog.
You can specify both a conditional expression and a pass count for a breakpoint. With both of these set, the expression must evaluate as true and the pass count must be reached for execution to stop at a given breakpoint.
As an example, if the conditional expression evaluates as true, but the pass count is set at 10, execution will not stop at this breakpoint until the pass count condition is also met. When both a pass count and condition are specified, the pass count is always checked first and decremented if not already zero. After the pass count is reached, the conditional expression is evaluated each time the breakpoint is hit.
Unlike standard breakpoints, which specify a location at which to halt execution, exception breakpoints halt execution at the origin of an exception of a specified type. Exception breakpoints are supported in this release of Service Bus and JDeveloper. You can create exception breakpoints for pipelines and split-joins.
When an exception breakpoint is triggered, the debugging framework is notified and provided with the location at which to halt execution. When execution is halted, you can review the following information:
The exception type being raised; this is useful you created the exception breakpoint using a wildcard
A message about the exception
The stack trace of the underlying exception thrown by the runtime, if avialable
The stack frame and the data values when execution was halted.
If multiple enabled exception breakpoints match the raised exception type, the debugging framework selects the breakpoint that exactly matches the exception (for instance, an exception breakpoint without a wildcard) or the first breakpoint set with a wildcard.
Conditional expressions and pass counts are supported for exception breakpoints. See About Conditional Breakpoints for more information about conditional expressions and pass counts..
See the following topics for additional information about using exception breakpoints with Service Bus components:
The pipeline runtime throws
PipelineExceptions contain error codes that you can set (using the Raise Error action) or are set by each action.
You can choose the following exception types for pipeline exception breakpoints:
All Pipeline Exceptions: Use this type to halt execution when any pipeline exceptions are thrown, specifically those without explicit error codes..
Pipeline Exception:Use this type to halt execution when pipeline exceptions with an explicit error code is thrown. For example, entering 382510 into the Error Code field halts execution when a pipeline exception with an error code of 382510 is thrown.
You can enter an asterisk (*) in the Error Code field to catch any pipeline-specific exceptions.
System Exceptions:Use this type for any unexpected exceptions thrown by the runtime.
See How to Set Exception Breakpoints for Service Bus Components for information about adding pipeline exception breakpoints.
Split-joins are based on the BPEL language. The BPEL error handling framework uses faults and fault handlers. Faults are defined by QNames. Split-joins have a set of BPEL language-defined faults; additionally, you can define your own faults manually or by using WSDL faults.
You can choose the following exception types for split-join exception breakpoints:
All Split/Join Exceptions: Use this type to halt execution when any split-join exception is thrown.
All System Exceptions: Use this exception type to halt execution when any runtime exception is thrown.
Spit/Join Exception: Use this type to halt execution when a specific split-join error is thrown. For example, entering userFault into the Error code field halts execution when a split-join fault named
userFault is thrown.
System Exception: Use this type to halt execution when a specific runtime error is thrown.
See How to Set Exception Breakpoints for Service Bus Components for information about adding split-join exception breakpoints.
JDeveloper provides several different debugging windows with the debugger, where you can view and analyze data as it moves through the debugging process. Service Bus utilizes the following debugging windows:
For more information about these windows, see "Using the Debugger Windows" in Developing Applications with Oracle JDeveloper.
Starting in 12.2.1, JDeveloper has been enhanced to debug XSLT maps using the SOA Debugger.
You can invoke this feature from Service Bus split-join and pipeline editors and from the XSLT test tool in JDeveloper. For information on debugging XSLT maps and setting breakpoints in the XSLT map editor, see Debugging the XSLT Map in Developing SOA Applications with Oracle SOA Suite.
You can configure project and debugger settings to control the debugging process. Settings that control the way programs are debugged or run are defined in run configurations. These settings include such things as the target, launch options, and the behavior of the debugger, logger, and profiler. Service Bus provides a default run configuration for local debugging and testing, but you can create new configurations. A project may have several run configurations, each set up for a specific facet of the project or phase of the development process. A run configuration can be bound to the project and be available to all who work on the project, or it can be custom configuration, for your use only.
These steps are optional, and you can perform local debugging using the default configuration with the integrated server. For more information and instructions, see the following topics in Developing Applications with Oracle JDeveloper:
You create a new run configuration by copying an existing configuration, such as the Default configuration provided with Service Bus. Then you modify the settings for the new configuration
To create a run configuration for remote debugging:
For more information about any of the windows and fields you work with on the run configuration windows, click Help.
The Edit Run Configuration window appears with the Launch Settings page displayed.
To connect a specific server automatically when you select this run configuration, enter the host name, port number, and a timeout value.
To display a dialog that lets you enter host information when you select this run configuration, select Show Dialog Box Before Connecting Debugger.
If you perform both of the above steps, the dialog appears when you select the run configuration, and is already populated with the connection information you specified above.
A default run configuration is created for each new project, and it uses the integrated WebLogic server for local debugging. You can select this default or any other configuration you have created to run a selected project. If you run the debugger from the JDeveloper toolbar, you can select the run configuration from the list of configuration options available next to the Debug icon.
To choose a run configuration for debugging:
There are several ways to start the JDeveloper debugger. The instructions in this chapter use the Application Navigator to start the debugger, but you can use any of the following methods to start the debugger when you are ready.
Right-click a project or component in the application and select Debug.
In the JDeveloper toolbar, click the Debug icon. The debug process uses the selected run configuration. See How to Choose a Run Configuration for Debugging.
Right-click a pipeline or split-join in the Service Bus Composite Overview Editor and select Debug.
Right-click in the editor of an open pipeline or split-join and select Debug.
This section describes how to start the debugger, create breakpoints, and debug Service Bus applications in JDeveloper. There are ways to debug other than using the Test Console and debugger. You can also run your service in other ways, such as posting a JMS message or placing an input file in the directory of a file proxy service.
Breakpoints are the intentional pausing locations in a Service Bus application that you set for debugging purposes. When you run test data using the Test Console, the process pauses at each breakpoint and does not resume until you tell it to. You can set breakpoints on pipelines and split-joins.
To set breakpoints on Service Bus components:
A red icon appears next to the node to indicate that a breakpoint is set.
Exception breakpoints do not halt execution at a set point; you set exception breakpoints in JDeveloper’s Breakpoints window instead of in a specific location.
When you debug a component using a local server, the Test Console is launched so you can enter the input for the debugging process. You can only test locally when using the integrated WebLogic server. You specify whether to test locally or remotely in the project's properties. You can also configure how breakpoints are handled during debugging.
To initiate debugging on components with breakpoints:
The Test Console appears.
If you do not have a domain running, the Create Default Domain dialog appears. Enter the connection information for the integrated server and click OK. This may take several minutes.
For more information, see Using the Test Console.
The Test Console executes the command, but pauses when it reaches the first breakpoint and returns to the editor for the pipeline or split-join. The breakpoint icon is now blue instead of red to indicate where the debugger is stopped.
In this window, you can view variable values at the current state in processing. For information about what you can do here, see Working with the Debugger Windows.
The debugging framework lets you debug incrementally by performing step actions to debug code. You can step over parts of the message flow and begin debugging at a different location, such as a different breakpoint in the same or a different component. As you proceed with debugging, additional frames are created for breakpoints and are displayed in the Stack view.
All of the icons mentioned in the following steps are located in the toolbar to the right of the Debug icon. Hover over an icon to see its name.
To step through a debugging session:
When the debugger reaches a breakpoint, you can begin to step through.
The current breakpoint icon is blue instead of red.
To stop debugging, you can either detach or terminate the debugger.
To end or detach from a debugging session:
The Terminate Debugger Process dialog appears.
Both options terminate the debugger connection to the server and the process continues to run on the server until it completes.
When you start a debugging session, several tabs appear in the Log window that provide you with additional information and features to help you with the debugging process. You can also access these windows from the Window > Debugger menu.
The Breakpoints window lets you add breakpoints to a group and enable or disable all the breakpoints in a group. You can also configure logging, sounds, and whether reaching a breakpoint halts processing. The Breakpoints window is available whether you are inside or outside a debugging session.
To view and modify the options of a breakpoint:
The Edit Breakpoint dialog appears with a Definition tab, a Conditions tab, and an Actions tab.
For more information about the Definition and Actions tabs, click Help.
Creating breakpoint groups lets you perform bulk edits to breakpoints. When you create a group, a new node is added to the Breakpoint window and any breakpoints added to the group appear under that group node.
To create a breakpoint group:
The Edit Breakpoint dialog appears with the Definition tab displayed.
The new group is added to the Breakpoint window, and the breakpoint is added to the group.
To add a breakpoint to an existing group:
The Edit Breakpoint dialog appears with the Definition tab displayed.
You can disable or remove individual breakpoints or all breakpoints.
To remove or disable breakpoints:
If you disable a breakpoint, you can enable it again to include it back in your debug process.
To enable a breakpoint:
The Data window displays the context variables and their values for the current breakpoint. You can view request or response data throughout the debugging process, and modify their values for further debugging. Only simple-type variables values can be modified.
To view and modify variable values:
A watch lets you monitor the changing values of variables or expressions as your program runs. After you enter a watch expression, the Watches window displays the current value of the expression. As your program runs, the value of the watch changes as your program updates the values of the variables in the watch expression.
A watch evaluates an expression according to the current context which is controlled by the selection in the Stack window. If you move to a new context, the expression is re-evaluated for the new context. If the execution point moves to a location where any of the variables in the watch expression are undefined, the entire watch expression becomes undefined. If the execution point returns to a location where the watch expression can be evaluated, the Watches window again displays the value of the watch expression.
To add a watch:
The Watch window opens with a new row defining the watch for the selected variable.