While preparing for the next session in our internal SOA for Java Professionals training program on BPEL, I revisited the BPEL activity Java Embedding that allows us to enrich a BPEL process with custom, Java based functionality. I tried to determine how best to explain, present and demonstrate this activity to my colleagues. This article is a brief summary of what I will tell them. It may help you to quickly get up to speed with this activity in BPEL using Oracle SOA Suite 11g.
The Java Embedding activity allows us to add activities in a BPEL process in which we can write a Java snippet using standard JDK libraries, the BPEL APIs, custom and 3rd party Java Classes included in JAR files in deployed SCA composites (in SCA-INF/lib directory) and Java Classes and libraries available on the Classpath for the SOA Suite run time (note: through the oracle.soa.ext.jar file in the directory
<FMW_HOME>/soa/modules/oracle.soa.ext_11.1.1 we make the resources available at run time; use the ANT script in this directory to add custom classes and JAR-files to the oracle.soa.ext.jar file).
I will show the creation of the Hello World of Java Embedding – a very simple BPEL process that has a string as an input and a string as output. This simple process contains a Java Embedding activity that uses Java to:
- Write a line of log output to the console
- Set the name for the composite instance
- Access the name element in the input parameter
- Set the value on the output parameter
- Write an entry in the BPEL audit trail
Note: no 3rd party libraries or custom classes are required for these actions.
The process looks like this:
The code in the Java Embedding activity is the following:
try { System.out.println("==> HelloWorld - Java_Embedding_setOutput, processing input; instance id "+getInstanceId()); // note: XMLElement can only be used if it is imported using <import> in the BPEL Process XMLElement input = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:input"); String name = input.getTextContent(); System.out.println("qname "+input.getQualifiedName()+" value = "+name); addAuditTrailEntry("executing HelloWorld.Java_Embedding_setOutput for "+ name); setCompositeInstanceTitle("Composite HelloWorld "+name); // note: this statement fails if the targeted element does not already exist setVariableData("outputVariable", "payload", "/client:processResponse/client:result", "Hello "+name); } catch (Exception e) { System.out.println("exception "+e.getMessage()); addAuditTrailEntry(e); }
The IDE presents the snippet like this:
Note that the IDE does not offer fancy features such as code completion or even design time compilation of the code: only during deployment of the SOA Composite to the SOA Suite run time environment will the correctness of the code be verified. It took me a lot of time to get the code correctly constructed – as I am a lousy typer and used to a instant compiler alerting me to any coding mistakes.
The XMLElement class used in this snippet is not part of the standard JDK APIs. Therefore, this class has to be imported in the BPEL process, using a special import element:
<import location="oracle.xml.parser.v2.XMLElement" importType="http://schemas.oracle.com/bpel/extension/java"/>
This snippet uses a number of the API methods available for use in Java Embedding:
- getVariableData() – to access variables in BPEL process
- setVariableData – to set the value on variables
- addAuditTrailEntry() – add an entry to the audit trail
- getPreference() – access preference (property)
- setCompositeInstanceTitle() – set the title that is displayed in the EM FMW Console
- getInstanceId( ) – get value of Unique ID associated with this BPEL process instance
- lookup() – do JNDI lookup – for example to get hold of EJB
- setStatus(), setTitle(), setCreator – set meta data on process instance
- setIndex() – set up to 6 index variables that can be used to query process instances through the BPEL API
When the application is deployed and the service is invoked, the effect of the Java code can be seen in various placing, obviously including the response from the service exposed by the BPEL process:
The response is constructed in the line of code in the snippet that uses setVariable to manipulate the outputVariable.
The console window contains the following line, produced by the System.out.println statement:
The title for the composite instance is set in the snippet and the result is seen in the list of instances shown in the EM FMW console:
Finally, the code adds an entry to the Audit Trail for the BPEL process. This entry is seen in the Flow Trace details for the BPEL process instance:
More interesting things can be done through Java Embedding when 3rd party libraries or custom classes and libraries are engaged. Some additional steps may be required to include this code with the SOA Composite or across the SOA Suite run time environment. See the resources mentioned below for more details.
A few words of warning with regard to Java Embedding in BPEL processes:
Java Embedding means functionality hidden inside, in a not very decoupled way. The Java code is hard to maintain. By embedding Java in BPEL (XML driven) we start mixing technology paradigms, that require different skills as well as expensive XML to Java Object marshalling and unmarshalling.
The best use cases for Java Embedding seems to be advanced logging/tracing or for special validations/transformations. Not to replace built in capabilities of the BPEL engine as well as the other components in SOA Suite 11g and the adapters that come with it. For more extensive custom Java logic, the Spring Component should be considered, rather than including larger sections of Java code in a BPEL process.
Resources
Incorporating Java and Java EE Code in a BPEL Process – BPEL Documentation for PS4 http://docs.oracle.com/cd/E15586_01/integration.1111/e10224/bp_java.htm
Useful blog-articles on Java embedding in BPEL processes
- http://blog.andrade.inf.br/2010/09/generating-custom-logs-with-log4j.html
- http://yatanveersingh.blogspot.com/2011/08/how-to-call-java-method-inside-bpel.html
- http://beatechnologies.wordpress.com/tag/java-embedding-in-bpel/
- https://technology.amis.nl/blog/14229/soa-suite-11g-set-the-composite-instance-title-with-a-bpel-component
Hi,
I am facing an issue related to java embedding .
Here is what I am trying to achieve.
I have to generate a MD5 hash string from an xml file content then I have to check if it matches with another MD5 hash string.
Below is java code I am using.
String md5=getVariableData(“md5Var”).toString(); //this is the variable that needs to be md5 hashed
try{
MessageDigest md = MessageDigest.getInstance(“MD5”);
byte[] myByteArray1 = md5.getBytes(“UTF-8”);
byte[] myByteArray2 = md.digest(myByteArray1);
BigInteger bigInt = new BigInteger( 1, myByteArray2);
String javahashedstring = bigInt.toString(16);
setVariableData(“md5Var”, javahashedstring, false); //return md5 hashed variable
}catch (Exception ex){
ex.printStackTrace();
}
The above java code works fine if I run it as a standalone program.
The java program has is using Message digest class which is present in JSR177.I have added that in sca-inf\lib folder of the composite, added to the project properties->Library and classpath.
I have also added this jar to the my soa server folder E:\SOA11G7\Oracle\Middleware\Oracle_SOA1\soa\modules\oracle.soa.ext_11.1.1 and after that I ran Ant command as per the oracle documentation.
Also I am using bpel 2.0.My JDK version is JDK1.6.29
But it still give me below error.I have spent a lot of time on this by going through various documentation and blogs but I am still not able to find an answer.
Any suggestion/pointers would be appreciated.
Thanks Lucas. You rock as always !!!
hi
We ran the ant script after placing the jar file in <FMW_HOME>/soa/modules/oracle.soa.ext_11.1.1and folder and also confirmed that the MANIFEST file is updated with my custom jar file name.
But oracle.soa.ext_11.1.1.x.jar file does not seem to be automatically added to the server’s classpath and hence when I restarted the weblogic server custom jar files are not being picked up.
Any other additional steps to be performed ?
Would adding oracle.soa.ext.jar explicitly onto BpelcClasspath help ?