[ 
http://issues.apache.org/jira/browse/AXIS2-919?page=comments#action_12422805 ] 
            
Derek Foster commented on AXIS2-919:
------------------------------------

The title of this one should be "bug in OMElement.serialize()", not "but in..." 
 Looks like my finger slipped.

> Unable to print out entire SOAP message: but in OMElement.serialize()
> ---------------------------------------------------------------------
>
>                 Key: AXIS2-919
>                 URL: http://issues.apache.org/jira/browse/AXIS2-919
>             Project: Apache Axis 2.0 (Axis2)
>          Issue Type: Bug
>          Components: core, om
>    Affects Versions: 1.0
>            Reporter: Derek Foster
>
> I was attempting, inside an XMLBeans-generated service method, to print out 
> the entire SOAP message to a log file. Towards that end, I tried to execute 
> the following code:
> final StringWriter writer = new StringWriter();
> messageContext.getEnvelope().serialize(writer);
> System.out.println(writer.toString());
> However, I was surprised to get the following exception resulting from this:
> org.apache.axiom.om.OMException
>       at 
> org.apache.axiom.om.impl.llom.OMElementImpl.getNextOMSibling(OMElementImpl.java:266)
>       at 
> org.apache.axiom.om.impl.traverse.OMChildrenIterator.next(OMChildrenIterator.java:111)
>       at 
> org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:771)
>       at 
> org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:177)
>       at 
> org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:756)
>       at 
> org.apache.axiom.om.impl.llom.OMNodeImpl.serialize(OMNodeImpl.java:310)
>       at 
> org.apache.axiom.om.impl.llom.OMNodeImpl.serialize(OMNodeImpl.java:352)
>        ...
> The cause of the problem appears to be the fact that the SOAP envelope is a 
> top-level XML object. Thus, the item immediately following it is a 
> DOCUMENT_END. The OMElementImpl.internalSerialize(XMLStreamWriter, boolean 
> cache) method contains the following code:
>             Iterator children = this.getChildren();
>             while (children.hasNext()) {
>                 ((OMNodeEx) children.next()).internalSerialize(writer);
> which seems plausible. However, the iterator that is returned is of type 
> OMChildrenIterator. Its hasNext method looks like this:
>     /**
>      * Returns <tt>true</tt> if the iteration has more elements. (In other
>      * words, returns <tt>true</tt> if <tt>next</tt> would return an element
>      * rather than throwing an exception.)
>      *
>      * @return Returns <tt>true</tt> if the iterator has more elements.
>      */
>     public boolean hasNext() {
>         return (currentChild != null);
>     }
> but its next() method looks like this:
>     /**
>      * Returns the next element in the iteration.
>      *
>      * @return Returns the next element in the iteration.
>      * @throws java.util.NoSuchElementException
>      *          iteration has no more elements.
>      */
>     public Object next() {
>         nextCalled = true;
>         removeCalled = false;
>         if (hasNext()) {
>             lastChild = currentChild;
>             currentChild = currentChild.getNextOMSibling();
>             return lastChild;
>         }
>         return null;
>     }
> which is a problem, because currentChild.getNextOMSibling() looks like this:
>     /**
>      * Gets the next sibling. This can be an OMAttribute or OMText or
>      * OMELement for others.
>      *
>      * @throws OMException
>      */
>     public OMNode getNextOMSibling() throws OMException {
>         while (!done) {
>             int token = builder.next();
>             if (token == XMLStreamConstants.END_DOCUMENT) {
>                 throw new OMException();
>             }
>         }
>         return super.getNextOMSibling();
>     }
> which will under some circumstances throw an OMException, which is not in the 
> contract of the iterator's next() method to throw.
> Thus, iterator.hasNext() is returning true, implying that there is a next 
> element, but when next() is actually called, the iterator discovers that it 
> has reached the end of the document, and that therefore there really is no 
> next element. It therefore throws an OMException.
> Firstly, if the next() method is going to be implemented this way, then 
> hasNext() should perform enough lookahead on the document to detect that the 
> next item in the input stream is indeed a END_DOCUMENT, and should therefore 
> return false, since under these circumstances there truly isn't a next 
> element (and calling next() would therefore always throw an OMException). 
> That way, when the end of the document is hit, the serialize method will 
> simply stop and return its results rather than trying to advance past the end 
> of the document as it does now.
> Secondly, this OMException really should have some meaningful error text in 
> it, such as "Can't call 'next()' on an iterator which is positioned at 
> element 'foo' which is the last element in the document" or even better, 
> "Can't call next() when hasNext() returns false" (see below). I can't think 
> of any cases in typical library code where it is desirable to throw 
> exceptions that don't have any message text. This is really unpleasant for 
> anybody that is trying to debug a problem. I would encourage someone to do a 
> search through the source code for "throw new OMException()" and add an 
> explanatory error message wherever one is found.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to