--- old/src/java.base/share/classes/java/security/PrivilegedActionException.java 2018-09-13 13:47:54.000000000 -0700 +++ new/src/java.base/share/classes/java/security/PrivilegedActionException.java 2018-09-13 13:47:53.000000000 -0700 @@ -25,6 +25,13 @@ package java.security; +import jdk.internal.misc.SharedSecrets; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; + /** * This exception is thrown by * {@code doPrivileged(PrivilegedExceptionAction)} and @@ -53,19 +60,13 @@ private static final long serialVersionUID = 4724086851538908602L; /** - * @serial - */ - private Exception exception; - - /** * Constructs a new PrivilegedActionException "wrapping" * the specific Exception. * * @param exception The exception thrown */ public PrivilegedActionException(Exception exception) { - super((Throwable)null); // Disallow initCause - this.exception = exception; + super(null, exception); // Disallow initCause } /** @@ -84,23 +85,49 @@ * AccessControlContext) */ public Exception getException() { - return exception; + return (Exception)super.getCause(); } + public String toString() { + String s = getClass().getName(); + Throwable cause = super.getCause(); + return (cause != null) ? (s + ": " + cause.toString()) : s; + } + + /** - * Returns the cause of this exception (the exception thrown by - * the privileged computation that resulted in this - * {@code PrivilegedActionException}). + * Serializable fields for UndeclaredThrowableException. + * + * @serialField undeclaredThrowable Throwable + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("exception", Exception.class) + }; + + /* + * Reconstitutes the PrivilegedActionException instance from a stream + * and initialize the cause properly when deserializing from an older + * version. * - * @return the cause of this exception. - * @since 1.4 + * The getException and getCause method returns the private "exception" + * field in the older implementation and PrivilegedActionException::cause + * was set to null. */ - public Throwable getCause() { - return exception; + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField fields = s.readFields(); + Exception exception = (Exception) fields.get("exception", null); + if (exception != null) { + SharedSecrets.getJavaLangAccess().setCause(this, exception); + } } - public String toString() { - String s = getClass().getName(); - return (exception != null) ? (s + ": " + exception.toString()) : s; + /* + * To maintain compatibility with older implementation, write a serial + * "exception" field with the cause as the value. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + ObjectOutputStream.PutField fields = out.putFields(); + fields.put("exception", super.getCause()); + out.writeFields(); } }