SOAP started as a simple way of doing synchronous RPC over HTTP (Internet) but since then it has morphed into doing both synchronous and asynchronous RPC over multiple transports.
There has been a trend to use asynchronous transport in Enterprise Class applications over the last few years. Decoupling with asynchronous transport enables the applications to scale better and simplifies the processing logic in applications from reliability handling point of view (that is, retransmissions, timeouts, and duplicate detection). Because Web services are positioned as the technology for enabling fast integration of applications, there is a movement towards exposing existing Enterprise Applications as Web services (service providers). Clients of such services (service consumers) can access these services with multiple levels of reliability depending on the transport used to access the services.
When these services are accessed through HTTP, limited guarantees are available at the transport level and client applications have the responsibility to check for timeouts, retransmissions, and duplicate detection. For low-volume applications that access short running business processes with a finite response time, this is a low cost solution. Because applications have to deal with more than business logic, low cost of transport is offset by repeated implementation of complexity in multiple applications.
But when service providers are accessed through a reliable asynchronous transport, service consumer applications can shed some of its responsibilities because the Message Oriented Middleware (MOM) handles these issues on behalf of the application and hence applications can focus more on the business logic. This is especially true where legacy MQ applications, supporting a fire and forget model, are exposed as service providers.
SOAP over asynchronous transport is an application pattern that is getting a lot of attention for myriad of reasons. Long running business processes, loose coupling of service provider and service consumer from service availability and separation of component boundary point of view, increased scalability of services due to reduced execution path lengths in the asynchronous models are some of the reasons. Reliability of Web services can be improved through acknowledgements in the SOAP message itself (for example, ebXML) or through carrying SOAP payload in a more reliable transport than HTTP. The focus of this document is to show design alternatives for carrying SOAP payload over an asynchronous transport like MQSeries, although the same argument can be extended to products from other MOM vendors.
This document assumes basic understanding of the Web services stack and WebSphere MQ.
There are multiple design approaches in providing solution to SOAP over asynchronous transport application pattern.
- First method is by using the extensibility of WSDL to include asynchronous transport binding.
- Second method is by using a framework, which allows transport handlers to be plugged in the pathway between the service consumer and the service producer.
- Third method is by introducing custom adapters that do protocol conversion from HTTP to MQ/JMS.
With the first approach, should the binding be to WebSphere MQ or JMS? There is no industry standard way of extending WSDL bindings and different vendors are implementing WSDL extensions by binding transport natively to the transport, although there is concurrence that binding over JMS should be the way to go and Apache's WSIF is close to specifying the XMLSchema for such a binding. See the Resources section for more information about WSIF. But the more difficult part is the availability of tools (java2wsdl and wsdl2java) for generating stubs and skeleton that handles asynchronous transport and it is currently not available in WSIF.
An example of the second approach is the Apache's Axis framework that allows handlers to be chained at both the client and server ends. An example of the third approach is mentioned in the article. (See Resources.)
In this paper we have tried to dig a little deeper on implementation issues and analyze the design alternatives 1 and 2 presented in the previous section.
Also, WSDL specification supports four transmission primitives that an end point can specify:
- One-way
- Request/reply
- Solicit/response
- Notification
In this paper, we are interested in evaluating design implications for one way and request/reply communication patterns. Solicit/response and notification a pub/sub model and is transmission primitives are currently excluded from the discussions. Security related details in the architecture will be covered in the next article.
An established way of invoking services through SOAP over HTTP, as used by Axis, is shown below. Java2Wsdl tool generates the WSDL with HTTP binding. Wsdl2Java tool generates the stubs required by client application and skeletons used by the server side.
Figure 1. Baseline case - SOAP over HTTP transport

When the client implementation makes the RPC call, the stub does the marshalling of the request along with the serialization of the arguments. Other issue connected with this operation is the encoding of Java programming language type to XML type and its decoding back to Java programming language type. WSDL becomes the component interface for the service. Out of the three aforementioned design alternatives, the first two are addressed in this section.
Alternative 1: Using WSDL with MQ transport binding with MAOR Supportpac
This architecture is used by MA0R. The support pac provides its own implementation of Java2Wsdl and Wsdl2Java tools that generate and handle WSDL with MQ native binding. They have defined URI mapping to accomplish this. The diagram below shows how it is accomplished.
Figure 2. Using WSDL with MQ transport binding

