We are having some issue with XML file generation using JAXB.(The generated file is corrupted/jumbled even if we validate against XSD). But no errors are reported in server logs(catalina.out)

While we were doing the investigations, we happened to found the following code segment in com.sun.xml.internal.bind.v2.runtime.MarshallerImpl(This is the runtime class used by java to marshall the JAXB objects to XML).

 

/**

* All the marshal method invocation eventually comes down to this call.

*/

private void write(Object obj, XmlOutput out, Runnable postInitAction) throws JAXBException {

    try {

        if( obj == null )

            throw new IllegalArgumentException(Messages.NOT_MARSHALLABLE.format());

 

        if( schema!=null ) {

            // send the output to the validator as well

            ValidatorHandler validator = schema.newValidatorHandler();

            validator.setErrorHandler(new FatalAdapter(serializer));

            // work around a bug in JAXP validator in Tiger

            XMLFilterImpl f = new XMLFilterImpl() {

                @Override

                public void startPrefixMapping(String prefix, String uri) throws SAXException {

                    super.startPrefixMapping(prefix.intern(), uri.intern());

                }

            };

            f.setContentHandler(validator);

            out = new ForkXmlOutput( new SAXOutput(f) {

                @Override

                public void startDocument(XMLSerializer serializer, boolean fragment, int[] nsUriIndex2prefixIndex, NamespaceContextImpl nsContext) throws SAXException, IOException, XMLStreamException {

                    super.startDocument(serializer, false, nsUriIndex2prefixIndex, nsContext);

                }

                @Override

                public void endDocument(boolean fragment) throws SAXException, IOException, XMLStreamException {

                    super.endDocument(false);

                }

            }, out );

        }

 

        try {

            prewrite(out,isFragment(),postInitAction);

            serializer.childAsRoot(obj);

            postwrite();

        } catch( SAXException e ) {

            throw new MarshalException(e);

        } catch (IOException e) {

            throw new MarshalException(e);

        } catch (XMLStreamException e) {

            throw new MarshalException(e);

        } finally {

            serializer.close();

        }

    } finally {

        cleanUp();

    }

}

 

private void cleanUp() {

    if(toBeFlushed!=null)

        try {

            toBeFlushed.flush();

        } catch (IOException e) {

            // ignore

        }

    if(toBeClosed!=null)

        try {

            toBeClosed.close();

        } catch (IOException e) {

            // ignore

        }

    toBeFlushed = null;

    toBeClosed = null;

}

 

The method write(Object obj, XmlOutput out, Runnable postInitAction) calls the cleanup method in the finally clause and there is the flushing is happening. But in this cleanup method while flushing if any IOException happens, they ignore the exception.

We are wondering, whether this segments generated the corrupted XML as it does not throw back the exception and simply eats up the exception.

Also we have found the following statement in API documentation of XML serializer.

class: org.apache.xml.serialize.XMLSerializer

If an I/O exception occurs while serializing, the serializer will not throw an exception directly, but only throw it at the end of serializing (either DOM or SAX's DocumentHandler.endDocument().

 

Any help is appreciated.

Regards, Mayuran

FacebookTwitterLinkedin
Pin It
Joomla Tutorials for Beginners