IBM BPM, V8.0.1, All platforms > Authoring services in Integration Designer > Developing business processes > Building BPEL processes > Defining BPEL process logic > Adding an activity to a BPEL process

Use Java methods in process snippets

You can use Java™ methods in process snippets to perform a variety of functions.

Java coding methods are used in process snippets to perform a variety of functions.

When you use a process snippet in a BPEL process, the Java code does everything that you would normally do in an enterprise bean, and using the same restrictions (for example, there is no thread handling).

There are two different ways to use Java code in your BPEL process:

In both of these cases, the Java code accesses objects defined in the enclosing BPEL process. These objects are either data types or Java objects representing primitive data types. These objects consist of variables and their properties such as:

You can access the snippet process variables the same way as you would access them if they were local variables in the Java method.

You can use any BPEL variable in a snippet without the need to declare it. There is no separate input or output data specified for a snippet activity. In the case of more complex objects, XML-based schema types can be mapped to corresponding Java types using predefined mapping rules.


Process Variables

A process variable can be specified in several ways:

  1. You can initialize a process variable on the properties view details tab when you select the variable in the BPEL process editor.

  2. You can assign the WSDL message type, which is defined as an XML-schema. In this case the message can either be handled in RPC style (where the representation of the message is the corresponding Java class) or in document/literal wrapped style (where a single-part message of a primitive type is encapsulated in a commonj.sdo.DataObject).

  3. Assign the XML schema directly to the variable. The primitive types are mapped to the corresponding Java class.

    For example, xsd:int is mapped to java.lang.Integer. Complex types are represented by a commonj.sdo.DataObject.

BPEL process variable changes in Java code

Changing the value of a BPEL process variable in a Java code snippet is visible to other activities and in some cases persists across activities.

Comparing Java snippets with Java conditions and expressions

By default, BPEL process variables are accessible for read/write access in Java snippet activities. This means that changes to BPEL process variables persist after the Java snippet is executed. This is also true for all modified BPEL process variables if a Java exception occurs during the execution of the Java snippet.

For Java conditions and expressions (including join conditions, transition conditions, while conditions, and wait durations), the default access for BPEL process variables is read-only. This means that changes to BPEL process variables are discarded after the Java condition or expression is evaluated. However, when the changes are discarded depends on the data type (complex or boxed-primitive) and the process execution mode (long-running or microflow). A common pitfall is a while condition in which a counter is evaluated and then increased or decreased. This action can fail because the default access for the BPEL process variables used in the while condition is read-only.

Improving the BPEL default behavior

Sometimes, the default behavior is not sufficient. If you specify BPEL process variables as read-only access in Java snippets, this setting reduces the probability of database deadlocks and can therefore improve the overall BPEL process performance.

For example, if you use four variables to initialize a fifth variable without specifying read-only access on the four variables, five database updates will occur.

Specifying the variables as read-only saves four unnecessary database updates, including four unnecessary update events. The read-only access also lowers the probability of database deadlocks. This can be either done manually in the java code (see the following Code Example section) or, as it would be recommended, using the “Performance” property page (refer to the following Performance property page section).

In some cases, conditions such as the while condition (that evaluates a counter and modifies it in one step) ensures that the BPEL process definition can be kept more readable by specifying the counter BPEL process variable as read/write access instead of separate the counter modification of the evaluation.

Code example

The following presents an example on how you can manually add bpc pragmas to your Java code.
// @bpe.readOnlyVariables names="<space separated list of BPEL Variables>"
// @bpe.readWriteVariables names="<space separated list of BPEL Variables>"

If the following example:
// @bpe.readWriteVariables names="LoopCounter Amount"

This example specifies read/write access to two BPEL process variables, LoopCounter and Amount. You can place these pragmas at any position in your Java code, but you need to specify them for each Java snippet, condition, or expression separately. For better readability, list these pragmas at the beginning of the Java code.

Performance property page

Declaring read-only access to BPEL process variables manually is done on a property page. Specifying BPEL process variables that are accessed as read-only variables improves the overall BPEL process performance (see the Improving the BPEL default behavior section earlier in this topic). The property page shows all process variables used in the Java snippet activity. The variables which are already specified as read only variables (because they are already included in the existing pragma of the snippet) have a check mark. Selecting a variable adds it to the variable list that is defined in the pragma, clearing a variable removes the variable. If no pragma exists and a variable is checked, the pragma is inserted automatically, similarly, if the last variable of the pragma gets removed, the pragma is also removed.


Create data objects

To create data objects you need the BOFactory service. The following code snippet shows how you can obtain the BOFactory service:

BOFactory boFactory = 
(BOFactory)ServiceManager.INSTANCE.locateService("com/ibm/websphere/bo/BOFactory");

To create a nested data object, you can use the createDataObject method of the DataObject class:

DataObject nested = Output.createDataObject("processBusinessObject");

You can also create a data object using the create method of the BOFactory service.

You have to specify namespace and name so that the order of the parameters matches the order that is used in the code sample:

MyBO = factory.create("http://JavaSnippets/bpc/samples","BO");

Copying data objects