The SupportPac provides a plug-in transport for the Apache Axis Web Services framework and permits interoperation over a WebSphere MQ transport between clients and services written in either of these environments.
A client program calls the appropriate Axis framework in the usual way. The stub marshals the call into a SOAP request message exactly as for SOAP/HTTP.
When the stub identifies the URI [wmq:xxx], it calls the WebSphere MQ transport sender code provided in MA0R SupportPac. This is then transported to a listener also provided with MA0R. This listener reads the incoming SOAP request, and hands it to the appropriate Web Services infrastructure. This infrastructure invokes the service, exactly as it would have done for a message that arrived on an HTTP transport.
It then marshals the response into a SOAP response message and returns it to the MA0R listener. The listener returns the message over WebSphere MQ to the MA0R sender, which passes it to the client Web services infrastructure. The client infrastructure parses the response SOAP message and hands the result back to the client application.
Alternative 2: Using Axis as a framework instead of WSDL extension
The Axis framework is a Java-based, open source implementation of the latest SOAP specification, SOAP 1.2, and SOAP with Attachments specification from the Apache Group. The following are the key features of this Axis framework:
- Flexible Messaging Framework: It provides a flexible messaging framework that includes handlers, chain, serializers, and deserializers. A handler is an object processing request, response, and fault flow. A handler can be grouped together into chains and the order of these handlers can be configured using a flexible deployment descriptor.
- Flexible Transport Framework: Axis provides a transport framework that helps users to create their own pluggable transport senders and transport listeners.
- Data Encoding support: Axis provides automatic serialization of a wide variety of data types as per the XML Schema specifications and provides a facility to use your own customized serializer and deserializer.
- Additional Features: Axis 1.2 provides full support for WSDL as well as Logging, Error, and Fault Handling mechanisms
This alternative makes use of the Flexible Transport feature of the Axis framework and does not make use of WSDL extension. The diagram below shows the architecture for this alternative.
Figure 3. Using transport handler in Axis Framework

