axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mark Tye (JIRA)" <>
Subject [jira] Commented: (AXIS-2029) SOAPHeader.appendChild() throws unexpected ClassCastException
Date Fri, 03 Jun 2005 00:20:51 GMT
     [ ]
Mark Tye commented on AXIS-2029:

The diff is a step in the right direction: it's certainly better to throw a DOMException with
a meaningful error message than a totally unhelpful ClassCastException. However, it would
probably make more sense to throw a SOAPException, since it's only within the context of SOAP
that Header elements are prohibited from having text nodes as their immediate children. From
a purely DOM perspective, it's perfectly legal to add a text node to the Header element.

However, I'm not sure that throwing an exception is always the right thing to do here. While
the SOAP specs (and the javadoc comments of the javax.xml.soap.SOAPHeader interface) forbid
the addition of Text node children to a SOAP Header element, that doesn't really address the
whitespace issue I mentioned in my original comment.

For example, if you're using the SAAJ API to build the response envelope in a message-style
service invocation (e.g. public void method(SOAPEnvelope req, SOAPEnvelope resp)) and you're
using a parsed DOM tree or SAX events as input, you might be tempted, as I was, to use the
SOAPElement.addTextNode(String) method to handle the character data the parser feeds you.
That works just fine if the SOAPElement you're adding text to is an instance of SOAPHeaderElement,
SOAPBodyElement, or even SOAPBody - and it *used* to work for instances of SOAPHeader under
Axis 1.2 beta - but now it results in a ClassCastException. You get this exception even if
the String you're trying to add contains only whitespace - which is perfectly legal in the
context of a SOAP Header.

I suggest that the SOAPHeader.appendChild(Node) method should check to see if the node being
appended is an instance of Text (or maybe CharacterData?). If it is, and the node contains
only whitespace, no exception should be thrown. (Presumably, the whitespace can be safely

An alternative might be to implement the addTextNode(String) method in SOAPHeader, overriding
the generic implementation in MessageElement, and throw an exception if the parameter string
contains non-whitespace characters. This would push the point of failure closer to source
of the problem, which is generally a good design principle.

If you take the latter approach, you probably want to do the same thing for the Axis SOAPBody
and SOAPEnvelope implementations, too.

(Regarding Venkat's comment about the SOAP 1.2 spec, I should point out that a SOAP header
*block* element information item is not the same thing as the SOAP Header element information
item itself - although that's anything but obvious at first glance. The sentence that Venkat
references in section 5.2.1 allows the *children* of the SOAP Header to have character information,
like so:

    this text is permitted

Whereas section 5.2 specifies that the immediate children of the SOAP Header *must* be elements,
which would seem to disallow text such as this:

  this text is not permitted

The SOAP 1.1 spec says more or less the same thing, but without the fussy nomenclature.)

> SOAPHeader.appendChild() throws unexpected ClassCastException
> -------------------------------------------------------------
>          Key: AXIS-2029
>          URL:
>      Project: Axis
>         Type: Bug
>   Components: Basic Architecture, SAAJ
>     Versions: 1.2
>  Environment: Windows XP Pro/WebSphere 4.0
>     Reporter: Mark Tye
>  Attachments: 2029.diff
> The class org.apache.axis.message.SOAPHeader overrides the appendChild(org.w3c.dom.Node)
method of org.apache.axis.message.NodeImpl in such a way that it breaks the contract of the
org.3c.dom.Node.appendChild(org.w3c.dom.Node) interface.
> Here's the implementation of appendChild(Node) in SOAPHeader:
> 390    public Node appendChild(Node newChild) throws DOMException {
> 391        SOAPHeaderElement headerElement = null;
> 392        if(newChild instanceof SOAPHeaderElement)
> 393            headerElement = (SOAPHeaderElement)newChild;
> 394        else 
> 395            headerElement = new SOAPHeaderElement((Element)newChild);
> 396        try {
> 397            addChildElement(headerElement);
> 398        } catch (SOAPException e) {
> 399            throw new DOMException(DOMException.INVALID_STATE_ERR,e.toString());
> 400        }
> 401        return headerElement;
> 402    }
> This works fine if the newChild Node parameter is an instance of SOAPHeaderElement or
org.w3c.dom.Element, but any other subclass of Node will cause a ClassCastException to be
thrown at line 395.
> It's reasonable to expect that in most cases, the Node being appended to a SOAP Header
will be DOM Element representing a header entry. However, there is no prohibition in the SOAP
1.1 Note or the SOAP 1.2 Recommendation against whitespace before, after, or in between the
header entries of a SOAP Header. Some parsers will render such whitespace as Text nodes, which
will cause a ClassCastException in the appendChild() method.
> Even if a deliberate design decision has been made not to support whitespace in the SOAPHeader
class, the appendChild(Node) method should probably do something more elegant than throw a
ClassCastException if the Node parameter is a Text node containing whitespace.

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators:
For more information on JIRA, see:

View raw message