Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6716540

SAXException swallows the error cause

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 6
    • Fix Version/s: None
    • Component/s: xml
    • Labels:

      Description

      FULL PRODUCT VERSION :
      java version "1.6.0_06"
      Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
      Java HotSpot(TM) Server VM (build 10.0-b22, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux luigi-laptop 2.6.24-18-generic #1 SMP Wed May 28 20:27:26 UTC 2008 i686 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      First of all, sorry for having posted this bug report on java.beans package. I didn't found any XML parser section on the previous page.

      SAXParserException loose the cause. (see my blogpost here: http://en.newinstance.it/2008/06/16/bug-saxexception-swallows-the-error-cause/)


      Here is the source:

       1import java.io.StringReader;
       2
       3import javax.xml.parsers.SAXParser;
       4import javax.xml.parsers.SAXParserFactory;
       5
       6import org.xml.sax.Attributes;
       7import org.xml.sax.InputSource;
       8import org.xml.sax.SAXException;
       9import org.xml.sax.helpers.DefaultHandler;
      10
      11
      12public class SAXExceptionTest {
      13
      14 private static class SampleHandler extends DefaultHandler {
      15 @Override
      16 public void startElement(String uri, String localName, String name,
      17 Attributes attributes) throws SAXException {
      18 try {
      19 Object o = null;
      20 o.hashCode();
      21 } catch (Exception ex) {
      22 throw new SAXException("Exception during startElement", ex);
      23 }
      24 }
      25 }
      26
      27 public static void main(String[] args) throws Exception {
      28 SAXParserFactory factory = SAXParserFactory.newInstance();
      29 SAXParser parser = factory.newSAXParser();
      30 String xmlToParse = "<sample-xml>Hello wold!</sample-xml>";
      31 InputSource source = new InputSource(new StringReader(xmlToParse));
      32 parser.parse(source, new SampleHandler());
      33 }
      34}
      35

      The exception you get from this source is:

      Exception in thread "main" java.lang.NullPointerException
      at SAXExceptionTest$SampleHandler.startElement(SAXExceptionTest.java:22)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
      at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startElement(XMLDTDValidator.java:767)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1357)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1297)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3088)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:914)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
      at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
      at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
      at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
      at SAXExceptionTest.main(SAXExceptionTest.java:32)

      So, you see a NullPointerException (that in reality is a SAXException, so this information is wrong!) thrown at line 22, but nothing about the root cause (the real NullPointerException, that in reality is thrown at line 20!).
      Also notice that the message “Exception during startElement” is lost, as well as the message contained in the NullPointerException (that usually just contains the String “null”).
      I think all this is misleading.

      Here is a fixed version of the same example (I subclasses SAXParseException into FixedSAXParseException):

       1import java.io.StringReader;
       2
       3import javax.xml.parsers.SAXParser;
       4import javax.xml.parsers.SAXParserFactory;
       5
       6import org.xml.sax.Attributes;
       7import org.xml.sax.InputSource;
       8import org.xml.sax.SAXException;
       9import org.xml.sax.helpers.DefaultHandler;
      10
      11public class FixedSAXExceptionTest {
      12
      13 public static class FixedSAXException extends SAXException {
      14 private static final long serialVersionUID = 649860250063124096L;
      15 private Throwable cause;
      16 private String message;
      17
      18 public FixedSAXException(String message, Exception cause) {
      19 this.message = message;
      20 this.cause = cause;
      21 }
      22
      23 @Override
      24 public Throwable getCause() {
      25 return cause;
      26 }
      27
      28 @Override
      29 public String getMessage() {
      30 return message + ": " + cause.getMessage();
      31 }
      32 }
      33
      34 private static class SampleHandler extends DefaultHandler {
      35 @Override
      36 public void startElement(String uri, String localName, String name,
      37 Attributes attributes) throws SAXException {
      38 try {
      39 Object o = null;
      40 o.hashCode();
      41 } catch (Exception ex) {
      42 throw new FixedSAXException("Exception during startElement", ex);
      43 }
      44 }
      45 }
      46
      47 public static void main(String[] args) throws Exception {
      48 SAXParserFactory factory = SAXParserFactory.newInstance();
      49 SAXParser parser = factory.newSAXParser();
      50 String xmlToParse = "<sample-xml>Hello wold!</sample-xml>";
      51 InputSource source = new InputSource(new StringReader(xmlToParse));
      52 parser.parse(source, new SampleHandler());
      53 }
      54}

      So you see the stacktrace I get this time:

      Exception in thread "main" FixedSAXExceptionTest$FixedSAXException: Exception during startElement: null
      at FixedSAXExceptionTest$SampleHandler.startElement(FixedSAXExceptionTest.java:42)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
      at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startElement(XMLDTDValidator.java:767)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1357)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1297)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3088)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:914)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
      at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
      at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
      at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
      at FixedSAXExceptionTest.main(FixedSAXExceptionTest.java:52)
      Caused by: java.lang.NullPointerException
      at FixedSAXExceptionTest$SampleHandler.startElement(FixedSAXExceptionTest.java:40)
      ... 15 more

      This time you get a FixedSAXException with message “Exception during startElement: null” at line 42 (where “null” is the message returned by the original exception) and as cause you get the NullPointerException at line 40. As it should be.

      Loosing that information could be painful debugging an application.

      My suggestion is to subclass the SAXParseException with a fixed behavior, like I did in this example.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the included examples.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      This is the trace one would expect when SAXParseException is nested with another exception.

      Exception in thread "main" SAXException: the message of SAXParseException (plus eventually the message of the cause)
      at FixedSAXExceptionTest$SampleHandler.startElement(FixedSAXExceptionTest.java:42)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
      at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startElement(XMLDTDValidator.java:767)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1357)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1297)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3088)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:914)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
      at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
      at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
      at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
      at FixedSAXExceptionTest.main(FixedSAXExceptionTest.java:52)
      Caused by: java.lang.NullPointerException
      at FixedSAXExceptionTest$SampleHandler.startElement(FixedSAXExceptionTest.java:40)
      ... 15 more

      ACTUAL -
      SAXParseException produces this trace:

      Exception in thread "main" java.lang.NullPointerException
      at SAXExceptionTest$SampleHandler.startElement(SAXExceptionTest.java:22)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
      at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startElement(XMLDTDValidator.java:767)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1357)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1297)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3088)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:914)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
      at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
      at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
      at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
      at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
      at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
      at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
      at SAXExceptionTest.main(SAXExceptionTest.java:32)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      included in the description.
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      creating a my-own FixedSAXParseException extending from SAXParseException

        Attachments

          Activity

            People

            • Assignee:
              joehw Joe Wang
              Reporter:
              ndcosta Nelson Dcosta (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Imported:
                Indexed: