Introduction

Web Services have brought a major shift in the way B2B transactions are conducted globally. The reduced cost and complexity of integrating disparate applications across businesses, combined with a wider horizon for selecting the technology domains make them a de facto choice for developing enterprise-wide business applications. The advantages that Web Services bring with them include a reduced total cost of ownership and increased scope for better customer-supplier management. The fundamental premise of Web Services is that standardization, predicted on promise of interoperability resolves many of the long-standing integration issues facing most of the B2B players today.

While the alternatives for interoperable, service-based components already being available under various tags like CORBA, DCOM, RMI etc., the major impediment to their widespread acceptability remains the inability to "truly & reliably" interoperate in a seamless fashion that forms the very basis of Web Services' advent. This article aims to demonstrate the capability of Web-services based architectures that bring together even the most disparate systems in a cost-effective, manageable and extensible manner.

Interoperability in Web Services

Most of the organizations around the globe today, have their enterprise systems comprising of different applications, built around different technologies and platforms. According to an estimate conducted by ZapThink (an industry research and analysis firm), approximately 70% of IT spending budget in these enterprises revolves around integrating and maintaining these systems. This is a major bottleneck faced by the critical business components of the enterprises, like, Supply Chain Management. The integration solutions, hence, forms a significant business opportunity for IT software and services vendors, advocating to address this lucrative sector.

Interoperability forms the core of any solution that proposes to address the integration issue in enterprise systems. While seamless integration drives the Web Services development, interoperability drives the integration. In simple terms, Interoperability refers to the "capability and suitability of any system to be implemented and accessed in platform-neutral and language-neutral manner". As is the case in any discipline, for any two systems to be able to talk to each other or in technical jargon - "interoperate", standards need to the defined. These standards define the modes in which one system may send/receive requests/responses to/from other systems, even if they belong to different, unrelated technology and platform domains. They define the very basis for compatibility between two disparate systems.

Benefits of Interoperability

The benefits of interoperability can be summarized as follows:

  • Facilitate the creation of a new presentation layer using a new technology and, at the same time, reuse the existing business components.
  • Integrate heterogeneous software components within an enterprise
  • Lower Integration efforts
  • This is contributed to the fact that the standards, which have been already agreed upon, make the interfaces between the systems and the processes compatible to each other.
  • Lower Ownership and Maintenance efforts. The cost and efforts of ownership and maintenance inherently decreases with the use of interoperable components, supplied by third parties.
  • Increased market and technology opportunities
    With the scope of web services and interoperability, the enterprises have a wider choice of vendors, as technologies no longer remain a hindering factor.

A typical Interop Scenario

WSInterop.jpg

Fig 1: A Typical Web Services Interoperability Scenario

As shown in the above diagram, a typical web-services' interoperability scenario consists of web-service(s) being developed on one platform and/or programming language and consumed by client(s), developed using a different programming language on a different platform. The typical example that can be cited to showcase this scenario (and which is also an important area of focus) would be a Java Web Service consumed by a Microsoft .NET client (either C# or VB.NET). The interoperability mechanism goes a long way ahead. Even logic on legacy mainframe systems can be exposed as web services that can be consumed from Microsoft .NET and Java clients. EIS systems such as SAP allow for exposing their business functionality as web services that can also be consumed from any client on any platform.

The diagram depicts a Java Web Service, deployed on Sun ONE Application Server. The web service's generic as well as technical information is published on the IBM UDDI Test Registry. A C#/VB.NET client, seeking to consume the functionality exposed by this web-service, can lookup the UDDI registry and obtain the reference to the web service. Microsoft .NET provides command-line as well as IDE-integrated options that would automatically generate a proxy for the web service, once a reference to the web service's WSDL is obtained. The web service methods can then be invoked through this proxy object, just as if the web service were a local object to the client itself.

Microsoft .NET technology and the Sun ONE platform natively support web services. However, there might be cases where the technology that you are using might not natively support web services. For example, you are using classic ASP programming and you want to consume a Microsoft .NET web service or if you are using a simple Java Swing windows application and you want to use the functionality exposed by some web services hosted by some third party. In such cases, the clients can also use the SOAP toolkits to pass SOAP messages directly to the web service. There are various SOAP toolkits available such as Microsoft SOAP Toolkit and the SOAP toolkits offered by Apache.

This mode does not require the use of any proxy objects. The demo example with this article uses the Microsoft SOAP Toolkit option.

Interoperability between Java and .NET

