[ 
http://issues.apache.org/jira/browse/AXIS2-919?page=comments#action_12428991 ] 
            
Eran Chinthaka commented on AXIS2-919:
--------------------------------------

Hi Derek,

First sorry for the late reply on this and thanks for bringing this up by 
suggesting to increase the severity of the bug.

I did write some test cases and for me this seems not to be a bug in the code 
you mentioned, but in the XMLBeans data binding code. Having said that let me 
establish the point. 

If you look at org.apache.axiom.om.impl.llom.OMElementImpl.java:263, the 
getNextOMSibling, it only throws this exception when there is an END_DOCUMENT 
element, whilst its not done. This can happen only if the XML is not  
well-formed. IIRC, we put that check to make sure our code won't breaks for 
user errors. 
You might be able to understand that END_DOCUMENT element can not be thrown, 
until the parser sends END_ELEMENT events for all the START_ELEMENT events. We 
track it using the "done" flag. So until the "done" flag is true for all the 
elements, there can't be END_DOCUMENT events.
I know, that piece of code will never be thrown for valid xmls, but we put it 
purposely, IIRC, to catch the user errors. Users might some times create 
OMElements from various sources, but might forget to call the 
setComplete(true). 

So IIUC, XMLBeans data binding code is not setting this flag properly. I will 
check on that and update you on that. If you still think its a bug in Axiom, 
please be kind enough to provide me with a test code, so that I can fix the 
bug, if any. 

Anyway, I will fix the empty message exception. 

-- Chinthaka

> Unable to print out entire SOAP message: bug 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
>         Assigned To: Eran Chinthaka
>            Priority: Blocker
>
> 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