To copy data objects, you need the BOCopy service. The following code snippet illustrates how you can obtain the BOCopy service:
BOCopy copyService = 
(BOCopy)ServiceManager.INSTANCE.locateService("com/ibm/websphere/bo/BOCopy");

The BOCopy service offers two methods to create a deep copy of data objects: copy and copyInto. The copy method returns a copy of the original DataObject and the copyInto method allows copying the original DataObject into the structure of an existing DataObject. This is especially needed when you use Java code in order to iterate over an array and want to move elements from one array to another. In order to achieve this, first create a deep copy of the element that you want to move.

Copy

DataObject dataObject = copyService.copy(ProcessBusinessObject);

CopyInto

copyService.copyInto(ProcessBO, Output, "processBO");


Java methods

The following table provides a list of the available Java methods:

Available Java methods
Java method Function

getServiceRefFromPartnerLink

commonj.sdo.DataObject getServiceRefFromPartnerLink( String partnerLinkName, int role )

These methods can be used to either specify or retrieve the Service destination at the end of the named partner link.

The role value must be one of:

  • PARTNER_LINK_PARTNER_ROLE
  • PARTNER_LINK_MY_ROLE

A DataObject is returned that contains an EndpointReference object with the name "EndpointReference".

setServiceRefToPartnerLink

void setServiceRefToPartnerLink( String partnerLinkName, commonj.sdo.DataObject serviceRef)

getVariableProperty

Object getVariableProperty( String variableName, QName propertyName )

These methods either specify or return the value of a process variable's property. If either the property or the variable do not exist, a StandardFaultException of kind "selection failure" is thrown. If the value is not compatible to the type of the property, a StandardFaultException of kind "mismatch assignment failure" is thrown.

An alternative way to specify a process variable is on the details tab of the properties view when you select the variable in the BPEL process editor.

setVariableProperty

void setVariableProperty( String variableName, QName propertyName, Object value)

getCorrelationSetProperty

Serializable getCorrelationSetProperty( String correlationSetName, QName propertyName )

This method can be used to retrieve the properties of correlation sets that are declared at the process level. If either the property with name propertyName or the correlation set with name correlationSetName do not exist, a StandardFaultException of kind “selection failure” is thrown.

getProcessCustomProperty

String getProcessCustomProperty( String name)

Use these methods to access or define custom properties at the process level.

The value for propertyName must be a valid NCName, and cannot be greater than 220 bytes in UTF-8 format. Not all functionality can be guaranteed for non NCNames.

setProcessCustomProperty

void setProcessCustomProperty( String name, String value )

getActivityCustomProperty

String getActivityCustomProperty( String activityName, String propertyName )

Use these methods to access or define custom properties at the activity level. If the activity does not exist, or activityName does not uniquely qualify an activity, a StandardFaultException of kind “selection failure” is thrown. If the value exceeds 254 bytes, an InvalidLengthException is thrown.

The value for propertyName must be a valid NCName, and cannot be greater than 220 bytes in UTF-8 format. Not all functionality can be guaranteed for non NCNames.

setActivityCustomProperty

void setActivityCustomProperty( String activityName String propertyName, String value )

getLinkStatus

boolean getLinkStatus(String linkName)

This method can be used in join conditions to access the state of the incoming links.

activityInstance

com.ibm.bpe.api.ActivityInstanceData activityInstance()

Use this method to return the current activity as an object in order to access its context

activityInstance

com.ibm.bpe.api.ActivityInstanceData activityInstance( String activityName)

Use this method to select an activity instance by its name.

To access an activity using this method, the activity must conform to the following restrictions:

  • The activity name must be unique within the scope of the process.

  • The activity must be a basic activity.

  • If the activity is nested within an event handler, or forEach activity the Java code snippet that accesses the activity must be within the same event handler, or forEach activity.

  • The activity must be a predecessor of the current Java code snippet (navigation-wise).

  • The activity must be persisted in the database. That is, the attribute businessRelevant of the activity is to be set to "true".

processInstance

com.ibm.bpe.api.ProcessInstanceData processInstance()

Use this method to return the current process as an object in order to access its context.

raiseFault

void raiseFault( QName faultName )

void raiseFault( QName faultName, String variableName )

void raiseFault( QName faultName, Serializable message )

Use this method to raise a fault in the surrounding process.

forceRollback

void forceRollback( )

Use this to cause the compensation of the microflow. This method will not work with long running processes.

BpelException

com.ibm.bpe.api.BpelException getCurrentFaultAsException()

Use this method to provide access to a Java exception within a fault handler.

getServiceRefForProcessTemplate

commonj.sdo.DataObject getServiceRefForProcessTemplate( String processTemplateName, String portTypeNamespace , String portTypeName )

Returns a service reference to the port type portTypeNamespace, portTypeName of the process specified by processTemplateName.

If multiple versions of a process template are available, the service reference is returned to the current valid version.

Important: Verify that you have added an export with an SCA binding for the corresponding process component in the assembly editor. Otherwise, no service reference is returned.

Adding an activity to a BPEL process


Related concepts:
Replacement variables and context variables
Use custom properties for human tasks
Use event handlers


Related tasks:
Modify the properties of an activity
Modify the type of an activity
Work with basic activities
Work with structured activities
Modeling human workflows