There are no stubs/skeletons generated in this case. Client would set the transport handler to be invoked in the application and calls the Web service using SOAP APIs.
A deployment descriptor, which specifies the transport handler, is prepared and deployed onto the Axis engine at the client side. At run time, the Axis framework loads the transport handler.
A JMS transport handler is used to send and receive SOAP messages over JMS.
The above framework can be demonstrated using the following steps:
- The SOAP client constructs the call object, sets the location, service, method name, and the transport mechanism and invokes the Axis Client.
- The Axis client checks the transport object in the deployment descriptor and loads the transport handler deployed for JMS Transport.
- The JMS SOAP Handler receives the SOAP request from the client and puts the request onto the request queue
- When the message arrives at request queue, the JMS SOAP Listener takes the JMS request, and converts it to a SOAP request and invokes the Axis Server engine.
- The Axis Server engine invokes the corresponding Web service and gives the response back to the JMS Listener which places the reply onto the response queue.
- The JMS SOAP Handler gets notified upon the arrival of the reply message. It then converts the reply onto a SOAP message and returns it to the client.
For a given problem description, this section compares the ease of deployment, client implementation, execution and operations for two solutions based on the two alternatives identified in previous section. It is important to note that messaging is persistent and client code optimizations have been made for better performance (where applicable these are indicated). Using non-persistent WebSphere MQ is a more expensive solution than using HTTP because it does not improve the reliability characteristics.
Data Transformation is a common service used in the application integration space. As a representative service to expose, we have utilized a Cash Trade transaction. An incoming message contains the Cash Trade details as an XML and the transformation on fields of the Cash Trade message is done based on a XSL file to meet the Schema specified by the receiving application. This includes both structural and semantic changes to the message. The message size is approximately 35K bytes.
To simulate the problem, we created a Web service where the LOB AD can setup the transformation by registering an XSL and subsequently utilize the transformation service by invoking the transformation with the payload. This is currently a suboptimal version where setting up of transformation and invocation of transformation is done on every request. In a production quality code, the setup() and invoke() would be two different calls with state information being retained on the server side.
Following is the implementation of "SimpleTransformation.java" which performs the transformation of the source XML file to destination XML file based on the XSL file provided. The transformation itself is outside the scope of this work.
Listing 1. SimpleTransformation
public class SimpleTransformation {
public int setupTransformation(byte[] b1, byte[] b2) throws Exception,
SAXException,TransformerConfigurationException{
// Instantiate a TransformerFactory.
tFactory = TransformerFactory.newInstance();
// convert the incoming byte array to InputStreams
.....
.....
InputSource isource = new InputSource(is2);
Source source = new SAXSource( isource );
Result result = new SAXResult( serializer.asContentHandler());
//transform
transformer = tHandler.getTransformer();
transformer.transform( source , result);
return 1;
}
}
|
This prototype was setup on Windows 2000 platform with a PIII Processor, 256MB memory. The client and server were both running on the same machine so that the network time would not impact the analysis.
Alternative 1: Using MQ WSDL binding extension (MA0R)
Deployment
Running "deployWMQService.bat" (Windows) provided in the SupportPac from the directory holding the source code for the service, deploys services.
Deployment performs several actions. Following are the steps performed by the deployWMQService batch file on Windows NT
- Compiles the source and puts the class into the classes subdirectory javac SimpleTransformation.java
- Generates the appropriate WSDL using "Java2WSDL" provided in the SupportPac. The WSDL file is named "javaDemos.server.SimpleTransformation_Wmq.wsdl". The generated WSDL file would contain the location as "wmq:SOAP.javaDemos.server.SimpleTransformation@MQSOAP.DEMO.QM?connectQueueManager=MQSOAP.DEMO.QM"
- Prepares the deployment descriptor file and deploys into the execution directory. Following are the WSDD file generated:
- SimpleTransformation_deploy.wsdd
- SimpleTransformation_undeploy.wsdd
- server-config.wsdd
- Generates the appropriate proxies for Java, from the generated WSDL file. The SupportPac provides a customized WSDL to Java stubs generator called "com.ibm.mq.ma0r.tools.RunWSDL2Java" which understand the URI "wmq:xxx". The WSDL and the proxies generated from it, will have the appropriate URI burned in to call the service. eg: "wmq:SOAP.javaDemos.server.SimpleTransformation@MQSOAP.DEMO.QM?connectQueueManager=MQSOAP.DEMO.QM"
- Compiles the Java proxies into the classes sub directory
- Prepares WMQ queues to hold requests to the service. Please note that the queue manager has to be created before this script can be run.
- Prepares a file to start the listener that will process this queue.
- Prepares the WMQ definitions that will permit the listener process to be automatically triggered. For example:
- WMQ Process: SOAP.javaDemos.server.SimpleTransformation
- WMQ Trigger Initiation Queue: SOAP.INITQ
- Deploys the generated WSDD file for SimpleTransformation into the Axis engine [Using java org.apache.Axis.utils.Admin server]
Implementing clients
Before implementing the client, the WSDL file generated has to be compiled to generate the stubs required for the client along with the deployment descriptors. The sample client code used to invoke the Web service is as shown below:
Listing 2. Client code snippet
public class WMQClient
{
public static void main( String[] args ) throws IOException, javax.xml.rpc.ServiceException
{
// Must register WMQ transport extensions before doing SOAP/MQ
com.ibm.mq.ma0r.usage.Util.registerExtensions();
Options opts = new Options( args );
int result=0;
byte[] b1;
byte[] b2;
try {
// Use the locator to get a handle to the service on a specific WSDL Port
SimpleTransformationService locator = new SimpleTransformationServiceLocator ();
SimpleTransformation service= locator.getJavaDemosServerSimpleTransformation_Wmq();
/* Convert the data in .xml and .xsl file to byte array to be passed
*to the web service
*/
.....
.....
result = service.setupTransformation( b1,b2 );
} catch ( Exception e ){
System.out.println("\n>>> EXCEPTION WHILE RUNNING ProxyClient DEMO <<<\n");
e.printStackTrace();
System.exit( 2 );
}
}
}
|
Note: The generated stubs encoded the SOAP payload using base64 encoding before invoking the Web service. There will be a high performance impact if SOAP payloads are sent without encoding.
Execution
Following tasks have to be carried out before executing the client:
- Create the queue manager. Create send & receive queues to be used to send and receive SOAP messages.
- Start the listener program provided in the SupportPac OR start the trigger monitor if the listener program needs to be automatically started when the request comes in. This would also require that a process be defined.
Now the client program can be executed to access the "SimpleTransformation" Web service.
Pros and Cons
| Pros | Cons |
|
|
Alternative 2: Using Axis as a framework instead of WSDL extension
Deployment
To deploy the above service, following tasks have to be carried out on the server
1. The required classes have to put into the CLASSPATH environment variable
2. Compile the Web service source files
3. Start the Simple Axis Server (OR Tomcat can be used)
4. Prepare the WSDD file for deploying the SimpleTransformation service. Please note that there is no WSDD file generated in this case. The WSDD file has to be prepared manually. It can look like this:
Listing 3. WSDD for service provider
<deployment xmlns="http://xml.apache.org/Axis/wsdd/" xmlns:java="http://xml.apache.org/Axis/wsdd/providers/java" name="TransformationService"> <service name="SimpleTransformation" provider="java:RPC"> <parameter value="javaDemos.server.SimpleTransformation" name="className"/> <parameter value="*" name="allowedMethods"/> </service> </deployment> |
5. Deploy the WSDD file for "SimpleTransformation" into the Axis engine [Using java org.apache.Axis.utils.Admin server] java org.apache.Axis.utils.Admin server SimpleTransformation.wsdd
6. Now we need to configure the JMS MQSeries Transport on the client side. The client WSDD file will look like this:
Listing 4. WSDD for service consumer
<deployment xmlns="http://xml.apache.org/Axis/wsdd/" xmlns:java="http://xml.apache.org/Axis/wsdd/providers/java"> <handler name="JMSMQSender" type="java:javaDemos.jms.JMSSOAPSender"/> <transport name="JMSTransport" pivot="JMSMQSender"/> </deployment> |
7. To deploy the client WSDD, execute the following command:
java org.apache.Axis.utils.Admin client jmsclient-deploy.wsdd
The option client indicates that deployment information is for client side only. You are now done with the deployment of your architecture.
Implementing clients
The clients used for invoking the Web services is as shown below. The call to "call.addParameter" is an important one. It encodes the SOAP payload before sending the request.
"base64Binary" represents Base64-encoded arbitrary binary data. For base64Binary data the entire binary stream is encoded using the Base64 Content-Transfer-Encoding defined in Section 6.8 of [RFC 2045].
Not encoding the SOAP payload can have a serious performance impact on the response time.
Listing 5. AXIS Client code snippet
public static void main(String args[]) {
// Method Name to invoke for the Web Service
String methodName = "setupTransformation";
/* Read the files .xml and .xsl and convert them into byte
* arrays to be sent to the Web service
*/
...
...
JMSTransport transport = new JMSTransport(connectorMap, cfMap);
// Create the Service call
Service service = new Service();
Call call = (Call) service.createCall();
QName qname= new QName("SimpleTransformation", methodName);
call.setOperationName(qname);
call.addParameter(new javax.xml.namespace.QName("", "byte1"),
new javax.xml.namespace.QName(
"http://www.w3.org/2001/XMLSchema", "base64Binary"),
byte[].class, javax.xml.rpc.ParameterMode.IN);
call.addParameter(new javax.xml.namespace.QName("", "byte2"),
new javax.xml.namespace.QName(
"http://www.w3.org/2001/XMLSchema", "base64Binary"),
byte[].class, javax.xml.rpc.ParameterMode.IN);
call.setTransport(transport);
call.setReturnType(XMLType.XSD_INT);
result = call.invoke(new Object[] { b1, b2 });
...
...
}
|
Execution
Before the client program can be executed to access the framework, following tasks have to be carried out:
1. Create the MQ objects like the queue manager and queues.
2. Create the JMS administered objects like queue connection factory and queue. For For WebSphere MQ, JMS administered objects are created using JMSAdmin.
Using "JMSAdmin" from the MQSeries installation directory, perform the following:
Listing 6. JMS provisioning
def qcf(MQ_JMS_MANAGER) qmgr(MQJMS.QManager) press Enter def q(JMS_RequestQueue) qmgr(MQJMS.QManager) queue(RequestQueue) press Enter def q(JMS_ResponseQueue) qmgr(MQJMS.QManager) queue(ResponseQueue) press Enter |
We have now bound the queues to JNDI objects.
3. Start the JMS listener program.
Now the client program can be executed to access the "SimpleTransformation" Web service.
Performance was studied only for the response time and not the throughput. The client assumed a single threaded model.
Response times
| Transport alternative | 10 runs in sec (per request in sec) | 100 runs in sec (per request in sec) | 500 runs in sec (per request in sec) | 10000 runs in sec (per request in sec) | 50000 runs in sec (per request in sec) |
| MAOR MQ | 12 (1.2) | 61 (0.61) | 285 (0.57) | 4941 (0.4941) | 24981 (0.499) |
| AXIS JMS | 11 (1.1) | 64 (0.64) | 251 (0.502) | 4810 (0.481) | 26075 (0.5215) |
| Pure HTTP | 7 (0.7) | 49 (0.49) | 274 (0.548) | 3066 (0.306) | 14439 (0.288) |
Figure 4. Response time graph