Let us consider the situation discussed above, in practical details. This example shall demonstrate the interoperability between Java and Microsoft .NET. We will have a Java Web Service that returns Vector objects back to the client and we will consume this web service from a Microsoft .NET client.

Case 1: Java Web Service and Visual Basic.NET client

InteropWS Web Service

We will create a Java web service, InteropWS, which maintains a Vector object, that is a list of all strings supplied to it. For this, the web service has exposed the following methods:

setVectorData - This method accepts a Vector object, which shall contain a list of all strings that need to be appended to be stored in the list maintained by the web service.

getCompleteList - This method returns a Vector object, containing the entire list of strings, that are stored at any given instant.

The following code snippet illustrates these methods of the web service:

/*
* SimpleTest.java
*
*/
package com.patni.coe.ws.interop;
import java.util.*;
public class SimpleTest implements SimpleTestInterface
{
/** Creates a new instance of SimpleTest */
public Vector vList = new Vector();
public SimpleTest()
{
// Loads the vector with initial values vList.add("Value 1");
vList.add("Value 2");
vList.add("Value 3");
vList.add("Value 4");
}
public Vector getCompleteList()
{
return vList;
}
public void setVectorData(Vector newList)
{
for(int i=0;i<newList.size();i++)
{
his.vList.add(newList.
get(i));
}
}
}

Listing 1: Web Service code snippet

InteropWS Client

To access this web service, we will create a Visual Basic .NET client that calls both these methods using the Microsoft SOAP Toolkit 3.0.

Sending list of values

The following code snippet illustrates the method to fetch the complete string list from the Java web service and display that list of values to the user:

