Dragons in the Algorithm
Adventures in Programming
by Michael Chermside

Wrong SAAJ Version - a Spring bug

A few notes on a bug I had so next time I won't make the same mistake.

In spring-ws, in the class org.springframework.ws.soap.saaj.SaajSoapMessage, in the method getImplementation(), it uses SaajUtils.getSaajVersion(SOAPMessage) to determine the SAAJ version of this message. Unfortunately, that has a bug in it (or at LEAST a poor design) which can be quite confusing.

getSaajVersion() calls SOAPMessage.getSOAPPart().getEnvelope(). If the message was badly formed (in my case, it declared an xsi:schemaLocation, but failed to declare xmlns:xsi) then this is where the exception will be thrown. The code in getSaajVersion() then catches any generic SOAPException and swallows it (assuming the message must be SAAJ_11). The "parse was invalid" SOAPException will be ignored.

That wouldn't be so bad if it weren't for the fact that the SOAPMessage is mutated. The getSOAPPart() and getEnvelope() start with "get" so it suggests that they do not mutate the SOAPMessage, but in fact they DO! In the normal flow of processing, this just happens to be the first time that the content of the message gets looked at. During the first time, the InputStream is read, but after that first time it won't be read again. So the NEXT time these are called, they will behave differently (returning null instead of throwing an exception). This confused me for a couple of days, thinking I had 2 different errors (it was returning null, and my SAAJ version was messed up), and producing the truly bewildering behavior (which should have tipped me off) that I could fix things by looking at something in the debugger.

Posted Sun 08 May 2011 by mcherm in Programming