I had listed invoking Bpel process from Java using WSIF as one of the exciting tasks that you can try out in your free time. Today I will be explain on how to start working on this using an HelloWorld example.
Given below are some of the classes we will be using for WSIF invocation.
WSIFServiceFactory
Abstract factory class to create instances of WSIFService. Call newInstance to get a instance of the factory. newInstance() method will create WSIFServiceFactoryImpl object
Factory class used to create instances of WSIFService. Create a WSIFService from WSDL document URL. If serviceName or serviceNS is null,then WSDL document must have exactly one service in it. If portTypeName or portTypeNS is null,then WSDL document must have exactly one portType in it and all ports of the selected service must implement the same portType.
WSIFService
A WSIFService is a factory via which WSIFPorts are retrieved. This follows the J2EE design pattern of accessing resources (WSIFPorts, in this case) via a factory which is retrieved from the context in which the application is running
WSIFPort
A WSIFPort represents the handle by which the operations from the <portType> of the <port> of this WSIFPort can be executed
WSIFOperation
A WSIFOperation is a handle on a particular operation of a portType that can be used to invoke web service methods. This interface is implemented by each provider
try {
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService("http://hostname:port/orabpel/default/HelloWorld/1.0/HelloWorld?wsdl",
"http://xmlns.oracle.com/HelloWorld", "HelloWorldService",
"http://xmlns.oracle.com/HelloWorld",
"HelloWorldType");
WSIFPort port = service.getPort();
// Create the operation object for the getOutput operation in the WSDL
WSIFOperation operation = port.createOperation("getOutput", "HWReqMessage", "HWRespMessage");
WSIFMessage inputMsg = operation.createInputMessage();
WSIFMessage outputMsg = operation.createOutputMessage();
WSIFMessage faultMsg = operation.createFaultMessage();
inputMsg.setObjectPart("input", new String("geo"));
// invoke the Service
boolean success = operation.executeRequestResponseOperation(inputMsg, outputMsg, faultMsg);
String output = (String)outputMsg.getObjectPart("output");
if (success == true) {
System.out.println(" Result..!!" + output);
} else {
System.out.println("No Result..Unable to execute the Operation!!");
}
} catch (WSIFException we) {
we.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Here operation.executeRequestResponseOperation() method will execute a request-response operation. The signature allows for input, output and fault messages. WSDL in fact allows one to describe the set of possible faults an operation may result in, however, only one fault can occur at any one time.
inputMsg - operation.createInputMessage()
Create an input message that will be sent via this port.
outputMsg - operation.createOutputMessage()
Create an output message that will be received into via this port.
faultMsg - operation.createFaultMessage()
Create a fault message that may be received into via this port.
Now create a BPEL process HelloWorld which will take the input and assign “Hello world” and input as a concatenated string to the output.
You need to remember some points while modifying the HelloWorld WSDL which is required before invoking from java using WSIF. Add a binding part to the wsdL. In Porttype tag modify the input and output operation to add the name attribute .This name attribute value will be used in creating oeration using port. createOperation() method.
HelloWorld WSDL
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="HelloWorld"
targetNamespace="http://xmlns.oracle.com/HelloWorld"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:client="http://xmlns.oracle.com/HelloWorld"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<schema targetNamespace="http://xmlns.oracle.com/HelloWorldType"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
</schema>
</types>
<message name="HelloWorldRequestMessage">
<part name="input" type="xsd:string"/>
</message>
<message name="HelloWorldResponseMessage">
<part name="output" type="xsd:string"/>
</message>
<!-- portType implemented by the HelloWorld BPEL process -->
<portType name="HelloWorldType">
<operation name="getOutput">
<input name="HWReqMessage" message="client:HelloWorldRequestMessage" />
<output name="HWRespMessage" message="client:HelloWorldResponseMessage"/>
</operation>
</portType>
<binding name="MyBinding" type="client:HelloWorldType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getOutput">
<soap:operation style="rpc" soapAction=""/>
<input name="HWReqMessage">
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output name="HWRespMessage">
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<plnk:partnerLinkType name="HelloWorld">
<plnk:role name="HelloWorldProvider">
<plnk:portType name="client:HelloWorldType"/>
</plnk:role>
</plnk:partnerLinkType>
</definitions>
Some errors you may face during runtime are
Exception#1
org.apache.wsif.WSIFException: No provider exists for the binding http://schemas.xmlsoap.org/wsdl/soap/
or
Exception in thread "main" java.lang.NoClassDefFoundError:oracle/j2ee/ws/wsdl/extensions/wsif/schema/Schema2Java
Solution
Add wsa.jar
Exception#2
unknown prefix in QName literal: null at oracle.j2ee.ws.common.encoding.simpletype.XSDQNameEncoder.stringToObject(XSDQNameEncoder.java:75)
Solution
The xsd elements are not read properly. Then instead of having complextypes use primitive types as your message parts
Exception #3
Exception in thread "main" java.lang.NoClassDefFoundError: javax/wsdl/Definition-
Solution
Add wsdl4j-1.5.1.jar
For compiling the process you need wsif.jar from webservices lib.
orabpel.jar , jaxrpc-api.jar, wsa. jar, http_client.jar, wsdl4j-1.5.1.jar are some of the jars required for runtime execution of the java program. There wil be mutiple wsif.jar’s available in your machine.Try to use the one provided by oracle since we are trying to connect to the oracle bpel process .