Archive for Spring

The Sorry State of SAAJ

When I started working on Spring Web Services some three years ago, I needed a way to represent a SOAP message. I was a good boy and used J2EE, or more specifically: the SOAP with Attachments API for Java™, also know as SAAJ, also known as the package javax.xml.soap. Founding Spring-WS on a specification seemed like the Proper Thing To Do, and gave me a warm fuzzy feeling inside.

Over time, I found out that SAAJ is quite possibly the worst implemented piece of J2EE Java EE out there. Now I’m sharing the pain with you in this post because, well, sharing is the first step in acceptance.

A Bit Of History

SAAJ started out as being part of the Java™ API for XML Messaging (JAXM). JAXM actually was quite nice: none of this “look ma, it’s just a method call!” nonsense that JAX-RPC offered. Unfortunately, JAXM was pulled in favor of JAX-RPC. Some of JAXM survived, namely the representation of a SOAP message, and was rebranded SAAJ 1.1.

SAAJ 1.1 basically offered a DOM-like representation of a SOAP message: SOAPEnvelope has a SOAPBody, and an optional SOAPHeader, and so on. All elements extended SOAPElement, which in turn extended Node. javax.xml.soap.Node, that is, not org.w3c.dom.Node, which - coincidentally - was the main problem with SAAJ 1.1: there was no easy way to integrate SAAJ with existing JAXP code. Even though SAAJ was similar to org.w3c.dom, there was no clear conversion path, besides writing the whole message to a buffer and reading that with JAXP. Yay.

The wise folks at the JCP decided to change that in SAAJ 1.2: in this version, all SAAJ classes extend their W3C DOM counterparts. So javax.xml.soap.Node extends org.w3c.dom.Node, SOAPElement extends Element, and so on, and so forth. Not everybody thought this was a clever idea; clearly Hani was not among those in favor. At this point, SAAJ was added to J2EE 1.4. Some J2EE vendors seem to agree with Hani as to whether this was a good idea, more about that later.

SAAJ 1.3 introduced some more stuff: support for SOAP 1.2, MTOM, and more. As a result of this plethora of features, SAAJ graduated from Java EE to Java SE in version 6. I think this was probably more a side-effect of SUN putting JAX-WS in Java 6, which is subject to a different rant altogether (short rant preview: had I implemented JAX-WS, I would be pretty pissed at SUN. Aren’t there laws against this sort of bundling?)

The SAAJ Saga continues

So, as of SAAJ 1.2, a SOAPElement isa W3C DOM Element. This makes sense, because now you can use JAXP to put XML content into the some message. For instance, you can use standard XML-DSIG or XML-ENC libraries to sign or decrypt a SOAP message, handy when doing WS-Security. Or, you can read a bit of XML from a file, and dump that into the SOAP body as a payload. The only caveat mentioned in the javax.xml.soap javadoc is that:

an application that starts to use SAAJ APIs on a tree after manipulating it using DOM APIs must assume that the tree has been translated into an all SAAJ tree and that any references to objects within the tree that were obtained using DOM APIs are no longer valid.

No problem, we can do that. Just don’t keep any references dangling around. So we might write something like:

MessageFactory messageFactory = MessageFactory.newInstance();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
SOAPMessage message = messageFactory.createMessage();
Document document = createDocument();
SOAPBody body = message.getSOAPBody();
transformer.transform(new DOMSource(document), new DOMResult(body));
body = message.getSOAPBody();
transformer.transform(new DOMSource(body), new StreamResult(System.out));
message.writeTo(System.out);

Here, we create a new SAAJ message using the MessageFactory. Next, we create a W3C DOM document, and we use a javax.xml.transform.Transformer to transform the document to the SOAP body. As a result the root element of the document should be appended to the SOAP body, it will become the payload of the message. Next, we write the body to the console, and finally we write the whole message to the console. Simple enough, and conforming to the spec.

Yet, this simple program does not work on the majority of Java EE servers.

The Acid Test

I created a simple Servlet which basically does the above, and ran it in a wide variety of Java EE application servers. Here is an overview, all J2EE 1.4 or higher (with the exception of Tomcat, of course, I used that as a baseline and to test the Axis 1 SAAJ implementation). I’ve listed the name, the MessageFactory implementation provided by the server, the test result, and the exception given - if any. Finally, I’ve submitted bugs where possible, because I am a Good Citizen.

