--- old/jaxp/src/javax/xml/xpath/XPathException.java 2013-05-27 01:29:06.025500812 +0400 +++ new/jaxp/src/javax/xml/xpath/XPathException.java 2013-05-27 01:29:05.961500813 +0400 @@ -26,6 +26,10 @@ package javax.xml.xpath; import java.io.PrintWriter; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; /** * XPathException represents a generic XPath exception.

@@ -35,9 +39,11 @@ * @since 1.5 */ public class XPathException extends Exception { - - private final Throwable cause; - + + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField( "cause", Throwable.class ) + }; + /** *

Stream Unique Identifier.

*/ @@ -62,9 +68,8 @@ if ( message == null ) { throw new NullPointerException ( "message can't be null"); } - this.cause = null; } - + /** *

Constructs a new XPathException * with the specified cause.

@@ -77,8 +82,7 @@ * @throws NullPointerException if cause is null. */ public XPathException(Throwable cause) { - super(); - this.cause = cause; + super(cause); if ( cause == null ) { throw new NullPointerException ( "cause can't be null"); } @@ -90,8 +94,42 @@ * @return Cause of this XPathException. */ public Throwable getCause() { - return cause; + return super.getCause(); + } + + /** + * Writes "cause" field to the stream. + * The cause is got from the parent class. + * + * @param out stream used for serialization. + * @throws IOException thrown by ObjectOutputStream + * + */ + private void writeObject(ObjectOutputStream out) + throws IOException + { + ObjectOutputStream.PutField fields = out.putFields(); + fields.put("cause", (Throwable) super.getCause()); + out.writeFields(); } + + /** + * Reads the "cause" field from the stream. + * And initializes the "cause" if it wasn't + * done before. + * + * @param in stream used for deserialization + * @throws IOException thrown by ObjectInputStream + * @throws ClassNotFoundException thrown by ObjectInputStream + */ + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + ObjectInputStream.GetField fields = in.readFields(); + Throwable scause = (Throwable) fields.get("cause", null); + if (super.getCause() == null && scause != null) + super.initCause(scause); + } /** *

Print stack trace to specified PrintStream.

--- /dev/null 2013-05-27 00:30:36.211070918 +0400 +++ new/jdk/test/com/sun/org/apache/xpath/XPathExceptionInitCause.java 2013-05-27 01:29:06.273500811 +0400 @@ -0,0 +1,78 @@ +/* + * @test + * @bug 8009579 + * @summary The initCause() incorrectly initialise the cause in + * XPathException class when used with XPathException(String) + * constructor. + * @run main XPathExceptionInitCause + * @author aleksej.efimov@oracle.com + */ + +import javax.xml.xpath.XPathException; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; +import java.io.IOException; + +public class XPathExceptionInitCause { + + //Serialize XPathException + static byte [] pickleXPE(XPathException xpe) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream xpeos = new ObjectOutputStream(bos); + xpeos.writeObject(xpe); + xpeos.close(); + return bos.toByteArray(); + } + + //Deserialize XPathException + static XPathException unpickleXPE(byte [] ser) + throws IOException, ClassNotFoundException { + XPathException xpe; + ByteArrayInputStream bis = new ByteArrayInputStream(ser); + ObjectInputStream xpeis = new ObjectInputStream(bis); + xpe = (XPathException) xpeis.readObject(); + xpeis.close(); + return xpe; + } + + public static void main(String[] args) throws Exception { + Throwable cause = new Throwable("message 1"); + XPathException xpathexcep = new XPathException("message 2"); + + //Test XPE initCause() method + xpathexcep.initCause(cause); + System.out.println("getCause() result: '" + xpathexcep.getCause() + + "' Cause itself: '" + cause + "'"); + if (!xpathexcep.getCause().toString().equals(cause.toString())) { + throw new Exception("Incorrect cause is set by initCause()"); + } + + //Test serialization/deserialization of initialized XPE + byte [] xpeserial; + XPathException xpedeser; + xpeserial = pickleXPE(xpathexcep); + xpedeser = unpickleXPE(xpeserial); + System.out.println("Serialized XPE: message='" + xpathexcep.getMessage() + + "' cause='" + xpathexcep.getCause().toString() + "'"); + System.out.println("Deserialized XPE: message='" + xpedeser.getMessage() + + "' cause='" + xpedeser.getCause().toString()+"'"); + if(xpedeser.getCause() == null || + !xpedeser.getCause().toString().equals(cause.toString()) || + !xpedeser.getMessage().toString().equals("message 2") ) + throw new Exception("XPathException incorrectly serialized/deserialized"); + + //Test serialization/deserialization of uninitialized cause in XPE + XPathException xpeuninit = new XPathException("uninitialized cause"); + xpeserial = pickleXPE(xpeuninit); + xpedeser = unpickleXPE(xpeserial); + System.out.println("Serialized XPE: message='" + xpeuninit.getMessage() + + "' cause='" + xpeuninit.getCause()+"'"); + System.out.println("Deserialized XPE: message='" + xpedeser.getMessage() + + "' cause='" + xpedeser.getCause()+"'"); + if(xpedeser.getCause() != null || + !xpedeser.getMessage().toString().equals("uninitialized cause") ) + throw new Exception("XPathException incorrectly serialized/deserialized"); + } +}