Private Sub GetListofValues()
Dim Connector As ISoapConnector
Dim Serializer As SoapSerializer30
Dim Reader As SoapReader30
Connector =
New HttpConnector30
Connector.Property("EndPointURL") = http://localhost/InteropWS/InteropWS
Connector.Connect()
Connector.BeginMessage()
Serializer =
New SoapSerializer30
Serializer.Init(Connector.InputStream)
Serializer.StartEnvelope(, "STANDARD")
Serializer.SoapNamespace("nso", "urn:InteropWS/wsdl")
Serializer.SoapNamespace("xsi", http://www.w3.org/2001/XMLSchema-instance)
Serializer.SoapNamespace("xsd", http://www.w3.org/2001/XMLSchema)
Serializer.StartBody("STANDARD")
Serializer.StartElement("nso:getCompleteList")
Serializer.EndElement()
Serializer.EndBody()
Serializer.EndEnvelope()
Connector.EndMessage()
Reader =
New SoapReader30
Reader.Load(Connector.OutputStream)
Dim list As MSXML2.IXMLDOMNodeList
list = Reader.Body.getElementsByTagName("item")
If list Is Nothing Then
MsgBox("No such element")
Else
MsgBox(list.length)
End If
Dim i As Integer
Dim values As String
values = ""
For i = 0 To list.length - 1
values = values & list.item(i).text & vbCrLf
Next
MsgBox(values)
End Sub

Listing 2: Visual Basic .NET Client code snippet for retrieving list of values

In the code snippet shown above, the Connector object is an ISOAPConnector implementation to send and receive SOAP messages. The Serializer object is a SOAPSerializer30 instance, that is used create a SOAP message. The SOAP message involves a call to the "getArrayList" method of the Java web service, which returns the vector in a serialized, XML format back to the calling object. An XML reader is then used to de-serialize the XML in SOAP response message and obtain the list of the strings, as required.

The following are the soap messages exchanged by the client and web service:

Request

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc=http://schemas.xmlsoap.org/soap/encoding/
xmlns:ns0="urn:InteropWS/wsdl"
xmlns:ns1=http://java.sun.com/jax-rpc-ri/internal
xmlns:ns2="urn:InteropWS/types" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:getCompleteList/>
</env:Body>
</
env:Envelope>
Response
<?xml version="1.0" encoding="UTF-8"?>
<
env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc=http://schemas.xmlsoap.org/soap/encoding/
xmlns:ns0="urn:InteropWS/types"
xmlns:ns1="http://java.sun.com/jax-rpc-ri/internal" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ans1:getCompleteListResponse xmlns:ans1="urn:InteropWS/wsdl">
<result xsi:type="ns1:vector" enc:arrayType="xsd:anyType[6]">
<item xsi:type="xsd:string">Value 1</item>
<item xsi:type="xsd:string">Value 2</item>
<item xsi:type="xsd:string">Value 3</item>
<item xsi:type="xsd:string">Value 4</item>
</result>
</ans1:getCompleteListResponse>
</env:Body>
</
env:Envelope>

Listing 3: SOAP Messages exchanged for getCompleteList method call

Retrieving a list of values

Similarly, the following code snippet creates a SOAP message, with list of strings that is to be appended to the in-memory list of strings maintained by the web service.

Private Sub AddtoListofValues(ByVal vectorData As Collection)
Dim Connector As ISoapConnector
Dim Serializer As SoapSerializer30
Connector =
New HttpConnector30
Connector.Property("EndPointURL") = http://localhost/InteropWS/InteropWS
Connector.Connect()
Connector.BeginMessage()
Serializer =
New SoapSerializer30
Serializer.Init(Connector.InputStream)
Serializer.StartEnvelope(, "STANDARD")
Serializer.SoapNamespace("xsd", http://www.w3.org/2001/XMLSchema)
Serializer.SoapNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance") Serializer.SoapNamespace("enc", "http://schemas.xmlsoap.org/soap/encoding/") Serializer.SoapNamespace("ns0", "urn:InteropWS/wsdl")
Serializer.SoapNamespace("ns1", "http://java.sun.com/jax-rpc-ri/internal") Serializer.SoapNamespace("ns2", "urn:InteropWS/types")
Serializer.StartBody("STANDARD")
Serializer.StartElement("ns0:setVectorData")
Serializer.StartElement("Vector_1")
Serializer.SoapAttribute("xsi:type", "ns1:vector")
Serializer.SoapAttribute("enc:arrayType", , "xsd:anyType[2]")
Dim index As Integer
For index = 1 To vectorData.Count
Serializer.StartElement("item")
Serializer.SoapAttribute("xsi:type", , "xsd:string")
Serializer.WriteString(vectorData.Item(index))
Serializer.EndElement()
Next
Serializer.EndElement()
Serializer.EndElement()
Serializer.EndBody()
Serializer.EndEnvelope()
Connector.EndMessage()
End Sub

Listing 4: Visual Basic.NET Client code snippet for adding to list of values

The above code snippet is similar to the code for GetListofValues. The difference lies that here, the Collection data to be added to the Java vector data, is first serialized into XML data for the SOAP message and then sent to the web service end. The web service on the other end does the converse of this process. The XML is de-serialized back, but this time, into a java Vector object.

The SOAP message sent to add the list of values to the existing list is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc=http://schemas.xmlsoap.org/soap/encoding/
xmlns:ns0="urn:InteropWS/wsdl"
xmlns:ns1=http://java.sun.com/jax-rpc-ri/internal
xmlns:ns2="urn:InteropWS/types"
env
:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:setVectorData>
<Vector_1 xsi:type="ns1:vector" enc:arrayType="xsd:anyType[2]">
<item xsi:type="xsd:string">Value 5</item>
<item xsi:type="xsd:string">Value 6</item>
</Vector_1>
</ns0:setVectorData>
</env:Body>
</
env:Envelope>

Listing 5: SOAP Message sent for setVectorData method call

Case 2: Visual C# Web Service and Java client

We will now consider the same scenario, as demonstrated above now for a Microsoft C# web service and a JAXM-based Java client.

Visual C# Web Service: InteropCS

The Interop CS web service has a method AppendtoList, which accepts an ArrayList of values and appends to its in-memory list, and returns the appended list back to calling client. The code snippet for the same is illustrated as follows:

[WebMethod]
public ArrayList AppendtoList(ArrayList newList)
{
if(list == null)
{
list =
new ArrayList();
}
if(newList == null)
{
return list;
}
IEnumerator enumList = newList.GetEnumerator();
while(enumList.MoveNext())
{
list.Add(enumList.Current.ToString());
}
return list;
}

Listing 6: Microsoft C# web service code snippet

InteropCS Client

To consume the Microsoft C# web service, we will now create a JAXM-based Java client. JAXM is Java API for XML Messages, and uses specialized XML parsing and messaging to send and receive SOAP messages.

The following snippet illustrates the Java client functionality:

package com.patni.coe.ws.interop;
import javax.xml.soap.*;
public class InteropCSClient
{
/** Creates a new instance of InteropCSClient */
public InteropCSClient()
{ }
public SOAPConnectionFactory getConnectionFactoryInstance() throws Exception
{
return SOAPConnectionFactory.newInstance();
}
public MessageFactory getMessageFactoryInstance() throws Exception
{
return MessageFactory.newInstance();
}
public SOAPMessage createSOAPMessage(MessageFactory msgFactory) throws Exception
{
SOAPMessage message = msgFactory.createMessage();
SOAPPart msgPart = message.getSOAPPart();
SOAPEnvelope envelope = msgPart.getEnvelope();
envelope.setEncodingStyle(http://schemas.xmlsoap.org/soap/encoding/);
SOAPElement xsd = envelope.addNamespaceDeclaration("xsd",http://www.w3.org/2001/XMLSchema);
SOAPElement xsi = envelope.addNamespaceDeclaration
("xsi",http://www.w3.org/2001/XMLSchema-instance);
SOAPElement enc = envelope.addNamespaceDeclaration("enc",http://schemas.xmlsoap.org/soap/encoding/);
SOAPBody body = envelope.getBody();
Name name = envelope.createName( "AppendtoList");
SOAPBodyElement bodyElement = body.addBodyElement(name);
bodyElement.addAttribute( envelope.createName("xmlns"),http://tempuri.org/);
Name newList = envelope.createName("newList");
SOAPElement newListElement = bodyElement.addChildElement( newList);
Name value5 = envelope.createName("anyType");
SOAPElement value5Element = newListElement.addChildElement( value5);
value5Element.addTextNode("Value5");
value5Element.addAttribute( envelope.createName("xsi:type"),"xsd:string");
Name value6 = envelope.createName("anyType");
SOAPElement value6Element = newListElement.addChildElement( value5); value6Element.addTextNode("Value6");
value6Element.addAttribute( envelope.createName("xsi:type"),"xsd:string");
Name value7 = envelope.createName("anyType");
SOAPElement value7Element = newListElement.addChildElement( value5); value7Element.addTextNode("Value7");
value7Element.addAttribute( envelope.createName("xsi:type"),"xsd:string");
return message;
}
public String getResponse (SOAPMessage response) throws Exception
{
response.writeTo(
new java.io.FileOutputStream("c:\\recd.txt"));
SOAPPart part = response.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
SOAPBody body = envelope.getBody();
if(body.hasFault())
{
return "Fault found";
}
java.util.Iterator iterator = body.getChildElements();
SOAPBodyElement element = (SOAPBodyElement)iterator.next();
java.util.Iterator it2 = element.getChildElements();
String values = "";
while(it2.hasNext())
{
values += String.valueOf(it2.next());
}
return values;
}
public void sendMessage()
{
try
{
SOAPConnectionFactory conFactory = getConnectionFactoryInstance();
SOAPConnection connection = conFactory.createConnection();
MessageFactory msgFactory = getMessageFactoryInstance();
SOAPMessage message = createSOAPMessage(msgFactory);
java.net.URL endpoint =
new java.net.URL("http://localhost/InteropCS/InteropCS.asmx"); message.getMimeHeaders().addHeader("SOAPAction","http://tempuri.org/AppendtoList"); SOAPMessage response = connection.call(message,endpoint);
java.io.FileOutputStream os =
new java.io.FileOutputStream("C:\\Sent.txt");
message.writeTo(os); os.close();
System.
out.println("Response: " + response);
if(null!=response)
{
System.
out.println("Message Sent successfully.....");
}
System.
out.println("Response status: " + getResponse (response));
}
catch(Exception ex)
{
System.
out.println("Exception in SOAP Messaging: ");
ex.printStackTrace();
}
}
public static void main(String args[])
{
InteropCSClient client =
new InteropCSClient();
client.sendMessage();
}

Listing 7: JAXM-based Java C# web service code snippet

The SOAPMessage, SOAPBody, SOAPElement typically map to the corresponding elements of a SOAP message. A SOAPConnection object is used to establish a connection to the URL where the web service is hosted. The MessageFactory creates a SOAP Message instance, whose attributes and details are then set in the createMessage method. The SOAP messages exchanged in this transaction are illustrated as follows:

Request:

<?xml version="1.0" encoding="UTF-8"?>
<
soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc=http://schemas.xmlsoap.org/soap/encoding/
soap-env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:Header/>
<soap-env:Body>
<AppendtoList xmlns="http://tempuri.org/">
<newList>
<anyType xsi:type="xsd:string">Value5</anyType>
<anyType xsi:type="xsd:string">Value6</anyType>
<anyType xsi:type="xsd:string">Value7</anyType>
</newList>
</AppendtoList>
</soap-env:Body>
</
soap-env:Envelope>

Response:

<?xml version="1.0" encoding="utf-8"?>
<
soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AppendtoListResponse xmlns="http://tempuri.org/">
<AppendtoListResult>
<anyType xsi:type="xsd:string">Value1</anyType>
<anyType xsi:type="xsd:string">Value2</anyType>
<anyType xsi:type="xsd:string">Value3</anyType>
<anyType xsi:type="xsd:string">Value4</anyType>
<anyType xsi:type="xsd:string">Value5</anyType>
<anyType xsi:type="xsd:string">Value6</anyType>
<anyType xsi:type="xsd:string">Value7</anyType>
</AppendtoListResult>
</AppendtoListResponse>
</soap:Body>
</
soap:Envelope>

Listing 8: SOAP Messages exchanged between the Java client and Microsoft C# Web Service

As shown in Listing 8, the SOAP Request is sent to the web service, with 3 new values. These values are added to the existing list of 4 values and this appended list is return back to the user.

Challenges to Interoperability

As is the case with any path-breaking technologies, the web service and the interoperability aspects also presents the providers and consumers with a few bottlenecks. The primary reason for most of these challenges being that Web Services are an emerging technology. They are yet to reach a stage where clients can consume an off-the-shelf type of a service in a "plug-n-play" mode. Some of the challenges faced, include the following:

  • One of the most intriguing challenges in interoperability is the mismatch between the datatypes of "interoperating" platforms. Other languages may not support the datatypes supported by one language. Though there may be equivalent datatypes, it is difficult to find interoperable datatypes. For example, the Arraylist type in Java is equivalent to the ArrayList type in Microsoft.NET. Though one cannot say they are directly interoperable. This is due to the fact the implementation of these types are specific to their parent platforms.
  • Every organization tries to address the interoperability in their own perspective, giving rise to "proprietary" standards, which defeat the very objective of web services and interoperability. These specifications cannot be guaranteed to be compatible with those adopted by other vendor(s) or client(s).
  • Lack of any industry standards and/or specifications
  • With the growing scope and horizon of the web services, new specifications and standards are being constantly added to the existing set, by the vendors, consortia of companies, standard bodies as well as individual companies. These groups may or may not be communicating with each other regarding any of their releases. This contributes to a growing set of incompatible specifications.

The best way to counter the diverse specifications and surmounting barriers to the web services interoperability is through consensus and industry-accepted and guided specifications. This shall be the only way that the enterprise end-users shall be assured of interoperable web service solutions.

Web Services Interoperability and Role of WS-I Organization

It was the challenges, as described above, that forced the technology leaders in Web Service specifications to collaborate and create the Web Services Interoperability Organization (WS-I). The organization was founded in 2002, and is aimed at promoting interoperability across platforms, applications and languages. The charter of the WS-I is to accelerate the adoption of Web Services by assisting in the selection and interpretation of WS specifications and in the development of common best practices for development and deployment and integration of business applications.

The Web Services Interoperability Organization addresses the issue of interoperability through the following deliverables:

  • Profiles, which, basically mean, a collection of specifications, alongwith the clarifications in any inherent ambiguity that they may have.
  • Testing and Implementation guides for efficient and rapid customer deployment
  • Best practices, Usage scenarios, use-cases and sample implementations
  • Self-administered and self-validating test suites

The organizations joining the WS-I can benefit from the following perspectives:

  • Since the WS-I is collaborated on the basis of use-cases derived from industry specifications, it acts as a forum for communicating the business requirements and those for distributed computing interoperability.
  • The organizations having proven credentials in a particular vertical, like Insurance and Hospitality, can help leverage and augment the horizontally focused computing with vertically focused business requirements.
  • Apart from the access to WS-I profiles, the member also gains access to the testing methodologies for web services, the usage & implementation scenarios and use-cases for the same. All these contribute to a reduced cost in development, deployment and integrations of their service-oriented solutions.

Summary

In this article, we have seen what interoperability is all about, a typical scenario of Java - Microsoft .NET interoperability, the benefits of and challenges faced in interoperability and the role of WS-I in this overall scenario.

It all indicates that web services are certainly going to form a huge chunk of the enterprise deployments in near future. The deciding factor in their success and acceptability will be the extent of interoperability provided to the enterprise partners. To achieve this, a cohesive interpretation of ambiguities, incompatibilities and best practices is needed. These are precisely the lines that the WS-I is functioning on.