As expected, the initial JVM startup time and loading up of classes has a high overhead for small number of requests. As the number of requests increase, this cost is amortized. The pure HTTP case showed good scalability indicating that it can be used for high volume traffic as well.
As per the discussion, both approaches have advantages and disadvantages. Standards are still emerging and the ease of deployment is improving. HTTP is a faster and a cheaper solution, but the extra cost and time is the cost of reliability. The recommendation is to use HTTP when reliability is not paramount, for example, reporting messages instead of value bearing transactions. Scalability of HTTP also demonstrated that it can be utilized for high volume applications. There was close to 60-80% overhead to carry SOAP payload on persistent MQ messages when compared with carrying the same on HTTP. WSDL generators simplify the client code and also the deployment. From operations point of view there is not much difference between the two solutions. The Axis adapter framework makes addition of handlers (for example, validation) easier. Design of interfaces is very important and good understanding of argument encoding is important from interoperability point of view.
- "Asynchronous Web Services and the Enterprise Service Bus" by David Chappell talks about a bridge from SOAP over HTTP to SOAP over JMS with internal integration through JCA &JMS, and external integration through HTTP or HTTPS.
- Read Holt Adams' developerWorks series about programming patterns to build asynchronous Web services based on the four different transmission primitives supported by WSDL.
- Asynchronous operations and Web services, Part 1 (developerWorks, April 2002)
- Asynchronous operations and Web services, Part 2 (developerWorks, June 2002)
- Asynchronous operations and Web services, Part 3 (developerWorks, October 2002)
- Programming JMS applications using Axis by Naveen Balani provides details on using AXIS with JMS Transport. (developerWorks, February 2003)
- The SOAP 1.1 Specifications provides the protocol details for SOAP
- The Apache Axis SOAP User Guide provides details on using AXIS
- The IBM WebSphere MQ SupportPac MA0R provides details on using MAOR
- The Apache WSIF are still coming up with JMS Extension for WSDL
Mouli Narayanan is currently a IT Solutions Architect working on building a messaging system for a Wall Street client. After graduating from Pennsylvania State University in 1998 with a Masters degree in Computer Science and Engineering, he joined Torry Harris. Prior to his current project he designed and built dotFlow, an embeddable Java technology workflow engine for J2EE servers. His interests include distributed transaction processing and messaging systems.
Srivathsa is currently a Technical Lead and has been working with Torry Harris Business Solutions for the past 5 years. His area of specialization also includes TP monitors like Transarc Encina and IBM CrossWorlds. He hold an engineering degree in the field of "Electronics and Communication." He has been working on projects involving various enterprise middleware products like IBM WebSphere MQ, WebSphere MQ Integrator, IBM DCE and has also provided enterprise training on WMQ & WMQI. He can be reached at srivathsa_vijay@thbs.com.
Comments (Undergoing maintenance)





