X

Antony Reynolds' Blog

  • December 15, 2004

Using Java from BPEL

Antony Reynolds
Senior Director Integration Strategy

Using Java from BPEL with WSIF


Often customers have existing Java code that they would like to use from within BPEL.  There are several approaches to this including



  • Calling the code directly using the <bpel:exec> construct.

  • Wrapping the Java code as a SOAP Web Service.

  • Wrapping the Java in WSIF.


All three options are viable. However they each have their own advantages and disadvantages,



  • Using the exec tag is very efficient but makes the BPEL source a little unreadable as you now have Java code mixed up with your BPEL tags.  The dependencies of the code are also hidden from the developer because BPEL variables are accessed directly from java, rather than being passed as parameters.  However using this approach you have access to the whole BPEL environment and so can do things that are not possible with any other way of invoking java.  It is also quick and easy to do!

    <BR/>Only use this for short simple snippets of java.

  • Creating a SOAP service from existing Java code is very quick and easy using the wizards in JDeveloper, however this does require the developer to deploy the Web Service seperately.  In addition there is now the overhead of a SOAP call to invoke the java code.  This approach does keep the BPEL nice and clean and the service can easily be re-used by other BPEL processes.

    <BR/>Use this when the service needs to be accessible from multiple machines and different BPEL processes and or other applications.

  • Wrapping the code in the Web Service Invocation Framework (WSIF) in many ways gives you the best of both worlds.  The code is kept seperate from the BPEL process and any dependencies are made explicit as all information is passed via parameters into the service.  However because the binding is to Java and not SOAP, there is no SOAP overhead and the invocation can be very efficient compared to packaging up a SOAP call.  Finally the code can easily be re-used by other BPEL processes by deploying the jar file containing the java classes and the WSDL document as part of a BPEL suitcase.


So now you are sold on the benefits of the WSIF approach, how do you actually do it?


Wrapping the Java Code


It's generally easier to create a Java wrapper for the code you want to call, as it often requires a little setting up, such as creating a java Locale for localisation, or setting up the JNDI environment.  So create a Java wrapper class that presents a nice clean API for use by the BPEL code.


Creating the WSIF File


There are several steps involved in creating the WSIF file.  Start with a simple WSDL file such as might describe a BPEL process and then do the following.


Definitions Tag


Add the highlighted schema to the normal WSDL defintions

<definitions name="TestService"

targetNamespace="http://oracle.com"

xmlns:tns="http://oracle.com"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:format="http://schemas.xmlsoap.org/wsdl/formatbinding/"
xmlns:java="http://schemas.xmlsoap.org/wsdl/java/"

xmlns="http://schemas.xmlsoap.org/wsdl/">

The format namespace adds support for mapping Java types to XML Schema definitions.  The java namespace allows the binding of WSDL operations to methods on a Java class.  The next sections will show how these schema extend WSDL to support Java binding.


Type Definitions


It is necessary to map the Java types used in your API onto the XML Schema definitions in your WSIF document.  This is done using the binding tag.


      <binding name="JavaBinding" type="tns:TestService">

<java:binding/>

The java:binding tag identifies that this is bound to Java code rather than a SOAP service.

      <format:typeMapping encoding="Java" style="Java">

The format:typeMapping tag tells us that we will be mapping XML Schema types onto Java types.

      <format:typeMap typeName="xsd:string" formatType="java.lang.String" />

The format:typeMap tag explains what Java type is to be used for each XML schema type in the interface.  In this case we are mapping an XML string onto a Java String object.

In addition to Java object types it is also possible to map Java primitives.


<format:typeMap typeName="xsd:boolean" formatType="boolean" />

Most Java methods of any consequence throw some sort of exception.  Rather than mapping the whole exception class it is often easier to treat the exception as a black box, the exception type being sufficient to figure out what went wrong.  In that case we can define an XML holder for the exception that accepts any type.  For example to map an exception wisdl.test.SimpleException we may have an XML type as shown.


      <complexType name="SimpleExceptionType">

<sequence>

<any/>Type> 

</sequence>pe> 

</complexType> 

This is then mapped onto the Java exception type as shown.

      <format:typeMap typeName="tns:SimpleExceptionType" formatType="wisdl.test.SimpleException" />

Method Mapping


The final step is now to map the Java method calls onto the WSDL operations.  This is done using the java:operation tag to identify which Java method should be used to support a given operation.

      <operation name="testString">

<java:operation methodName="testString"/>


<output name="TestStringResponse"/>

<fault name="SimpleFaultException"/>

Packaging


The WSIF file can now be used within the BPEL Process Manager just like any other WSDL file.  For it to work at runtime then the Process Manager must be able to find the Java classes referenced in the WSIF.  When using WSIF the classpath for the invoked WSIF service is different to the classpath for the BPEL process.  It is necessary to move the classes to the <BPEL_HOME>/system/classes directory. If working on a single machine this can be

accomplished by putting a line like the following into the build.xml.

      <javac srcdir="${basedir}/src/wisdl/test" destdir="${home}/system/classes" />

Otherwise the class files must be manually put into this directory.  A better approach is to wrap the classes into a jar file and deploy that jar file in the <BPEL_HOME>lib directory of the BPEL process manager.


Sample Code


The sample code for this example is available
here.  It comprises the following files



  • Simple.java

    <BR/>The Java class to be wrapped.

  • SimpleException.java

    <BR/>A sample Java exception class thrown by Simple.java methods.

  • Java_WSIF.wsdl

    <BR/>The WSIF files that wraps the Simple.java class.

  • WISDL_Test.bpel

    <BR/>BPEL process that uses the Java_WSIF service.

  • WISDL_Test.wsdl

    <BR/>Web Service definitions for BPEL process.

  • bpel.xml

    <BR/>BPEL deployment descriptor.

  • build.xml

    <BR/>Ant script to build and deploy BPEL suitcase.

  • .project

    <BR/>Eclipse Project file for BPEL Process Designer.

  • WISDL_Test.jpr

    <BR/>JDeveloper project file.


To try it out unzip the WISDL_Tets.zip file and then import the project into BPEL Process Designer (Select File->Import and choose "Existing Project into Workspace"). It is set up to deploy the compiled classes directly into BPEL classes directory. Have fun!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.