In this chapter we will cover:
Deploying a BPEL process
Gathering a BPEL process's in and out parameters
Calling a synchronous BPEL process from Java
Calling an asynchronous BPEL process from Java
Handling business faults from a synchronous BPEL process
Handling business faults from an asynchronous BPEL process
Mapping the results of a BPEL process
Business processes are an integral part of every company. As new requirements arise in the business processes, companies pursue its alignment with IT as well. Pursuing the need for IT to efficiently support business processes in companies, the
SOA (Service Oriented Architecture) was identified as the most important IT technology for business process implementation. Depending on the business environment, BPEL can also be considered as a suitable technology in EDA (Event Driven Architecture), since it provides constructs to handle events through event handlers (onMessage
and onAlarm
). Within SOA, the most common practice to implement business processes is by using a WSBPEL
(Web Services Business Process Execution Language), or BPEL for short. Of course, SOA itself does not make it compulsory to use BPEL for business process implementation, and you can also use other workflow languages, such as BPMN, YAWL, and jBPM(JPDL) just to name some. BPEL is an XML-based language for the definition and execution of business processes, and has become the de-facto standard for orchestrating web service compositions. The first official version of BPEL specification was named BPEL4WS 1.1, or BPEL 1.1 for short, in 2003. Later on, a new version, WS-BPEL 2.0, with significant enhancements, was released in 2007.
A BPEL process definition has three main parts:
A BPEL file in XML form: This contains the definition of a process (main activities, variables, events, partner links, fault handlers, compensation handlers, and so on).
The WSDL files: These files present web service interfaces, utilized by the BPEL process for orchestration purposes. Similar to BPEL, WSDL also released several versions of specification, which are widely used today. In 2001, WSDL 1.1 (Web Service Definition Language) was released, followed by WSDL 2.0 (Web Service Description Language) in 2007.
The XSD schema files: These files present XML definitions of the BPEL request, response, and fault messages, as well as the BPEL variable definitions.
The three mentioned parts present the source code of the business process definition. The source code is deployed on a BPEL engine, which is responsible for managing, running, and monitoring the execution of business processes.
We can find many BPEL execution engines on the market. They are either open source or proprietary. We will name just a few of them here which are most commonly used by companies and communities:
Vendor |
Product |
License Type |
BPEL specification supported |
---|---|---|---|
Oracle |
Oracle SOA Suite |
Proprietary |
1.1 and 2.0 |
jBoss |
jBPM |
Open source |
1.1 and partly 2.0 |
Apache |
Apache ODE |
Open source |
1.1 and 2.0 |
Active Endpoint |
ActiveVOS |
Proprietary |
1.1 and 2.0 |
IBM |
WebSphere Process Server |
Proprietary |
1.1 |
All these BPEL engines have the support of a BPEL specification, either Version 1.1 or 2.0. However, vendors do extend the functionality of the BPEL specification with their own extensions, making migration of business processes between various BPEL platforms more difficult. For example, IBM WebSphere Process Servers provides the possibility to declare inline human tasks, while Oracle SOA Suite provides Java Embedding activity and extension functions to monitor process and perform various XPATH operations.
It is evident that BPM applications are emerging, as business environments are becoming ever more dynamic and the need for agile IT is increasing. BPEL, as an orchestration technology, is able to compose business processes from various services. We can monitor business processes in real time with BAM (business activity monitoring) solutions, and extend their flexibility with the use of BRMS (business rules management system).
To successfully integrate a BPEL process with other types of applications, we need to know the description of the provided BPEL process operations, the type of the BPEL process (synchronous or asynchronous), and how to handle various faults thrown from the BPEL process.
In this chapter, we will deal with the deployment of a BPEL process. We will then investigate how applications written in Java efficiently utilize the BPEL processes.
This recipe describes how a BPEL process can be deployed in Oracle SOA Suite. We will show the deployment of the BPEL process from a GUI tool as well as from the command line.
We have to set up a BPEL engine and a proper development environment. For the BPEL engine, we use the BPEL Process Manager from Oracle SOA Suite 11g. We also use JDeveloper as the development environment.
Tip
The installation notes and packages can easily be accessed from the Oracle web page at http://www.oracle.com/technetwork/middleware/soasuite/downloads/index.html. An Oracle web account is required in order to access downloads.
We will start with the HelloWorld example from the Oracle SOA Suite examples and will add additional functionality in the later recipes. For this recipe, we will unzip the HelloWorld example to our hard drive.
Note
For this recipe, we use the example from the https://java.net/projects/oraclesoasuite11g/pages/BPEL address.
In the following steps, we will cover the actions we need to perform in order to deploy a BPEL process to the Oracle SOA Suite server:
To deploy the BPEL process, we first open JDeveloper and select Default Role. Depending on the role we choose, JDeveloper enables technologies available inside IDE. We choose the default role, which has the BPEL support enabled. We click on Open Application…, select the folder with the HelloWorld sample, and point to the
bpel-101-HelloWorld.jws
file. The project structure in JDeveloper is as shown in the following screenshot:We see the
HelloWorldProcess.xsd
file, which contains the XML data type and the XML element structures for the input and output messages that are utilized by the BPEL process. At the top level of the project, we see theHelloWorldProcess.bpel
file, which contains the BPEL process definition, andHelloWorldProcess.wsdl
that contains the definition of the BPEL process partner links.To deploy the BPEL process, we right-click on the top-level project in the Application Navigator, click on Deploy, and select the BPEL process. We select Deploy to Application Server and click on Next.
For the deployment configuration, we don't change anything; just click on Next. At this point, we have to select the application server on which we want to deploy the BPEL process. We click on the plus (+) sign and enter the name of the connection in the Connection Name field. Then, we click on Next and enter the username and password for the application server.
Next, we need to configure the
connection
parameters to the Oracle Weblogic Domain. The name of the Oracle Weblogic Domain can be obtained from the Oracle Weblogic management console.We leave the other parameters unchanged. We then test the connection to the Oracle Weblogic Domain by clicking on the Test Connection button.
Next, we click on Finish. Now, we select the newly defined BPEL server and click on Next. We can see various information such as the name of the SOA server, the partition to which we want to deploy the BPEL process, the status of the SOA server, and the URL of the server.
We then click on Next and Finish. The deployment process starts. When the deployment process finishes, we check if the process was successfully registered with the SOA server. We check this via the Oracle Enterprise Manager Console.
Also, we check to see if there was no error reported in JDeveloper. If deployment was successful, we will see a message in the JDeveloper deployment log as follows:
[10:05:55 PM] Successfully deployed archive sca_bpel-101-HelloWorld_rev1.0.jar to partition "default" on server AdminServer [http://medion:7001]
If our
HelloWorld
process appears in the Oracle Enterprise Manager Console, we succeeded in deploying the BPEL process; otherwise, we need to examine the error and respond accordingly. In case of an error, we need to first check the JDeveloper messages log, and then the Oracle SOA Suite console log. Theobe a useful source of information about the file.
After preparing the package for deployment with JDeveloper, we can deploy the BPEL process with the ant
scripts. The scripts comes handy for continuous integration tasks in staging and production environments, where various testing and deployment tasks are performed automatically. A set of ant
scripts comes with Oracle SOA Suite in order to compile, build, deploy/undeploy, and test the BPEL processes.
We first open the command prompt and change the directory to the example project home. For the deployment, we execute the ant
script as shown in the following screenshot:

The command with which we started the deployment is as follows:
ant -f %Middleware_Home%\%SOA_Suite_Home%\bin\ant-sca-deploy.xml -DserverURL=http://localhost:7001 -DsarLocation=.\deploy\sca_bpel-101-HelloWorld_rev1.0.jar -Doverwrite=true -DforceDefault=true
Tip
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
The ant
script parameters have the following meanings:
-f
: It is the location of the deployment script-DserverURL
: It is the base URL of the Oracle SOA Suite server-DsarLocation
: It is the location of the deployment package-Doverwrite
: If the BPEL process with the same version is already deployed, we can overwrite it-DforceDefault
: The force to deploy the package to the default domain
Before the deployment starts, we have to enter the username and password of the BPEL server. Again, we open the Oracle Enterprise Manager Console in order to check whether the BPEL process was successfully deployed.
This recipe will explain the ways of getting input and output parameters about a BPEL process. The information gathered is very important if we want to call the BPEL process from Java applications.
We are deploying the BPEL process on the BPEL server. The business process is now ready to be executed; however, we don't have any information about the business process besides the WSDL location of the business process.
In the Oracle Enterprise Manager Console, we select the BPEL process from the tree, and click on the following icon:
We receive information about the business process endpoint URI and a location of the business process WSDL as shown in the following screenshot:
By entering the WSDL address into the web browser, we receive a description of the BPEL process interface. In this definition, we check for the input and output messages as follows:
<wsdl: message name = "HelloWorldProcessRequestMessage"> <wsdl: part name = "payload" element = "client:process"/> </wsdl: message> <wsdl: message name = "HelloWorldProcessResponseMessage"> <wsdl: part name = "payload" element = "client: processResponse"/> </wsdl: message> <wsdl: portType name = "HelloWorldProcess"> <wsdl: operation name = "process"> <wsdl: input message = "client: HelloWorldProcessRequestMessage"/> <wsdl: output message = "client:HelloWorldProcessResponseMessage"/> </wsdl:operation> </wsdl:portType>
The most interesting part of WSDL is the
<wsdl:operation>
element, which indicates the entry point, the functionality, and the input and output messages of the BPEL process. We see that the input and output parameters both have a defined message in theclient
namespace, which is defined as the XSD schema. We can find its location in WSDL under the<import>
tag. We search for theclient: process
input parameter in the XSD schema:<element name="process"> <complexType> <sequence> <element name="input" type="string"/> </sequence> </complexType> </element>
As we can see, the input parameter takes the
string
variable with thename
input. Similarly, we explore the output parameterclient: processResponse
in the XSD schema as follows:<element name="processResponse"> <complexType> <sequence> <element name="result" type="string"/> </sequence> </complexType> </element>
The BPEL process will return the
string
variable namedresult
.
In general, there are two approaches to designing the BPEL processes. The first one is the top-down approach, where we first develop the XSD schema and WSDL files, which is also called the contract-first approach . The next one is called the bottom-up approach, where we start from the already-written Java code and generate the XSD schema and WSDL files with tools.
The recommended approach when designing the BPEL processes is to first define the XSD schema, which contains the definition of the input and output parameters. This is also the proper place to put the various complex variables used in the business process.
The schema is later used by WSDL to define the BPEL process interface via the <wsdl: portType>
element. Both WSDL and the XSD schema are packed into the deployment package and deployed to the BPEL server.
Note
The definition of the input and output parameters in the XSD schema is not mandatory. We can easily define them in WSDL of the BPEL process. However, we lose some of the readability of the WSDL document. Note that such an approach is bad practice and is not recommended, since it hinders the reusability of the XML data types and elements.
This recipe explains how to call a synchronous BPEL process from Java. When a client calls a synchronous BPEL, it gets blocked until the BPEL process finishes the processing and returns the response. Usually, synchronous BPEL processes are designed for cases where the operation will be completed in a relatively short time. For long-running operations, we instead design asynchronous BPEL processes. This recipe will also cover how to prepare a Java package for integration with Java applications. From the client perspective, a synchronous BPEL process can be invoked in the same way a synchronous web service could. The client is most commonly called proxy
, and it is used to ease the connection between the two technologies. In our case, we would like to call the BPEL process, which is mainly the XML content, from Java and proxy is helping us to get across the gap between those two technologies.
In order to call a synchronous BPEL process, we will develop a Java client using the JDeveloper wizard. After completing this recipe, we will be able to call a synchronous BPEL process from the Java client application.
First, we create another project in JDevelper. On the previously created BPEL sample project, we right-click, and select New…. From the Business Tier category, we select Web Services and then we select Web Service Proxy under Items as shown in the following screenshot:
Then, we click on OK, which shows the welcome screen, and then we click on Next. We have to enter the WSDL location of the BPEL process in the next window. We also have the ability to choose whether we want to copy the WSDL file into the project.
In the next window, we have to enter the name of the Java packages. We have to enter the package name of the proxy files (that is, Root Package for Generated Types) and Package Name, which is where the files for the XML serialization will be placed, as shown in the following screenshot:
We have inserted all the mandatory fields necessary to create the BPEL process proxy, so we conclude the wizard by clicking on Finish.
In JDeveloper, we see that a number of files were generated in a separate project. The package
org.packt.bpel.sync.gen
contains the files that are used for transformation between XML and Java.Let us check the
Process.java
file. We see that the class contains only one member as follows:@XmlElement(required = true) protected String input;
The code is annotated with the
@XmlElement
annotation, which indicates the usage of JAXB (Java Architecture for XML Binding). The JAXB implementation enables conversion from Java to XML and vice-versa. We need this conversion because data in Java is stored in objects, while BPEL holds data in XML format.Note
This variable presents the input parameter of the BPEL process. The class also contains two helper methods for setting the value and getting the value of the variable. Similarly, we can check the
ProcessResponse.java
class file which contains the output parameter of the BPEL process.The most interesting generated file is
HelloWorldProcess_ptClient.java
. This file contains skeleton prepared to call the BPEL process.The code starts with the reference to the BPEL process. Since the BPEL process is exposed as a web service, the code is as follows:
@WebServiceRef private static Helloworldprocess_client_ep helloworldprocess_client_ep;
We can also note the
@WebServiceRef
annotation, which is used by JAX-WS (Java API for XML Web Services). The annotation indicates a reference to the web service port, or in our case, the BPEL process port.We need to instantiate the proxy to the BPEL process and get the reference to the endpoint as follows:
helloworldprocess_client_ep = new Helloworldprocess_client_ep(); HelloWorldProcess helloWorldProcess = helloworldprocess_client_ep.getHelloWorldProcess_pt();
We define the input and output variables as the
String
type as follows:String input = "Jurij"; String output;
Remember that the BPEL process is taking
string
as an input. As a result, the BPEL process returns a concatenated string starting withHello
, followed by the input string, and concluded with three exclamation marks. Finally, we call the BPEL process and write results to the output as follows:output = helloWorldProcess.process(input); System.out.println("Business process returned:" + output);
As a result of the BPEL process call, we receive the following output to JDeveloper:
We can see that the BPEL process was executed in the Oracle Enterprise Manager Console as shown in the following screenshot:
We can now see that the BPEL process completed successfully.
With the wizard in JDeveloper, we prepare the Java proxy for calling the BPEL process using the wizards in JDeveloper. When the client is executed, it converts the parameters from Java types to XML types via JAX-WS. Then, the call to the BPEL process is performed, and after the BPEL process finishes, the client receives the result in XML. The XML types are then converted back to Java types.
This recipe explains how to call an asynchronous BPEL process from Java-based applications. Asynchronous communication is broadly used for long-running business processes. When a client invokes a long-running business process, it usually cannot wait long periods (days, weeks, and so on) for the response. Instead, the communication is closed, and a response from the business process is captured by listening for the callback. This recipe also uses the Apache AXIS package.
In this recipe, we call an asynchronous BPEL process. We enriched the sample scenario with the use of the Apache AXIS package. This allows us to receive an asynchronous callback from the BPEL process. We integrate the AXIS package into the JDeveloper environment simply by unpacking the AXIS package, and adding its jars into the JDeveloper project classpath.
We implement two classes. In the first class, we program the client that is calling the asynchronous BPEL process. In the second class, we prepare a callback class that is used to handle the response from the asynchronous BPEL process. Note that the asynchronous BPEL process is not sending a response to the client via a reply activity. Instead, the BPEL process is using the callback
method, which contacts the client, of course, if one is listening.
Let us examine the
ClientProxy.java
class first. We start by creating theServiceClient
client and preparing theOptions
class to configure theServiceClient
client as follows:ServiceClient client = new ServiceClient(); Options opts = new Options();
To configure the
ServiceClient
client, we set the parameters as follows:opts.setTo(new EndpointReference("http://medion:7001/soa-infra/services/default/HelloWordlAsync/helloworldasyncprocess_client_ep")); opts.setAction("process"); opts.setUseSeparateListener(true);
We instruct AXIS where the BPEL endpoint is, which actions we want to call, and the type of the listener (callback) we want to use. With the
setUseSeparateListener
call, we instruct AXIS to send a SOAP message over two separate channels, thus enabling the asynchronous communication.We engage the
addressing
module of the AXIS package as follows:client.engageModule("addressing");
With this line of code, we actually enable the WS-Addressing module inside the AXIS package. The WS-Addressing module provides transport-neutral mechanisms to address web services and messages. In AXIS, this package is a prerequisite for the asynchronous communication.
Finally, we set the options to the service client and fire a non-blocking request to the asynchronous BPEL process as follows:
client.setOptions(opts); client.sendReceiveNonBlocking(createPayLoad(), new BPELCallback());
The non-blocking request enables the client to continue its processing without actually waiting for the BPEL process to finish. The
createPayLoad()
method is a helper method used to create a request message for the BPEL process. The helper method is generating XML content out of the Java class through JAXB. We build the request with the help of the XML document builder.The code which simulates further processing of the client is as follows:
System.out.println("send the message"); while (!isFeedback) { Thread.sleep(5000); System.out.println("waiting ...."); } System.exit(0);
The main thread is sleeping for five seconds, and after that period is over, it checks if the response was already received from the BPEL process. In the meantime, the client can process other requests. When the client receives the response from the BPEL process, it exits.
We created a code for handling the BPEL process response in the
BPELCallback.java
class. We implemented theonMessage
andonComplete
methods. When the reply arrives from the BPEL process, we print out the complete SOAP message as follows:public void onMessage(MessageContext messageContext) { SOAPBody msg = messageContext.getEnvelope().getBody(); System.out.println(msg); }
When the transmission is complete, the method
onComplete
is invoked, and we signal the program from which we received the reply from the asynchronous BPEL process as follows:public void onComplete() { System.out.println("Transmission finished."); ClientProxy.isFeedback = true; }
After running the example, we check the client console output. As we can see, the message is sent to the BPEL process and the client program continues its work. When the response is retrieved from the BPEL process, we see that the message is retrieved within the callback handler, and that means the program exits.
send the message waiting .... waiting .... waiting .... waiting .... <env:Body xmlns:env = "http://schemas.xmlsoap.org/soap/envelope/"><processResponse xmlns = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess"> <result>Hello </result> </processResponse></env:Body> Transmission finished. waiting .... [SimpleHTTPServer] Stop called Process exited with exit code 0
We also check the Audit Trail of the BPEL process. We see that the BPEL process received the message, executed the flow of activities, and at the end, contacted the client and sent a response to it as shown in the following screenshot:
Asynchronous communication between the BPEL server and client is different than in synchronous communication. In synchronous communication, the BPEL process is invoked, the process flow is executed, and the result is returned to the client. The whole time the BPEL process is executed, the client is blocked. In asynchronous communication, the BPEL process is invoked and the communication is closed. We describe such a call as one-way invocation . When the BPEL process execution is finished, the BPEL engine initiates communication with the client and sends back the response via callback. An asynchronous BPEL process does not block the client. This means that as soon as the client initiates the asynchronous BPEL process, it can continue with other tasks. We can see that the asynchronous BPEL processes are used for long-running transactions where we cannot predict when they will finish. Such transactions can be found using human interaction through human tasks.
In order to enable asynchronous communication between the BPEL process and client, we use the WS-Addressing mechanisms. WS-Addressing provides transport-neutral mechanisms to address web services and messages. In the BPEL engine, the correlation mechanism is used in order to track multiple, long-running executions of the BPEL processes. Correlations help with tracking the route to the corresponding BPEL process instance. The correlation sets present a compound version of correlation, as they are composed of more individual correlations. In our example, the correlation information is hidden behind the scenes as WS-Addressing is automatically set to appropriate properties in communication between the BPEL process and client.
Note
Latest specifications of the WS-Addressing specification can be found at the following URL: http://www.w3.org/TR/ws-addr-core/.
Usually, both the BPEL servers as well as the client implementations already provide the libraries that support the WS-Addressing specification. The information about addresses resides in the SOAP Header class. When we initiate the BPEL process, the following attributes are set by the client:
wsa:To
: This identifies the asynchronous BPEL process which we want to start.wsa:ReplyTo
: This identifies the address of the client to which the asynchronous BPEL process should return the response.wsa:MessageID
: This identifies the uniquely defined number of a sent message. With this message ID, we match the sent request with the received response.wsa:Action
: This identifies the action which should be executed on the asynchronous BPEL process.
Similarly, when the asynchronous BPEL process has finished its execution, the response is sent to the client. In the response SOAP Header class, the following attributes are set:
wsa:To
: This identifies the address of the client.wsa:Action
: This identifies the response action name.wsa:MessageID
: This identifies the uniquely defined number of a sent message. With this message ID, we establish a correlation between the request with the received response.wsa:RelatesTo
: This identifies the message ID of the request.MessageID
of the request andRelatesTo
of the response are used by the applications to match the requests against their respective responses.wsa:ReplyTo
: This contains information about where the response should be sent. For the response message from the asynchronous BPEL process, the element is empty.wsa:FaultTo
: This contains information about the faults, if they exist.
This recipe explains how to handle the faults thrown from a synchronous BPEL process. A BPEL process uses the <throw>
activity in case of exceptional situations. It gives the client feedback on what went wrong with the BPEL process processing. In a scenario where the client is expecting the response message and does not capture the faults thrown from the BPEL process, we can define the inline fault in the BPEL process reply activity.
We modified the synchronous BPEL process to throw an exception when the input parameter says FAULT
. With the check_fault
condition, we check if the input parameter contains the word FAULT
. The modified BPEL process is shown in the following screenshot:

We also need to define the fault structure in the XSD schema (HelloWorldProcess.xsd
) as shown in the following code:
<element name = "fault"> <complexType> <sequence> <element name = "msg" type = "string"/> </sequence> </complexType> </element>
We define the element fault
, which contains the element msg
of the type string
. We then define the fault message in the WSDL document as follows:
<wsdl:message name = "ProcessFaultMessage"> <wsdl:part name = "message" element = "client:fault"/> </wsdl:message>
We also specify the fault in the <portType>
and <binding>
elements of the WSDL document (HelloWorldProcess.wsdl
). In the following code, we omit the <binding>
element definition:
<wsdl:portType name = "HelloWorldProcess"> <wsdl:operation name = "process"> <wsdl:input message = "client:HelloWorldProcessRequestMessage"/> <wsdl:output message = "client:HelloWorldProcessResponseMessage"/> <wsdl:fault name = "fault" message = "client:ProcessFaultMessage"/> </wsdl:operation> </wsdl:portType>
We create the client proxy the same way we created it in the Calling a synchronous BPEL process from Java recipe. We now see the additional class ProcessFaultMessage.java
. We use this class when the fault occurs in the BPEL process. The class is annotated with the @WebFault
annotation, which indicates the service specific exception class as follows:
@WebFault(faultBean = "org.packt.bpel.sync.gen.Fault", targetNamespace = "http://xmlns.oracle.com/bpel_101_HelloWorld_jws/bpel_101_HelloWorld/HelloWorldProcess", name = "fault") public class ProcessFaultMessage extends Exception
The faultBean
attribute defines the Java class that will transform the fault from XML to Java. Additionally, the namespace of the BPEL process is also defined.
We also need to modify the client proxy main class HelloWorldProcess_ptClient.java
. Since it is possible that the BPEL process throws a fault, we must prepare our client code in advance for such a situation.
First, we create the input and output variables as follows:
String input = "FAULT"; String output = "";
Tip
We changed the code for calling the BPEL process because it requests to be in the
try
/catch
block.try { output = helloWorldProcess.process(input); } catch (ProcessFaultMessage e) { System.out.println( e.getFaultInfo().getMsg()); } System.out.println("Business process returned:" + output);
We run the client and observer BPEL process execution in the Oracle Enterprise Manager Console as shown in the following screenshot:
The output of the console in JDeveloper contains the following messages:
Error while processing input parameter Business process returned: Process exited with exit code 0
The business faults, as opposed to the runtime faults, are thrown by the applications when a problem with processing information occurs. Various situations can cause the BPEL process to throw a fault. The BPEL process might interact with web services and web service itself may throw a fault. Consequently, the BPEL process must react on the fault thrown by web service. When an exceptional situation occurs in the BPEL process, the fault is propagated to the client. As we can see, the newly created class ProcessFaultMessage.java
extends the Exception
class. We see that the BPEL faults correspond to the Exception
class in Java with extensions. The BPEL process also provides the ability to define the compensation handlers. With the compensation handlers, it is possible to undo the actions that were executed during the BPEL process execution. We can consider the compensation handler as a block of code containing the activities performing the compensation tasks.
The BPEL specification defines two types of faults. In this, we meet the BPEL process fault; however, there also exists a set of standard faults.
Note
A list of standard faults can be accessed at the following URL: http://docs.oasis-open.org/wsbpel/2.0/wsbpel-v2.0.pdf (see Appendix A, Standard Faults).
The BPEL standard faults are thrown if the BPEL server encounters some conditions in the runtime environment that do not correspond to the specifications. This category also includes situations where the variables might not be initialized if transformation does not find the XSLT file or if some problems occur on the network.
Tip
When we want to add additional information to the already existing fault in the BPEL process, we define new fault message with additional information in the WSDL document of the BPEL process. We then model the fault handling within the fault handler (the catch
or catchall
activity). We specify the fault condition that will be caught by the fault handler. Inside the fault handler, we use the rethrow
activity that throws the fault, which will give the client a better insight into the problem that occurred in the BPEL process.
The faults that occur either in a synchronous or asynchronous BPEL process are treated the same way inside the BPEL process. The difference, however, exists in the way the client is notified about the fault in the BPEL process. We said earlier that the client is not blocked when calling an asynchronous BPEL process. Since the communication is closed between the BPEL process and client after initiation of BPEL, we need to find a way to notify the client that something went wrong in the BPEL process. This recipe will show you how to handle the faults from the asynchronous BPEL processes.
We modified the asynchronous BPEL process from the Calling an asynchronous BPEL process recipe. We added the If
activity, which checks the content of the input parameter of the BPEL process. If the input parameter contains FAULT
text, then the BPEL process finishes immediately; otherwise, the BPEL process waits for some time and sends success
to the client. The modified asynchronous BPEL process is shown in the following screenshot:

We notify the two reply activities. The callbackClient
invoke activity is used in case the asynchronous BPEL process finishes successfully. We add the new invoke activity named returnFault
for cases when we need to report the fault back to the client. We model the asynchronous BPEL process with the additional callback operation because the communication between the BPEL process and client is closed immediately after the client initiates the BPEL process, and there is no way the BPEL process can notify the client about the faults. We start by defining the fault message structure in the HelloWorldAsyncProcess.xsd
schema as follows:
<element name="fault"> <complexType> <sequence> <element name="msg" type="string"/> </sequence> </complexType> </element>
We define the fault message structure the same way as we did with the synchronous BPEL process. We also modify the WSDL description of the asynchronous BPEL process (HelloWorldAsyncProcess.wsdl
). Initially, we define the message for the fault as follows:
<wsdl:message name = "ProcessFaultMessage"> <wsdl:part name = "message" element = "client:fault"/> </wsdl:message>
We define a SOAP message containing the fault message later inside the <wsdl:operation>
element of <wsdl:binding element>
as follows:
<wsdl:binding name = "HelloWorldAsyncProcessCallbackBinding" type = "client:HelloWorldAsyncProcessCallback"> <soap:binding transport = "http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name = "processFault"> <soap:operation style = "document" soapAction = "processFault"/> <wsdl:input> <soap:body use = "literal" namespace = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess"/> </wsdl:input> </wsdl:operation> </wsdl:binding>
In the synchronous BPEL process scenario, we added the <wsdl:fault>
information in the reply
operation. For the asynchronous BPEL process scenario, we model the fault callback as a new operation
in the callback portType
as follows:
<wsdl:portType name = "HelloWorldAsyncProcessCallback"> <wsdl:operation name = "processFault"> <wsdl:input message = "client:ProcessFaultMessage"/> </wsdl:operation> </wsdl:portType>
Information about the fault is then sent via the new callback operation
to the client.
The asynchronous BPEL process does not return a fault in the same way as the synchronous BPEL process. For that purpose, we need to check the response SOAP message to see whether it contains the fault as follows:
Iterator<?> it = msg.getChildrenWithLocalName("fault"); if (it.hasNext()) { System.out.println("Fault occurred: " + msg.getFirstElement().getFirstElement().getText()); return; }
If the fault exists, we execute the actions for solving the problems.
We know from the previous recipes that calling an asynchronous BPEL process does not block the client. So, in order to retrieve information about the fault, we need to take a different approach as and when we call the synchronous BPEL process. We already mentioned that we defined another operation in reply to portType
.
We now have a problem, when we send the response information back to the client. Namely, the client does not care, if the message is a success or failure. In any case, the onMessage
method in the AxisCallback
class is executed. Here is the reason why we needed to implement the additional code inside the onMessage
method to check whether we received the fault from the asynchronous BPEL process.
Another way of testing whether we received the fault as the response from the asynchronous BPEL process is to take advantage of the WS-Addressing fields in the SOAP Header class of the SOAP message. If we know the operation with which the asynchronous BPEL process is returning the faults to the client, we can check the <wsa:Action>
element in SOAP Header as follows:
<wsa:Action xmlns:wsa = "http://www.w3.org/2005/08/addressing"> processFault </wsa:Action>
This element identifies the operation that was executed when the asynchronous BPEL process returned the response to the client.
The applications that integrate with BPEL processes are most interested in the results. As we saw in the asynchronous scenario recipes, as a result, we receive SOAP Header and SOAP body within SOAP message. The XML presentation is not very useful for Java applications. The better solution would be to instead have Java applications consume the Java Bean classes. For that purpose, different tools exist that enable efficient XML to Java mapping.
In this recipe, we will examine how to map the results of a BPEL process to Java-based clients.
We will need to extend the client proxy from the Calling an asynchronous BPEL process recipe, so we need to have the asynchronous BPEL process deployed and the client proxy ready.
First, we will update the response of the asynchronous BPEL process to include more XSD schema elements as follows:
<element name = "processResponse"> <complexType> <sequence> <element name = "result" type = "string"/> <element name = "postalcode" type = "int"/> <element name = "temperature" type = "double"/> <element name = "person"> <complexType> <sequence> <element name = "name" type = "string"/> <element name = "lastname" type = "string"/> </sequence> </complexType> </element> </sequence> </complexType> </element>
If we now call an asynchronous BPEL process, we will receive more information. Also, the information is nested in the response.
We will start this recipe by generating the Java Bean class that corresponds to the body of the SOAP response message. We use the
wsimport
command as follows:C:\>wsimport -keep -p org.packt.async.generated -Xnocompile -d C:\Temp\gen\ http://medion:7001/soa-infra/services/default/HelloWordlAsync/helloworldasyncprocess _client_ep?WSDL parsing WSDL... generating code... C:\>
In the directory
C:\temp\gen
, the skeleton classes of the corresponding WSDL document are now generated. If we check the content of the directory, we see that there are many more files in it. There are also request classes as well as a client proxy to initiate the BPEL process. For our recipe, we only need theProcessResponse.java
file, so we move only this file into our JDeveloper project. In JDeveloper, we create another Java package as shown in the following screenshot:We then copy the
ProcessResponse.java
file into the project. Now, our project layout consists of the following classes:We now have to adapt the
ClientProxy
class in order to support the mapping of the result to our Java client. In the AXIS package, there is a utility class,BeanUtil
, which is used for the deserialization of the XML content into Java classes. We start by preparing the variable of the result as follows:ProcessResponse responseBean;
We then deserialize the XML content of SOAP message body element through the
BeanUtil
utility class as follows:try { responseBean = (ProcessResponse)BeanUtil.deserialize(ProcessResponse.class, msg.getFirstElement(), new DefaultObjectSupplier(), null); } catch (AxisFault e) { onError(e); }
The XML content of the response from the asynchronous BPEL process is now accessible through the Java Bean as follows:
<processResponse Process"> <result>Hello Jurij</result> <postalcode>1430</postalcode> <temperature>37.5</temperature> <person> <name>Jurij</name> <lastname>Laznik</lastname> </person> </processResponse>
The response from the BPEL process presents an XML document wrapped with the SOAP message. The XML format is not very friendly for programming in Java. That is why few implementations arise with the intent to simplify the transformation of XML to Java.
Implementation |
Description |
---|---|
JAXB |
Java Architecture for XML Binding. The essential tools of JAXB are as follows:
|
JAX-WS |
Java API for XML Web Services. The important tools of JAX-WS are as follows:
|
JAX-RPC |
Obsolete: replaced by JAX-WS |
All the implementations mentioned here work with the same basic concept of serialization, deserialization, marshalling, and unmarshalling. In general, serialization and deserialization presents a way of transforming the data structures in a way that we can store them or transfer them between applications or over a network. The synonym for serialization, when we transform Java objects, is marshalling. Consequently, the synonym for the opposite operation, that is deserialization, is called unmarshalling.
The following mapping is used when we convert from XSD schema types to corresponding Java data types:
XML Schema Type |
Java Data Type |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
While the preceding table shows the default mapping between XML data types and Java data types, it is also possible to customize the mapping, usually through the configuration mapping file.
Applications written in Java usually do not operate with XML documents. If we want to call a BPEL process, we must also create a request. Until now, we used to build the request with the help of the XML document builder as follows:
OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace omNs = fac.createOMNamespace("http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess", ""); OMElement method = fac.createOMElement("process", omNs); OMElement value = fac.createOMElement("input", omNs); method.addChild(value); //value.setText("Jurij"); value.setText("FAULT");
In the request, we have to know all the information, such as namespace, names of the XML tags, and, of course, the data itself.
To simplify the creation of a request, we can utilize the JAXB tools. First, we will take the Process.java
class that we created with the wsimport
tool. We include the class into the JDeveloper project. We need to add namespace info to the annotations in the class file as follows:
@XmlRootElement(name = "process", namespace = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess") @XmlElement(required = true, namespace = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess")
We can now also change the createPayLoad()
method in the ClientProxy.java
class. We create an XML document from the DocumentBuilderFactory
class as follows:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); Document doc = dbf.newDocumentBuilder().newDocument();
Then, we create a JAXB context with the following:
JAXBContext jc = JAXBContext.newInstance(Process.class);
Finally, we create marshaller
and serialize the request class as follows:
Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); marshaller.marshal(req, doc);
The difference between the previous version of createPayLoad()
and the newer version is that the previous version lacks transparency and clarity in the code. We can now fill the request data in the following way:
Process req = new Process(); req.setInput("JURIJ");
And call it as follows:
createPayLoad(req)
To learn more about the web services request and the response message structure, refer to the Introduction section of Chapter 2, Calling Services from BPEL of this book. More information about the tools we used in this recipe is also available in that chapter.
Refer to http://docs.oracle.com/javase/7/docs/technotes/tools/share/wsimport.html for more information about the
wsimport
tool.Also, refer to https://jaxb.java.net/ for more information about the JAXB reference implementation documentation.