Exception handling in WebSphere Process Server and WebSphere Enterprise Service Bus

This article explains how error conditions are captured and processed in WebSphere Process Server and WebSphere Enterprise Service Bus, and describes problem detection, retry behavior, exception propagation, and reporting. The article assumes you are familiar with the Service Component Architecture (SCA) programming model, and have experience developing applications with WebSphere Process Server and WebSphere Enterprise Service Bus.

Share:

Pamela Fong (pamela@us.ibm.com), Senior Software Engineer, IBM

Pamela Fong is a software developer with the WebSphere Enterprise Service Bus team at the IBM Hursley Software Lab in the UK. She is currently working on next-generation messaging bindings built on the open-source SCA Tuscany project. You can contact Pamela at pamela@us.ibm.com



Jeff Brent (jeffb@us.ibm.com), Advisory Software Engineer, IBM

Jeff Brent is a senior engineer for WebSphere process integration. He is the technical lead for a team of engineers who help customers with complex product implementations. When he is not helping customers, he enjoys spending time with his family and playing basketball. You can contact Jeff at jeffb@us.ibm.com.



16 May 2007

Also available in Japanese

Introduction

When running enterprise applications in a production environment, it is obviously important to understand of how the system will behave under failure conditions. This article describes the basic categories of exceptions in IBM® WebSphere® Process Server (hereafter called Process Server) and IBM WebSphere Enterprise Service Bus (hereafter called Enterprise Service Bus). The article describes:

  • How the system behaves when it encounters a problem
  • Where problems are logged
  • How you recover from various problems

SCA primer

Before delving into error handling, you need to understand the basics of some of Service Component Architecture (SCA), including interface types, invocation patterns, and exception categories.

Interface types

SCA supports two interface types:

JTtype
Defined using Java™ interface
WType
Defined using a WSDL port type

The type is used to describe interfaces and references. The client programmer using a reference must interact with the reference based on the type. The target for the invocation or service provider can use a different type (J or W) from how it is referenced. SCA will resolve the differences.

Business exceptions may be declared on both JType and WType interfaces. JType interfaces use a throws clause, while WType interfaces declare faults.

Invocation patterns

SCA provides two invocation styles:

Synchronous
Blocking request made to the target, and response returned on same thread.
Asynchronous
Non-blocking request made, and response is provided in a separate thread.

Within the asynchronous style, the SCA asynchronous programming model provides three types of asynchronous invocation patterns:

One way
Used as a fire and forget invocation pattern. The client calls the operation provided via the reference and control is returned immediately. No response, exception, or fault is returned.
Deferred response
Request-response asynchronous invocation pattern. The client makes a request and requests the response at a time convenient for the client.
Callback
Request-response asynchronous invocation pattern. The client implements a callback interface that is invoked by the SCA runtime when the response is ready.

Knowing the differences between the invocation patterns is essential for understanding the error conditions you might face.

Exception categorization

In Process Server and Enterprise Service Bus, applications are built using the SCA programming model. It defines two types of error conditions: business exceptions and system exceptions -- called ServiceBusinessException and ServiceRuntimeException in the programming model.

Business exceptions

Business exceptions are checked exceptions declared in a business method's function signature (WSDL faults or Java throws). Business exceptions are used to identify error conditions that are anticipated by the application or service. An example is an InvalidSymbolException for a stock quote service. Such exceptions are wrapped by ServiceBusinessException and passed back to the client.

System exceptions

System exceptions are also known as runtime exceptions. They are not declared in the method signature. In general, they represent error conditions that are not anticipated by the application, such as a NullPointerException in a Java Component. These exceptions are wrapped by ServiceRuntimeException and passed back to the client, which can interrogate the ServiceRuntimeException to determine the cause.

A few built-in system exceptions are defined in the SCA programming model as sub-classes of ServiceRuntimeException:

ServiceExpirationRuntimeException
Indicates that an asynchronous SCA message has expired. Expiration times can be set using the RequestExpiration or ResponseExpiration qualifier on a service reference.
ServiceTimeoutRuntimeException
Indicates that the response to an asynchronous request was not received within the specified time limit, which is set programmatically during the invokeResponse() call when using the deferred response asynchronous communication pattern.
ServiceUnavailableException
Indicates that an exception was thrown while invoking an external service via an import.
ServiceUnwiredReferenceRuntimeException
Indicates that the service reference on the component is not wired correctly.

Exception handling for synchronous invocation