Application Server MessageFactory Result Exception Bug
Geronimo 2.1.2 with Jetty org.apache.geronimo.webservices.saaj.GeronimoMessageFactory
Geronimo 2.0.2 with Tomcat org.apache.geronimo.webservices.saaj.GeronimoMessageFactory TransformerException when transforming Document to SOAPBody GERONIMO-4029
AXIS2-3808
GlassFish v2ur1 com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
JBoss 4.2.2 org.jboss.ws.core.soap.MessageFactoryImpl IndexOutOfBoundsException when transforming SOAPBody to stream JBAS-5531
OC4J 10.1.3.1 oracle.j2ee.ws.saaj.soap.MessageFactoryImpl TransformerException when transforming Document to SOAPBody
Tomcat 6.0.16 with SAAJ RI com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
Tomcat 6.0.16 with Axis 1.4 SAAJ org.apache.axis.soap.MessageFactoryImpl
WebLogic 9.2 weblogic.webservice.core.soap.MessageFactoryImpl UnsupportedOperationException when getting SOAPBody
WebLogic 10.0 weblogic.webservice.core.soap.MessageFactoryImpl UnsupportedOperationException when getting SOAPBody
WebSphere 6.1 com.ibm.ws.webservices.engine.soap.MessageFactoryImpl

Of this bunch, WebLogic is the clear winner. Every time you call SOAPMessage.getBody(), WebLogic barfs up a UnsupportedOperationException, saying that “This class does not support SAAJ 1.1″! The thing is: it supports SAAJ 1.1 just fine, it just doesn’t do SAAJ 1.2. You know, J2EE 1.4 and all that.

You Can Help!

Obviously, I am missing WebSphere in this overview. Because I run OS X, I can’t install WebSphere. So if you want to be a Good Citizen too, you can run my little test program on WebSphere, or any other app server I have missed. Update: craig has given me the info for WebSphere, and I’ve updated the table accordingly. Thanks! I’m still interested in any other J2EE 1.4+ app servers I’ve missed, though.

Or if you don’t trust me, you can test it yourself. Just deploy the WAR, and let me know in a comment below.

saaj-test.war

If you don’t trust me at all, you can get the sources. It has a build.xml and all:

saaj-test.zip

Let’s hope that this post solves the issues with SAAJ, because I Want To Believe.

Comments (8)

Conforming to Zawinski’s Law

Over at the SpringSource Team Blog, I’ve just written a post about the new features in Spring Web Services 1.5. One of the new features is the email transport, thereby conforming to Zawinski’s Law of Software Envelopment:

Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.

I’m happy to announce that Spring-WS 1.5 is ready to replace some other programs!

Comments off

Conferences, conferences, conferences

I just came back from JavaZone. Good fun, just like last year. I did two talks: one together with Jürgen Höller about managing large code bases, and one by myself about WS-DuckTyping.

I’ve you missed me in Oslo, not to worry! I have a few more talks coming up:

  • On the 18th of September 2007 (yes, that’s tomorrow), I will be talking with Alef about Spring 2.5 and OSGi at the Cap Gemini Java Night.
  • On the 9th of October 2007, I will be talking about Spring Web Services at the BeJUG SOA Event.
  • From the 15th till the 18th of October 2007 I will be speaking at Expo-C. This is a small conference in the south of Sweden, which apparently brings good quality audience and speakers (which makes me wonder why they asked me ;) ). I will be talking about WS-DuckTyping, and Effective Framework Design, which is going to be a “lessons learned when we built Spring”-sorta session.
  • From the 13th till the 15th of November 2007, I will be speaking at Øredev about the architecture of large open source frameworks. Also, I will be giving an AOP course while I’m there.
  • Last but not least, from December 12th till 15th 2007, I will be talking at The Spring Experience. I had a great time there last year, and if this year’s version is only half as good, it will be worth it. I will do three sessions on Spring Web Services (WS-DuckTyping, REST, and a basic introduction).

All in all quite a busy schedule. Hope to see you at one of these sessions!

Comments (3)

Spring Web Services Gets a Face

One of the few remaining things to be done before we could release Spring-WS 1.0 is to get a logo. And here it is:

I think Nikki Konicki, our designer, has done an excellent job. It clearly has a reference to both Spring and Web services, while it also shows the document-driven approach that Spring-WS takes.

Comments (3)

Speaking at SpringOne 2007

After last years success, we decided to do it again:

SpringOne 2007
from June 20th till 22nd
Antwerp
Belgium

I will giving two talks: WS-DuckTyping with Spring Web Services, which is a following up to my blog post where give some practical tips to make your web services less strict, and more liberal. The other talk is titled Pragmatic SOA, where I try to find some substance in the hype that surrounds SOA, including the WS-* space, REST, etc.

So register now!

Comments (3)

« Previous entries ·