News -- MS SOAP SDK vs IBM SOAP4J: Comparison & Reviewby James Snell
With the recent submission of the Version 1.1 Specification of the Simple Object Access Protocol (SOAP) to the W3C, the fledgling new XML-messaging/rpc protocol has been getting a lot of attention -- mostly from developers wanting to know how exactly to use it in their enterprise applications. Not wanting to disappoint, the two largest supporters of SOAP, IBM and Microsoft, have both recently released two vastly different (and unfortunately, incompatible) reference implementations of SOAP.
If you're new to SOAP, I'd recommend first taking a look at the specification before playing around with either package so you can have a better understanding of what is going on behind the scenes. If you are already familiar with SOAP, I've done my best to put together a side by side comparison of the two packages as they relate to SOAP Version 1.1 Conformance, ease of use, stability, deployability and compatibility.
- IBM/Apache SOAP Project Version 1.2 (Apache XML Project Release Version)
- Microsoft SOAP Toolkit For Visual Studio 6.0 (Build 204).
SOAP Version 1.1 Conformance
IBM wins overall regarding SOAP Version 1.1 conformance. The areas I looked at include the formatting of the SOAP Envelope, namespace usage, data type support, and fault response structure.
SOAP Envelope & Namespace Usage: The SOAP specification uses XML namespaces to uniquely identify the various elements of the SOAP envelope. The IBM tools appropriately reference the proper SOAP namespaces http://schemas.xmlsoap.org/soap/envelope/ and http://schemas.xmlsoap.org/soap/encoding/, whereas the Microsoft tools append a "2000-03-01" to the end of the namespace references, causing problems with other SOAP implementations. Additionally, in the MS SOAP Envelope, the encodingStyle attribute improperly references the http://schemas.xmlsoap.org/soap/envelope/ namespace instead of the http://schemas.xmlsoap.org/soap/encoding/ namespace. It's an easy fix, but one that lessens the overall quality of the code.
Data Type Support: Both packages seem to do well when it comes to supporting the basic SOAP datatypes, although both don't handle Arrays and Structs very nicely at all. IBM scores a few additional points, however, with its facility to allow developers to specifically create type mappings between the Java datatypes and SOAP standard data types. Additionally, IBM SOAP encodes the datatypes directly into the SOAP envelope whereas the MS SOAP package relies on the External SDL file to provide type specific information. While legal according to the SOAP v1.1 specification, I'd have to argue that, for completeness, datatype information should be passed along with the request.
IBM's output: <nsl:getQuote> <symbol xsd:type='xsi:string'>IBM</symbol> </nsl:getQuote> Versus Microsoft's output: <getQuote> <symbol>IBM</symbol> </getQuote>
Specific to the Microsoft implementation, when using the ASP-based SOAP listener, developers are forced to rely a great deal on the VARIANT datatype for ByRef (IN/OUT) parameters, causing the SOAP envelope to lose valuable type specific information.
Fault Response Structure: The MS SOAP package fails miserably here. Whereas the documentation details fault responses that correlate with the version 1.1 specification, the ASP listener appears to use a limited combination of SOAP version 1.0 and version 1.1 fault codes. This turns into a big problem for Non-MS SOAP client applications trying to parse detailed error information from the SOAP server.
MS loses twice here, once for improper support, and once for invalid documentation. IBM, on the other hand, properly supports the full Version 1.1 fault code specification.
To illustrate the problems with the Microsoft ASP Listener, open your web browser and navigate directly to Listener.asp. The response you'll get looks like the following:
<?xml version="1.0" ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>300</faultcode> <faultstring>Nothing was posted</faultstring> <faultactor>300</faultactor> <detail>Nothing was posted</detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Notice the faultcode which uses a SOAP Version 1.0 value; and the faultactor which, according to the SOAP v1.1 spec, if used at all, should be set equal to the URI of the listener where the error occured.
Another caveat with the Microsoft SOAP SDK: The component responsible for parsing the SOAP response envelope, the SOAPPackager, contains a bug that does not allow the fault information to be properly parsed. If you want to use this information, you will have to extract it yourself.
Ease Of Use
Microsoft wins for overall ease of use. The areas I looked at include ease of installation, implementation code complexity, and debugging.
Installation: First of all, I'd have to say that in this arena, I've always been pretty biased against Java. I personally can't stand the CLASSPATH architecture for locating Java packages, and much prefer GUI based tools for installing applications. That being said, the "installation" procedures for both packages can up equal. Once I had all of the classpath information appropriately added to my Apache Jakarta Tomcat webserver, I was off and running. The IBM web-based SOAP webservice deployment tool is nice, if not stylish. The server also comes with a java command line tool for deploying new services which also happens to use SOAP. Pretty cool.
On the Microsoft side of things, the installation was a tad easier:
Register the Rope.dll (the component containing all of the SOAP implementation code).
Create a SOAP virtual directory.
Run the SDL wizard to generate the server code and off you go.
The client side of the installation tells the same story. For IBM, make sure the SOAP classes are in your classpath and you're good to go. For Microsoft, register the Rope.dll and you're all set. One drawback though: The Microsoft Rope.dll was built with Windows 2000/NT4 SP6 in mind, so if you want to distribute it to Windows 98 machines, you may have to make some changes. Luckily, the source code is included.
Implementation Code: Microsoft definitely wins here with its Proxy component. Whereas the IBM "SOAP For Java" package requires hand coding of the SOAP envelope package, the Microsoft Proxy component whittles down the process so that all of the SOAP envelope construction is occuring behind the scenes -- effectively reducing the amount of code a developer has to write for most processes down to 3 lines of code:
Dim Proxy As New Proxy Proxy.LoadServiceDescription .... Proxy.SomeMethod Param1, Param2, ...
The downside of the proxy component is that it currently does not support Payload headers, so if you need to include any custom SOAP headers in your request, you will be hand coding the Envelope using the SOAPPackager component which can be, at times, a slightly less than intuitive process (read: be sure to read the docs first).
Debugging: Unfortunately, I was able to get quite a bit of experience debugging the Microsoft SOAP SDK as I was going through it. The upshot is that it is a fairly straightforward process. Anybody who is familiar with debugging ASP and COM applications should have no problem locating and solving various issues with the code. The biggest challenge I found, however, was in how the ASP listener handles errors that occur within the COM objects it is exposing as services. Take the following code for example:
Public Function SomeMethod() As String Err.Raise 1000, "Test Error" End Function
When the above method is called, the Proxy component errors with a "Bad SOAP Return" message that doesn't tell you anything about the real error that occurred. In fact, when investigating further, the error is never properly handled and packaged as a SOAP fault on the server side.
The only debugging I've ever had to do with the IBM implementation is making sure that I was using the right version of the Apache Xerces-J XML parser. There are other issues, of course, though I just haven't hit my head against them.
IBM wins, hands down. Here, I looked at bugs in the package and how those errors were handled.
Bugs: The MS SOAP package appears to be very unstable. Not only are there bugs in the XML encoding (try setting the method namespace using the SOAPPackager component), but there are many unhandled exceptions that cause pretty nasty results. The lesson: be sure to save your work in progress before you test your code in the VB IDE. Below is a list of just a few of the bugs that I've found:
Improper encodingStyle attribute.
Improper Namespace usage.
LoadServiceDescription/ValidateDataAsType/IsMethodAvailable methods return BOOL instead of VARIANT_BOOL.
Fault Codes not parsed properly in the SOAPPackager.setPayload method.
Multiple host ports not supported (http://localhost:8080) wouldn't work. The WireTransfer object would still use the default Port 80.
The WireTransfer.Port property doesn't do anything and is undocumented.
WireTransfer.getPageByURI method does not compile HTTP headers.
Invalid XML is generated by the SOAPPackager.getPayload method if a MethodNamespace is set using the SOAPPackager.SetPayloadData method (the namespace prefix is missing).
XML passed to the SOAPPackager.setPayload method must contain <?xml version='1.0'?> or an unhandled exception will occur.
As I mentioned earlier, the IBM package is wonderfully stable -- and I would wager to say that it's nearly production ready.
IBM wins. I examined the interoperability of each package with other SOAP v1.1 implementations.
As a quick experiment, try using an MS SOAP Client application to hit an IBM SOAP For Java server. I'll tell you now that it won't work unless you manually code the SOAP envelope XML and pass it through using nothing but the WireTransfer object included in the Rope.dll. The problem lies with the improper and inconsistent SOAP version 1.1 conformance, and the bugs, within the Microsoft SOAPPackager component. Because the SOAP Packaging is incorrect, it takes a lot of massaging to get the Microsoft toolkit to work with other, more compliant SOAP v1.1 implementations. The reverse is also true -- IBM SOAP For Java clients do not work "out of the box" with an MS implemented SOAP server.
IBM's SOAP For Java, on the other hand, works beautifully with clients and servers designed tightly around the SOAP v1.1 specification.
When all is said and done, the Microsoft toolkit currently works very well with SOAP implementations designed specifically around its envelope encoding quirks and errors. However, this doesn't make the Microsoft toolkit very useful for developers wanting to integrate with existing SOAP implementations on other platforms.
I do, however, remain optimistic that the situation will get better. Microsoft has put a lot of time and energy into SOAP and has committed a good deal of resources to the task. The MS SOAP toolkit will be improved over time. On the IBM side of things, the recent news that the Apache Software Foundation has taken over the SOAP For Java project means there is no doubt that the package will only get better with time.