When a Service component is invoked synchronously, both the client and the service provider execute in the same thread. The target can return a response message, an exception, or nothing (in a one way operation) to the client. If the result is an exception, it can be either a business exception or a system exception. The client in this case can be either application code or some form of system code.

Figure 1. Invocation assembly diagram
Invocation assembly diagram

Here is a sample client that invokes a Java component declared with a JType interface. The interface has one method declared as follows:

Listing 1. Stock quote interface
public interface StockQuote {
float getQuote(String symbol) throws InvalidSymbolException;
}

The client code looks like this:

Listing 2. Stock quote synchronous client quote
try {
float quote = StockQuoteService.getQuote(String symbol);
} catch (InvalidSymbolException s) {
System.out.println(This is business exception declared in the Java interface.);
} catch (ServiceRuntimeException e) {
System.out.println(Unchecked system exception detected);
}

In the above scenario, the first exception InvalidSymbolException indicates that the request has reached the service provider, which does not recognize the client's input. The service provider then throws a business exception stating that the symbol supplied is invalid. This business exception is the only one declared by the method signature.

JType exceptions like InvalidSymbolException are only caught with clients using a JType reference. For client programming with WType references, you can download the WSDL sample below..

In addition to the business exception declared, the client can receive system exceptions. For example, if the stock exchange system runs into a problem, the service might fail to obtain the quote with some kind of unchecked exceptions. When such an exception is thrown by the service, a ServiceRuntimeException is returned to the client, and the client might then want to determine the underlying cause. The following code snippet shows how it can obtain this information:

Listing 3. Stock quote synchronous client quote II
try {
float quote = StockQuoteService.getQuote(String symbol);
} catch (ServiceRuntimeException e) {
Throwable t = e.getCause();
if (t instanceof RemoteException) {
system.out.println(System ran into RemoteException. Details as follows:  + e.toString());
}

Exception handling for asynchronous invocation

As described above, the SCA programming model supports three types of asynchronous invocation patterns. When a service component is invoked asynchronously, the client and service provider are executed in different threads, and error conditions can occur in either thread. The client may experience a system exception during the invocation, or the service provider may experience a business or system exception while servicing the request.

In Process Service or Enterprise Service Bus, there will always be an asynchronous counterpart of the interface shown above:

Listing 4. Asynchronous stock quote interface
public interface StockQuoteAsync {
public Ticket getQuoteAsync(String arg0);
public Ticket getQuoteAsyncWithCallback(String arg0);
public float getQuoteResponse(Ticket ticket, long timeout) throws InvalidSymbolException;
}

Here is the client code for a call using the invocation pattern for deferred response:

Listing 5. Asynchronous client
Ticket ticket = stockQuote.getQuoteAsync(symbol);
try {
quote = stockQuote.getQuoteResponse(ticket, Service.WAIT);
} catch (InvalidSymbolException s) {
System.out.println(This is business exception declared in the interface.);
} catch (ServiceRuntimeException e) {
System.out.println(Unchecked system exception detected);
}

Similar to a synchronous invocation, InvalidSymbolException indicates that the request has reached the service provider, which has thrown a business exception stating that the symbol is invalid. This business exception is the only one declared by the interface.

Again, JType exceptions like InvalidSymbolException are caught only with clients using a JType reference. For client programming with WType references, you can download the WSDL sample below..

In addition to the business exception declared, the client can receive system exceptions such as connection error that happens while sending the message. The client cannot receive system exceptions that happen in the service thread (the thread on the service side of the asynchronous invocation). According to the SCA asynchronous programming model, runtime exceptions that occur at the target component are not returned to the source component. The routing of these errors is described below.

Exception case on asynchronous exception handling

There is one exception to the SCA asynchronous programming model rule that runtime exceptions that occur at the target component are not returned to the source component. If the source component is a Business Process component or Staff Process, system exceptions that occur in the target service component are returned to the caller. This capability lets business process designers model and catch system exceptions, and execute error logic if a BPEL client returns a system exception.

Retry configuration

SCA uses a Service Integration Bus to transport messages between components. These destinations are created by install tasks when a module is installed to a Process Server or Enterprise Service Bus server. During an invocation, if the target service component returns a system exception, the Service Integration Bus automatically resubmits the message until a threshold on the module destination is reached. This section explains how to view and edit this retry setting, and describes special conditions when this setting is ignored.

A retry example

Assume a module named StockServiceModule contains two components: Validator and Calculator. Validator makes an asynchronous invocation to Calculator. The asynchronous invocation generates a message and puts it on the Service Integration Bus. This message is later picked up by the SCA invocation framework, which invokes the Calculator service. In this example, suppose that a software defect causes Calculator to throw a NullPointerException because the input parameter is null:

Figure 2. StockServiceModule
StockServiceModule

When a NullPointerException is returned from Calculator, SCA rolls back the current transaction, which causes the invocation message to be put back on the Service Integration Bus, onto a destination that represents the module that the target service belongs to. In our example, the module name is StockServiceModule, so the destination name to which the message is rolled back is sca/StockServiceModule. By default, the Service Integration Bus will try to deliver the same message to the Calculator service up to five times, and you can set the number of retries.

Changing the retry setting

As describe above, the Service Integration Bus has a built-in retry mechanism with the SCA message driven bean (MDB). You can configure the retry behavior by modifying the Maximum Failed Deliveries attribute on the module destination. Suppose you have a module named StockServiceModule, and a number of Service Integration Bus destinations created by SCA to support asynchronous communication, with one of them named sca/StockServiceModule. To change the number of retries when an asynchronous service invocation fails, you change the value of Maximum failed deliveries:

  1. Identify the module that the target component resides in. In this example, it's StockServiceModule.
  2. From the admin console, find the SCA system bus, which typically follows this naming convention: SCA.SYSTEM.$cellName.Bus. For example, SCA.SYSTEM.widcell.Bus is the default bus for a Unit Test Environment.
  3. Navigate to the list of destinations associated with this bus.
  4. Find the destination that has a name like sca/$moduleName. In this example, the name we are looking for is sca/StockServiceModule.
  5. From the module destination's attribute screen, locate the field Maximum failed deliveries, and set it to any integer from 2 to as high as you want. The values 0 and 1 are invalid in Enterprise Service Bus and Process Server.
Figure 3. Configuring maximum failed deliveries
Configuring maximum failed deliveries

When the retry configuration does not work

If you insert a print statement inside of the Calculator implementation, the number of redeliveries sometimes does not always match the configured value. There are two features that can cause this deviation:

JMS export

If the request involves passing a message between a JMS Export and a Component, the number of retries will always be 1 more than the configured value. The diagram below shows how destinations are used to route a message from a JMS export to a component:

Figure 4. JMS Export
JMS Export
  1. Message is picked up from the module's external destination and delivered to the target component, Pojo1 in this case.
  2. Pojo1 throws a system exception.
  3. Message is rolled back to where it was picked up. In this case, it is the SCA module destination name sca/Module1.
  4. After the message is rolled back to the destination, the underlying system redelivers the message based on the destination's maximum failed delivery setting:
    Figure 5. JMS Export II
    JMS Export II
  5. Message is redelivered to JMSExport1.
  6. JMSExport1 binding detects that a redelivered message and puts the message to the sca/Module1/component/Pojo1 destination.
  7. Message is forwarded to sca/Module1 and delivered to Pojo1.
  8. Pojo1 throws a system exception
  9. Message is rolled back to sca/Module1.
  10. From here, message is redelivered to Pojo1 four more times.

The result is that Pojo1 gets invoked six times, one more than the Maximum failed deliveries value for sca/Module1.

Business process component

When a business process component invokes a target service component, any runtime exception encountered by the target thread is delivered back to the process component. Here is the sequence of events for handing the runtime exception:

Figure 6. Business process component
Business process component
  1. Before the process component delivers the message to an outgoing destination, it marks in the message that all system exceptions should be returned to the caller for processing.
  2. Message is put to the sca/Module2/component/Pojo2 destination.
  3. Message is picked up from sca/Module2 and delivered to Pojo2.
  4. Pojo2 throws a system exception.
  5. Message is rolled back to sca/Module2.
  6. From here, the message is redelivered four times based on the default Maximum failed deliveries setting of five (once for the original delivery plus four redeliveries).
  7. On the fourth retry (fifth delivery), the message is interrupted by SCA, and delivered back to the caller with the reason for the failure, so Pojo2 is never invoked during the last message redelivery.

The result is that Pojo2 gets invoked four times, one fewer than the Maximum failed deliveries value for sca/Module2.

Where are the failed messages?

Routing rules for failed messages in Enterprise Service Bus

When a system exception occurs at the target component during an asynchronous invocation, the message is rolled back to the incoming destination and redelivered. In Enterprise Service Bus, after the retry limit is reached, the message is routed to an exception destination as specified in the Exception destination field of the module destination. This destination is set in the SCA system bus system exception destination. By default, there is a system exception destination for each server.

For an environment with Node name WPSNode, Server name server1, and Bus name SCA.SYSTEM.WBIDev-BGMNode01Cell.Bus, the system exception destination would be _SYSTEM.Exception.Destination.WPSNode.server1-SCA.SYSTEM.WBIDev-BGMNode01Cell.Bus

Over time, messages accumulate at this exception destination, and you can browse the number of messages in the queue using the admin console. Alternatively, you can write a JMS client application to read the messages off the queue for exception processing.

Routing rules for failed messages in Process Server

In Process Server product, the exception destination is set to the Process Server Recovery exception destination, with the following naming convention. For a server with node name WPSNode and Server name server1, the recovery exception destination is WBI.FailedEvent.WPSNode.server1

There is one recovery exception destination per server. In general, all the regular destinations created on the SCA system bus will be configured to route failed messages to the recovery exception destination. On the other hand, regular destinations on the SCA application bus are configured to route failed messages to the SCA application bus system exception destination. Thus if a JMS export picks up a message from the SCA application bus and runs into a rollback situation, the failed message will be routed to the SCA application bus system exception destination instead of the WebSphere Business Integration recovery exception destination.

When a system failure occurs, in addition to capturing the failed message at this exception destination, the Process Server Recovery feature also generates a failed event that represents the system error and stores it into the Recovery database. The Failed Event Manager subsystem consists of a set of database tables, message-driven beans, EJBs, and other J2EE artifacts.

Failed Event Manager processing

This diagram shows how failed events are created:

Figure 7. Failed Event Processing
Failed Event Processing
  1. The source component makes a call using an asynchronous invocation pattern.
  2. The SCA MDB picks up the message up from the SCA destination.
  3. The SCA MDB calls the correct target component.
  4. The target component throws a ServiceRuntimeException.
  5. The SCA MDB transaction rolls back to the SCA destination.
  6. The exception information is stored to the FEM database with a status of not confirmed.
  7. The invocation is retried by the Service Integration Bus n times -- the default is five (one original and four retries). As described above, you can change the default value using the admin console. Given an SCA module M, navigate to Buses => SCA.SYSTEM.$Cellname.Bus => Destinations => sca/M and change Maximum failed deliveries.
  8. After the number of retries is reached, the message is moved to the FEM destination.
  9. The FEM MDB picks up the message, updates the failed event in the database, and sets status to Failed.

When are failed events created? As stated, failed events are not created for synchronous invocations nor for two-way business process interactions. They are created when clients use an asynchronous invocation pattern and a ServiceRuntimeExcpetion is thrown by the service provider. If the target component is a cluster member, the message is redelivered to the same cluster member up to the retry setting. Afterwards, the message is routed to the recovery exception destination that is specific to the server that the target component runs on.

Advanced invocation style determination

So far we have explained that handling of system exceptions is very different when an invocation is made synchronously versus asynchronously. Therefore, to understand how system exceptions are handled, you must understand what type of invocation style is used to for the invocation. However, this determination is not always straightforward. Whether a call is synchronous or not depends on the API used in the application. The SCA Dynamic Invocation Interface has the following methods:

invoke() invokeAsync()

You can assume that invokeAsync() will result in an asynchronous invocation. However, for the first API invoke(), the interpretation is not so straightforward. When a target service is invoked, the system can switch a synchronous invocation into an asynchronous one if the target service has asynchronous implementation. Examples of asynchronous implementation include long-running business processes and certain types of import bindings such as JMS imports. In short, if the target service is a component with asynchronous implementation, there will be an asynchronous hop (message serialization and de-serialization to a destination) inserted in front of the component:

Figure 8. Invoking asynchronous component
Invoking asynchronous component

If the target service is represented by an asynchronous import, any system errors occurring beyond the asynchronous hop will not be reported to the client.

Figure 9. Invoking asynchronous import
Invoking asynchronous import

There is some confusion about the location of the asynchronous hop surrounding synchronous imports. Assume you have a POJO invoking a Web service import asynchronously. The asynchronous hop will be in front of the Web service import. Any system error occurring after the asynchronous hop is not reported, so if the Web service import runs into an EndPointNotFound problem when invoking the remote service, this error is captured in a failed message, and will be routed to an exception destination:

Figure 10. Invoking synchronous import asynchronously
Invoking synchronous import asynchronously

Message expiration and timeout exceptions

Message expiration is another error condition that is processed differently. When the SCA API invokeResponse(ticket, timeout) is used, you can pass in a timeout value to specify how long the thread should be blocked waiting for a response to arrive. If a response does not arrive during the specified time, a ServiceTimeoutRuntimeException is thrown. This exception is only applicable in the caller's thread while polling for a response. This exception is not to be confused with the ServiceExpirationRuntimeException.

When SCA makes an invocation to another component, you can specify a request expiration and response expiration value. These properties are set as reference qualifiers of the calling component. If a request message is not picked up within the specified time, a ServiceExpirationRuntimeException is thrown. By the same token, if a response message is not received within the response expiration time limit, a ServiceExpirationRuntimeException is thrown. Detection of these conditions can occur at either the calling or receiving side of the invocation. When detected in the receiving side, a response message containing the exception is sent to notify the caller.

Is it possible to receive expiration or timeout exception when making a synchronous call? As discussed earlier, when an asynchronous component or asynchronous import is invoked synchronously, there is an asynchronous hop along the invocation path. Therefore the client can receive a ServiceTimeoutRuntimeException or ServiceExpirationRuntimeException even when the call is initiated synchronously.

Error handling sample

You can download a test module and explore various kinds of exceptions, including business and runtime exceptions, and throwing exceptions as a simple Java type or as a Business fault. This section describes this test module.

The BO and interfaces used for this interaction were designed with the SCA programming model in mind. The sample includes two Java components that implement the interface and pass the BO.

Figure 11. Error sample
Error sample

The client component is called InvocationPatternComp. The service provider for the sample is called ErrorComp.

Interfaces

Two interfaces are used in this sample. InvocationPatternInterface is exposed by the InvocationPatternComp and contains one operation -- start. Use this interface to start the test. It lets you decouple the invocation pattern used by the interaction between client and service provider from the sync-only invocation pattern used by component test:

Figure 12. InvocationPattern interface
InvocationPattern interface

The second interface is called ErrorInterface and is exposed and implemented by the ErrorComp. The interface contains one-way operations and a variety of request/response styles:

Figure 13. ErrorInterface
ErrorInterface

Business objects

Two business objects are use in this sample. ErrorBO contains a number of fields that define the behavior that the client and service provider will exhibit:

Figure 14. Error BO
Error BO

The first set of fields are used by the InvocationPatternComp to decide which operation to call and which invocation pattern to use.

How InvocationPatternComp handles the Error BO
AttributeValid ValuesComment
invocationPattern

sync

async oneway

async deferred response

async callback

Determines the invocation pattern to be used when calling the target component
operationType

oneway - Invokes a one way operation.

reqresp - Invokes a request response operation

rrno - Invokes a request response with no output

rrnowf - Invokes a request response operation with no output but has faults declared

Determines the operation on the target interface to call
exceptionType

Business

Runtime

This field is used by the ErrorComp to decide what type of exception to throw.
faultType

bo

string

This field instructs the Error component as to which type (simple string or BO) to use for a ServiceBusinessException constructor

Implementations

The InvocationPatternComp receives the ErrorBO via the start operations populated using component test. The component will read in the values from the BO and make the invocation as necessary. The ErrorComp then receives the ErrorBO from the InvocationPatternComp and reads the values specifying the type of exception to throw and acts appropriately.

Component test to exercise the sample

  1. Start server and deploy the module.
  2. Right-click on InvocationPatternComp and select Test Component.
  3. Populate the BO as shown below and click Continue.
Figure 15. Error test
Error test

Using the values from above, the InvocationPatternComp acts as the client and invokes the ErrorComp using a synchronous invocation pattern via the request/response operation. The ErrorComp acts as service provider and responds with a ServiceBusinessException constructed using a business object (FaultBO).

Conclusion

This article has described the basic categories of exceptions used in WebSphere Process Server and WebSphere Enterprise Service Bus. It has explained how various exceptions are processed, how to configure retries, and where to locate failed messages. The article also explained how to determine which invocation mechanism is employed under the covers, because it affects how exceptions are treated.


Download

DescriptionNameSize
Sample codeSCAExceptions.zip13 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=223568
ArticleTitle=Exception handling in WebSphere Process Server and WebSphere Enterprise Service Bus
publish-date=05162007