Java WSIF Revisited
Revisiting Java and WSIF
With the imminent release of 10.1.3.1 of JDeveloper and BPEL as part of the SOA suite I thought I might revisit what has proved to be a popular subject - calling Java from BPEL using WSIF.When I first addressed this topic I had to hand crank the WSDL to describe my Java classes. The latest JDeveloper will take care of this for me.
The instructions below are based upon a pre-release version of JDeveloper and SOA Suite 10.1.3.1. However I don't expect any differences from the production release.
The Problem
Often we have some java code that we want to call from BPEL. We could embed this into a bpelx:exec tag but it is cleaner to wrap it as a web service. By using a java WSIF binding we can avoid the overhead of a SOAP call and jump straight into the java from BPEL. To do this we need to do three things- Create a WSDL document describing the java class we want to call and its WSIF binding.
- Use the WSDL to define a partner link and invoke it from within our BPEL process.
- Put the java code somewhere where it can be found by the BPEL process manager at runtime.
The Scenario
I created a simple 'Hello World' java class that has two methods.- String hello(String name);
- String hello(Person p);
The first method demonstrates the simple case of primitive type parameters. The second method shows a more complex class structure being used as a parameter. The class diagram is shown below.

I now want to be able to call these two methods from BPEL.
Wrapping the Java Code
To start with I wrapped the Java code with WSIF. I pointed at the Java class in the applications navigator and selected 'Create J2EE Web Service'.
I then selected the J2EE 1.4 service type.

In the wizard I changed the name of the service to a sensible name 'GreetingService' and I added WSIF to the list of bindings. There seems to be a bug in that if you don't leave at least one SOAP binding in place you are unable to select the correct encoding.

In step 2 of the wizard you need to select a literal encoding (doesn't matter if it is document literal or RPC literal, I chose RPC literal). If you don't select a literal encoding then the generated service has a wrapper class around the parameters for which there is no equivalent Java class. You can then finish the wizard.
At this point the wizard has generated the following files
- GreetingService.java - this provides an interface that defines the service
- GreetingService.wsdl - this is the actual service definition, including the SOAP and WSIF bindings
- GreetingService-java-wsdl-mapping.xml - this provides details of the actual java class /XML element mapping
Note that we now have a service with two endpoints, one a SOAP endpoint and the other a Java class endpoint through WSIF.
A final gotcha
Before moving on to use the service there is a final gotcha in the beta version at least. Web services are not allowed to overload methods. In our example we have two hello methods distinguished by their signatures. The wizard generates a WSDL with two methods, hello and hello2. This is good but unfortuantely it then sometimes gets the mapping wrong (seems to happen on some routes through the wizard and properties file but not others), mapping the WSDL method 'hello2' to java method 'hello2'. The solution is to manually edit the WSDL file and go and change this mapping as shown below so that WSDL operation hello2 maps to java method hello.
<operation name="hello2">
<java:operation methodName="hello" methodType="instance" parameterOrder="name"
returnPart="result"/>
We are now ready to start using our new WSIF service in a BPEL process.
Using the Binding from BPEL
To use the new service from BPEL we must first create a partner link to the service. We then import the WSDL generated previously into this project by looking it up on the local file system. Once found and loaded we agree to copy the file into the BPEL project and create a wrapper WSDL with appropriate BPEL partner link entries. We then select the partner role to indicate who is implementing the service.

We can now go ahead and finish the process. I created a simple synchronous process to test this out, using a switch on a boolean input parameter to decide which method to call, the simple parameter one (true) or the complex parameter one (false).

We now have a BPEL process that uses our WSIF Java binding. Time to try them out.
Deploying the Process and Java Classes
First we deploy the BPEL process, using either JDeveloper, the command line or the console. This will deploy not only the BPEL process but also the WSDL that describes our WSIF binding. We now need to make sure that BPEL is able to find the classes referenced by our WSIF binding, and ultimately any other classes that are used by those classes (the transitive closure). The quickest easiest way to do this is to take the classes directory from our JDeveloper java project and drop it into the $ORACLE_HOME/bpel/system/classes directory. Note that the location of this has changed in the 10.1.3 release. It used to be buried away under $ORACLE_HOME/integration. Once we have transferred the classes then we can test our process by invoking it from the console.
We can enter the method we wish to test by choosing the simple or compex parameter flag to the process and then provide a first and last name. The first and last name are conacatenated by the BPEL process in the case of a simple string parameter method call. In the case of a complex parameter then the first name and last name are copied to the appropriate elements of the complex message that is passed into the invoke operation.
Hopefully if all has gone well then we will receive a greeting back from the web service.
The Java project for this entry is available here and here is a BPEL project that can be used to test the binding. Enjoy!
In theory I should also be able to use JDeveloper 10.1.3 which is currently production to do this, but I haven't got it installed on my system, I would be interested to know if it all works OK in tha release.