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

One XMLStreamException constructor fails to initialize cause

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 23
    • xml
    • None
    • behavioral
    • low
    • Hide
      The only risk is from code out there might be already working around this issue by explicitly invoking `initCause()` after creating the `XMLStreamException()` using the buggy constructor, which will now start throwing `IllegalStateException`.

      The existence of such code is hypothetical, and it's made even more unlikely by the fact that it would be using the wrong workaround: the proper workaround is to use the `XMLStreamException(String, Location)` constructor and then invoke `initCause()`, which works just fine.

      Moreoer, if any code using the wrong workaround does exist, it is doing something that is clearly documented to result in an `IllegalStateException` being thrown. So the risk (to whatever extent it may be real) is only to code that is by definition already buggy.
      Show
      The only risk is from code out there might be already working around this issue by explicitly invoking `initCause()` after creating the `XMLStreamException()` using the buggy constructor, which will now start throwing `IllegalStateException`. The existence of such code is hypothetical, and it's made even more unlikely by the fact that it would be using the wrong workaround: the proper workaround is to use the `XMLStreamException(String, Location)` constructor and then invoke `initCause()`, which works just fine. Moreoer, if any code using the wrong workaround does exist, it is doing something that is clearly documented to result in an `IllegalStateException` being thrown. So the risk (to whatever extent it may be real) is only to code that is by definition already buggy.
    • Java API
    • JDK

      Summary

      Fix a bug where one of the XMLStreamException() constructors taking a Throwable was failing to pass it to the superclass constructor, thereby "dropping" the chained exception.

      Problem

      The class XMLStreamException has three constructors taking a Throwable cause:

      XMLStreamException(Throwable th)
      XMLStreamException(String msg, Throwable th)
      XMLStreamException(String msg, Location location, Throwable th)

      The first two correctly pass the Throwable parameter to the superclass constructor, thereby initializing the chained exception cause, but the third constructor does not.

      Failing to chain exceptions can create difficulties for developers because it obscures the underlying cause for an exception.

      Solution

      Fix the bug by having the constructor invoke the Exception(String, Throwable) superclass constructor instead of Exception(String).

      This solution changes the behavior in two areas:

      • An XMLStreamException created with the modified constructor will now automatically have a cause. This means those causes will appear in stack traces like they should.
      • Invoking initCause() on an XMLStreamException created with the modified constructor will now throw IllegalStateException, whereas before it did not.

      It's possible that there is code out there that is already working around this issue by explicitly invoking initCause() after creating the XMLStreamException using the buggy constructor. Once this fix is applied, such code will start throwing IllegalStateException. This appears to be the only possible downside to this change.

      On the other hand, the IllegalStateException is completely consistent with the documented behavior of exception chaining - you can't invoke initCause() if you've already chained another exception - so in some sense this can only affect code that is already by definition buggy, albeit, buggy for a reasonable cause.

      Specification

      The specification doesn't change; the implementation is corrected to match the specification with this patch:

      --- a/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java
      +++ b/src/java.xml/share/classes/javax/xml/stream/XMLStreamException.java
      @@ -95,7 +95,7 @@ public XMLStreamException(String msg, Throwable th) {
         public XMLStreamException(String msg, Location location, Throwable th) {
           super("ParseError at [row,col]:["+location.getLineNumber()+","+
                 location.getColumnNumber()+"]\n"+
      -          "Message: "+msg);
      +          "Message: "+msg, th);
           nested = th;
           this.location = location;
         }

            acobbs Archie Cobbs
            acobbs Archie Cobbs
            Joe Wang
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: