emul/src/main/java/java/lang/Throwable.java
branchemul
changeset 49 0a115f1c6f3c
child 51 506ef276a0db
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/emul/src/main/java/java/lang/Throwable.java	Fri Sep 28 17:59:03 2012 +0200
     1.3 @@ -0,0 +1,1080 @@
     1.4 +/*
     1.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package java.lang;
    1.30 +import  java.io.*;
    1.31 +import  java.util.*;
    1.32 +
    1.33 +/**
    1.34 + * The {@code Throwable} class is the superclass of all errors and
    1.35 + * exceptions in the Java language. Only objects that are instances of this
    1.36 + * class (or one of its subclasses) are thrown by the Java Virtual Machine or
    1.37 + * can be thrown by the Java {@code throw} statement. Similarly, only
    1.38 + * this class or one of its subclasses can be the argument type in a
    1.39 + * {@code catch} clause.
    1.40 + *
    1.41 + * For the purposes of compile-time checking of exceptions, {@code
    1.42 + * Throwable} and any subclass of {@code Throwable} that is not also a
    1.43 + * subclass of either {@link RuntimeException} or {@link Error} are
    1.44 + * regarded as checked exceptions.
    1.45 + *
    1.46 + * <p>Instances of two subclasses, {@link java.lang.Error} and
    1.47 + * {@link java.lang.Exception}, are conventionally used to indicate
    1.48 + * that exceptional situations have occurred. Typically, these instances
    1.49 + * are freshly created in the context of the exceptional situation so
    1.50 + * as to include relevant information (such as stack trace data).
    1.51 + *
    1.52 + * <p>A throwable contains a snapshot of the execution stack of its
    1.53 + * thread at the time it was created. It can also contain a message
    1.54 + * string that gives more information about the error. Over time, a
    1.55 + * throwable can {@linkplain Throwable#addSuppressed suppress} other
    1.56 + * throwables from being propagated.  Finally, the throwable can also
    1.57 + * contain a <i>cause</i>: another throwable that caused this
    1.58 + * throwable to be constructed.  The recording of this causal information
    1.59 + * is referred to as the <i>chained exception</i> facility, as the
    1.60 + * cause can, itself, have a cause, and so on, leading to a "chain" of
    1.61 + * exceptions, each caused by another.
    1.62 + *
    1.63 + * <p>One reason that a throwable may have a cause is that the class that
    1.64 + * throws it is built atop a lower layered abstraction, and an operation on
    1.65 + * the upper layer fails due to a failure in the lower layer.  It would be bad
    1.66 + * design to let the throwable thrown by the lower layer propagate outward, as
    1.67 + * it is generally unrelated to the abstraction provided by the upper layer.
    1.68 + * Further, doing so would tie the API of the upper layer to the details of
    1.69 + * its implementation, assuming the lower layer's exception was a checked
    1.70 + * exception.  Throwing a "wrapped exception" (i.e., an exception containing a
    1.71 + * cause) allows the upper layer to communicate the details of the failure to
    1.72 + * its caller without incurring either of these shortcomings.  It preserves
    1.73 + * the flexibility to change the implementation of the upper layer without
    1.74 + * changing its API (in particular, the set of exceptions thrown by its
    1.75 + * methods).
    1.76 + *
    1.77 + * <p>A second reason that a throwable may have a cause is that the method
    1.78 + * that throws it must conform to a general-purpose interface that does not
    1.79 + * permit the method to throw the cause directly.  For example, suppose
    1.80 + * a persistent collection conforms to the {@link java.util.Collection
    1.81 + * Collection} interface, and that its persistence is implemented atop
    1.82 + * {@code java.io}.  Suppose the internals of the {@code add} method
    1.83 + * can throw an {@link java.io.IOException IOException}.  The implementation
    1.84 + * can communicate the details of the {@code IOException} to its caller
    1.85 + * while conforming to the {@code Collection} interface by wrapping the
    1.86 + * {@code IOException} in an appropriate unchecked exception.  (The
    1.87 + * specification for the persistent collection should indicate that it is
    1.88 + * capable of throwing such exceptions.)
    1.89 + *
    1.90 + * <p>A cause can be associated with a throwable in two ways: via a
    1.91 + * constructor that takes the cause as an argument, or via the
    1.92 + * {@link #initCause(Throwable)} method.  New throwable classes that
    1.93 + * wish to allow causes to be associated with them should provide constructors
    1.94 + * that take a cause and delegate (perhaps indirectly) to one of the
    1.95 + * {@code Throwable} constructors that takes a cause.
    1.96 + *
    1.97 + * Because the {@code initCause} method is public, it allows a cause to be
    1.98 + * associated with any throwable, even a "legacy throwable" whose
    1.99 + * implementation predates the addition of the exception chaining mechanism to
   1.100 + * {@code Throwable}.
   1.101 + *
   1.102 + * <p>By convention, class {@code Throwable} and its subclasses have two
   1.103 + * constructors, one that takes no arguments and one that takes a
   1.104 + * {@code String} argument that can be used to produce a detail message.
   1.105 + * Further, those subclasses that might likely have a cause associated with
   1.106 + * them should have two more constructors, one that takes a
   1.107 + * {@code Throwable} (the cause), and one that takes a
   1.108 + * {@code String} (the detail message) and a {@code Throwable} (the
   1.109 + * cause).
   1.110 + *
   1.111 + * @author  unascribed
   1.112 + * @author  Josh Bloch (Added exception chaining and programmatic access to
   1.113 + *          stack trace in 1.4.)
   1.114 + * @jls 11.2 Compile-Time Checking of Exceptions
   1.115 + * @since JDK1.0
   1.116 + */
   1.117 +public class Throwable implements Serializable {
   1.118 +    /** use serialVersionUID from JDK 1.0.2 for interoperability */
   1.119 +    private static final long serialVersionUID = -3042686055658047285L;
   1.120 +
   1.121 +    /**
   1.122 +     * Native code saves some indication of the stack backtrace in this slot.
   1.123 +     */
   1.124 +    private transient Object backtrace;
   1.125 +
   1.126 +    /**
   1.127 +     * Specific details about the Throwable.  For example, for
   1.128 +     * {@code FileNotFoundException}, this contains the name of
   1.129 +     * the file that could not be found.
   1.130 +     *
   1.131 +     * @serial
   1.132 +     */
   1.133 +    private String detailMessage;
   1.134 +
   1.135 +
   1.136 +    /**
   1.137 +     * Holder class to defer initializing sentinel objects only used
   1.138 +     * for serialization.
   1.139 +     */
   1.140 +    private static class SentinelHolder {
   1.141 +        /**
   1.142 +         * {@linkplain #setStackTrace(StackTraceElement[]) Setting the
   1.143 +         * stack trace} to a one-element array containing this sentinel
   1.144 +         * value indicates future attempts to set the stack trace will be
   1.145 +         * ignored.  The sentinal is equal to the result of calling:<br>
   1.146 +         * {@code new StackTraceElement("", "", null, Integer.MIN_VALUE)}
   1.147 +         */
   1.148 +        public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
   1.149 +            new StackTraceElement("", "", null, Integer.MIN_VALUE);
   1.150 +
   1.151 +        /**
   1.152 +         * Sentinel value used in the serial form to indicate an immutable
   1.153 +         * stack trace.
   1.154 +         */
   1.155 +        public static final StackTraceElement[] STACK_TRACE_SENTINEL =
   1.156 +            new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
   1.157 +    }
   1.158 +
   1.159 +    /**
   1.160 +     * A shared value for an empty stack.
   1.161 +     */
   1.162 +    private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
   1.163 +
   1.164 +    /*
   1.165 +     * To allow Throwable objects to be made immutable and safely
   1.166 +     * reused by the JVM, such as OutOfMemoryErrors, fields of
   1.167 +     * Throwable that are writable in response to user actions, cause,
   1.168 +     * stackTrace, and suppressedExceptions obey the following
   1.169 +     * protocol:
   1.170 +     *
   1.171 +     * 1) The fields are initialized to a non-null sentinel value
   1.172 +     * which indicates the value has logically not been set.
   1.173 +     *
   1.174 +     * 2) Writing a null to the field indicates further writes
   1.175 +     * are forbidden
   1.176 +     *
   1.177 +     * 3) The sentinel value may be replaced with another non-null
   1.178 +     * value.
   1.179 +     *
   1.180 +     * For example, implementations of the HotSpot JVM have
   1.181 +     * preallocated OutOfMemoryError objects to provide for better
   1.182 +     * diagnosability of that situation.  These objects are created
   1.183 +     * without calling the constructor for that class and the fields
   1.184 +     * in question are initialized to null.  To support this
   1.185 +     * capability, any new fields added to Throwable that require
   1.186 +     * being initialized to a non-null value require a coordinated JVM
   1.187 +     * change.
   1.188 +     */
   1.189 +
   1.190 +    /**
   1.191 +     * The throwable that caused this throwable to get thrown, or null if this
   1.192 +     * throwable was not caused by another throwable, or if the causative
   1.193 +     * throwable is unknown.  If this field is equal to this throwable itself,
   1.194 +     * it indicates that the cause of this throwable has not yet been
   1.195 +     * initialized.
   1.196 +     *
   1.197 +     * @serial
   1.198 +     * @since 1.4
   1.199 +     */
   1.200 +    private Throwable cause = this;
   1.201 +
   1.202 +    /**
   1.203 +     * The stack trace, as returned by {@link #getStackTrace()}.
   1.204 +     *
   1.205 +     * The field is initialized to a zero-length array.  A {@code
   1.206 +     * null} value of this field indicates subsequent calls to {@link
   1.207 +     * #setStackTrace(StackTraceElement[])} and {@link
   1.208 +     * #fillInStackTrace()} will be be no-ops.
   1.209 +     *
   1.210 +     * @serial
   1.211 +     * @since 1.4
   1.212 +     */
   1.213 +    private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
   1.214 +
   1.215 +    // Setting this static field introduces an acceptable
   1.216 +    // initialization dependency on a few java.util classes.
   1.217 +    private static final List<Throwable> SUPPRESSED_SENTINEL =
   1.218 +        Collections.unmodifiableList(new ArrayList<Throwable>(0));
   1.219 +
   1.220 +    /**
   1.221 +     * The list of suppressed exceptions, as returned by {@link
   1.222 +     * #getSuppressed()}.  The list is initialized to a zero-element
   1.223 +     * unmodifiable sentinel list.  When a serialized Throwable is
   1.224 +     * read in, if the {@code suppressedExceptions} field points to a
   1.225 +     * zero-element list, the field is reset to the sentinel value.
   1.226 +     *
   1.227 +     * @serial
   1.228 +     * @since 1.7
   1.229 +     */
   1.230 +    private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
   1.231 +
   1.232 +    /** Message for trying to suppress a null exception. */
   1.233 +    private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
   1.234 +
   1.235 +    /** Message for trying to suppress oneself. */
   1.236 +    private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";
   1.237 +
   1.238 +    /** Caption  for labeling causative exception stack traces */
   1.239 +    private static final String CAUSE_CAPTION = "Caused by: ";
   1.240 +
   1.241 +    /** Caption for labeling suppressed exception stack traces */
   1.242 +    private static final String SUPPRESSED_CAPTION = "Suppressed: ";
   1.243 +
   1.244 +    /**
   1.245 +     * Constructs a new throwable with {@code null} as its detail message.
   1.246 +     * The cause is not initialized, and may subsequently be initialized by a
   1.247 +     * call to {@link #initCause}.
   1.248 +     *
   1.249 +     * <p>The {@link #fillInStackTrace()} method is called to initialize
   1.250 +     * the stack trace data in the newly created throwable.
   1.251 +     */
   1.252 +    public Throwable() {
   1.253 +        fillInStackTrace();
   1.254 +    }
   1.255 +
   1.256 +    /**
   1.257 +     * Constructs a new throwable with the specified detail message.  The
   1.258 +     * cause is not initialized, and may subsequently be initialized by
   1.259 +     * a call to {@link #initCause}.
   1.260 +     *
   1.261 +     * <p>The {@link #fillInStackTrace()} method is called to initialize
   1.262 +     * the stack trace data in the newly created throwable.
   1.263 +     *
   1.264 +     * @param   message   the detail message. The detail message is saved for
   1.265 +     *          later retrieval by the {@link #getMessage()} method.
   1.266 +     */
   1.267 +    public Throwable(String message) {
   1.268 +        fillInStackTrace();
   1.269 +        detailMessage = message;
   1.270 +    }
   1.271 +
   1.272 +    /**
   1.273 +     * Constructs a new throwable with the specified detail message and
   1.274 +     * cause.  <p>Note that the detail message associated with
   1.275 +     * {@code cause} is <i>not</i> automatically incorporated in
   1.276 +     * this throwable's detail message.
   1.277 +     *
   1.278 +     * <p>The {@link #fillInStackTrace()} method is called to initialize
   1.279 +     * the stack trace data in the newly created throwable.
   1.280 +     *
   1.281 +     * @param  message the detail message (which is saved for later retrieval
   1.282 +     *         by the {@link #getMessage()} method).
   1.283 +     * @param  cause the cause (which is saved for later retrieval by the
   1.284 +     *         {@link #getCause()} method).  (A {@code null} value is
   1.285 +     *         permitted, and indicates that the cause is nonexistent or
   1.286 +     *         unknown.)
   1.287 +     * @since  1.4
   1.288 +     */
   1.289 +    public Throwable(String message, Throwable cause) {
   1.290 +        fillInStackTrace();
   1.291 +        detailMessage = message;
   1.292 +        this.cause = cause;
   1.293 +    }
   1.294 +
   1.295 +    /**
   1.296 +     * Constructs a new throwable with the specified cause and a detail
   1.297 +     * message of {@code (cause==null ? null : cause.toString())} (which
   1.298 +     * typically contains the class and detail message of {@code cause}).
   1.299 +     * This constructor is useful for throwables that are little more than
   1.300 +     * wrappers for other throwables (for example, {@link
   1.301 +     * java.security.PrivilegedActionException}).
   1.302 +     *
   1.303 +     * <p>The {@link #fillInStackTrace()} method is called to initialize
   1.304 +     * the stack trace data in the newly created throwable.
   1.305 +     *
   1.306 +     * @param  cause the cause (which is saved for later retrieval by the
   1.307 +     *         {@link #getCause()} method).  (A {@code null} value is
   1.308 +     *         permitted, and indicates that the cause is nonexistent or
   1.309 +     *         unknown.)
   1.310 +     * @since  1.4
   1.311 +     */
   1.312 +    public Throwable(Throwable cause) {
   1.313 +        fillInStackTrace();
   1.314 +        detailMessage = (cause==null ? null : cause.toString());
   1.315 +        this.cause = cause;
   1.316 +    }
   1.317 +
   1.318 +    /**
   1.319 +     * Constructs a new throwable with the specified detail message,
   1.320 +     * cause, {@linkplain #addSuppressed suppression} enabled or
   1.321 +     * disabled, and writable stack trace enabled or disabled.  If
   1.322 +     * suppression is disabled, {@link #getSuppressed} for this object
   1.323 +     * will return a zero-length array and calls to {@link
   1.324 +     * #addSuppressed} that would otherwise append an exception to the
   1.325 +     * suppressed list will have no effect.  If the writable stack
   1.326 +     * trace is false, this constructor will not call {@link
   1.327 +     * #fillInStackTrace()}, a {@code null} will be written to the
   1.328 +     * {@code stackTrace} field, and subsequent calls to {@code
   1.329 +     * fillInStackTrace} and {@link
   1.330 +     * #setStackTrace(StackTraceElement[])} will not set the stack
   1.331 +     * trace.  If the writable stack trace is false, {@link
   1.332 +     * #getStackTrace} will return a zero length array.
   1.333 +     *
   1.334 +     * <p>Note that the other constructors of {@code Throwable} treat
   1.335 +     * suppression as being enabled and the stack trace as being
   1.336 +     * writable.  Subclasses of {@code Throwable} should document any
   1.337 +     * conditions under which suppression is disabled and document
   1.338 +     * conditions under which the stack trace is not writable.
   1.339 +     * Disabling of suppression should only occur in exceptional
   1.340 +     * circumstances where special requirements exist, such as a
   1.341 +     * virtual machine reusing exception objects under low-memory
   1.342 +     * situations.  Circumstances where a given exception object is
   1.343 +     * repeatedly caught and rethrown, such as to implement control
   1.344 +     * flow between two sub-systems, is another situation where
   1.345 +     * immutable throwable objects would be appropriate.
   1.346 +     *
   1.347 +     * @param  message the detail message.
   1.348 +     * @param cause the cause.  (A {@code null} value is permitted,
   1.349 +     * and indicates that the cause is nonexistent or unknown.)
   1.350 +     * @param enableSuppression whether or not suppression is enabled or disabled
   1.351 +     * @param writableStackTrace whether or not the stack trace should be
   1.352 +     *                           writable
   1.353 +     *
   1.354 +     * @see OutOfMemoryError
   1.355 +     * @see NullPointerException
   1.356 +     * @see ArithmeticException
   1.357 +     * @since 1.7
   1.358 +     */
   1.359 +    protected Throwable(String message, Throwable cause,
   1.360 +                        boolean enableSuppression,
   1.361 +                        boolean writableStackTrace) {
   1.362 +        if (writableStackTrace) {
   1.363 +            fillInStackTrace();
   1.364 +        } else {
   1.365 +            stackTrace = null;
   1.366 +        }
   1.367 +        detailMessage = message;
   1.368 +        this.cause = cause;
   1.369 +        if (!enableSuppression)
   1.370 +            suppressedExceptions = null;
   1.371 +    }
   1.372 +
   1.373 +    /**
   1.374 +     * Returns the detail message string of this throwable.
   1.375 +     *
   1.376 +     * @return  the detail message string of this {@code Throwable} instance
   1.377 +     *          (which may be {@code null}).
   1.378 +     */
   1.379 +    public String getMessage() {
   1.380 +        return detailMessage;
   1.381 +    }
   1.382 +
   1.383 +    /**
   1.384 +     * Creates a localized description of this throwable.
   1.385 +     * Subclasses may override this method in order to produce a
   1.386 +     * locale-specific message.  For subclasses that do not override this
   1.387 +     * method, the default implementation returns the same result as
   1.388 +     * {@code getMessage()}.
   1.389 +     *
   1.390 +     * @return  The localized description of this throwable.
   1.391 +     * @since   JDK1.1
   1.392 +     */
   1.393 +    public String getLocalizedMessage() {
   1.394 +        return getMessage();
   1.395 +    }
   1.396 +
   1.397 +    /**
   1.398 +     * Returns the cause of this throwable or {@code null} if the
   1.399 +     * cause is nonexistent or unknown.  (The cause is the throwable that
   1.400 +     * caused this throwable to get thrown.)
   1.401 +     *
   1.402 +     * <p>This implementation returns the cause that was supplied via one of
   1.403 +     * the constructors requiring a {@code Throwable}, or that was set after
   1.404 +     * creation with the {@link #initCause(Throwable)} method.  While it is
   1.405 +     * typically unnecessary to override this method, a subclass can override
   1.406 +     * it to return a cause set by some other means.  This is appropriate for
   1.407 +     * a "legacy chained throwable" that predates the addition of chained
   1.408 +     * exceptions to {@code Throwable}.  Note that it is <i>not</i>
   1.409 +     * necessary to override any of the {@code PrintStackTrace} methods,
   1.410 +     * all of which invoke the {@code getCause} method to determine the
   1.411 +     * cause of a throwable.
   1.412 +     *
   1.413 +     * @return  the cause of this throwable or {@code null} if the
   1.414 +     *          cause is nonexistent or unknown.
   1.415 +     * @since 1.4
   1.416 +     */
   1.417 +    public synchronized Throwable getCause() {
   1.418 +        return (cause==this ? null : cause);
   1.419 +    }
   1.420 +
   1.421 +    /**
   1.422 +     * Initializes the <i>cause</i> of this throwable to the specified value.
   1.423 +     * (The cause is the throwable that caused this throwable to get thrown.)
   1.424 +     *
   1.425 +     * <p>This method can be called at most once.  It is generally called from
   1.426 +     * within the constructor, or immediately after creating the
   1.427 +     * throwable.  If this throwable was created
   1.428 +     * with {@link #Throwable(Throwable)} or
   1.429 +     * {@link #Throwable(String,Throwable)}, this method cannot be called
   1.430 +     * even once.
   1.431 +     *
   1.432 +     * <p>An example of using this method on a legacy throwable type
   1.433 +     * without other support for setting the cause is:
   1.434 +     *
   1.435 +     * <pre>
   1.436 +     * try {
   1.437 +     *     lowLevelOp();
   1.438 +     * } catch (LowLevelException le) {
   1.439 +     *     throw (HighLevelException)
   1.440 +     *           new HighLevelException().initCause(le); // Legacy constructor
   1.441 +     * }
   1.442 +     * </pre>
   1.443 +     *
   1.444 +     * @param  cause the cause (which is saved for later retrieval by the
   1.445 +     *         {@link #getCause()} method).  (A {@code null} value is
   1.446 +     *         permitted, and indicates that the cause is nonexistent or
   1.447 +     *         unknown.)
   1.448 +     * @return  a reference to this {@code Throwable} instance.
   1.449 +     * @throws IllegalArgumentException if {@code cause} is this
   1.450 +     *         throwable.  (A throwable cannot be its own cause.)
   1.451 +     * @throws IllegalStateException if this throwable was
   1.452 +     *         created with {@link #Throwable(Throwable)} or
   1.453 +     *         {@link #Throwable(String,Throwable)}, or this method has already
   1.454 +     *         been called on this throwable.
   1.455 +     * @since  1.4
   1.456 +     */
   1.457 +    public synchronized Throwable initCause(Throwable cause) {
   1.458 +        if (this.cause != this)
   1.459 +            throw new IllegalStateException("Can't overwrite cause");
   1.460 +        if (cause == this)
   1.461 +            throw new IllegalArgumentException("Self-causation not permitted");
   1.462 +        this.cause = cause;
   1.463 +        return this;
   1.464 +    }
   1.465 +
   1.466 +    /**
   1.467 +     * Returns a short description of this throwable.
   1.468 +     * The result is the concatenation of:
   1.469 +     * <ul>
   1.470 +     * <li> the {@linkplain Class#getName() name} of the class of this object
   1.471 +     * <li> ": " (a colon and a space)
   1.472 +     * <li> the result of invoking this object's {@link #getLocalizedMessage}
   1.473 +     *      method
   1.474 +     * </ul>
   1.475 +     * If {@code getLocalizedMessage} returns {@code null}, then just
   1.476 +     * the class name is returned.
   1.477 +     *
   1.478 +     * @return a string representation of this throwable.
   1.479 +     */
   1.480 +    public String toString() {
   1.481 +        String s = getClass().getName();
   1.482 +        String message = getLocalizedMessage();
   1.483 +        return (message != null) ? (s + ": " + message) : s;
   1.484 +    }
   1.485 +
   1.486 +    /**
   1.487 +     * Prints this throwable and its backtrace to the
   1.488 +     * standard error stream. This method prints a stack trace for this
   1.489 +     * {@code Throwable} object on the error output stream that is
   1.490 +     * the value of the field {@code System.err}. The first line of
   1.491 +     * output contains the result of the {@link #toString()} method for
   1.492 +     * this object.  Remaining lines represent data previously recorded by
   1.493 +     * the method {@link #fillInStackTrace()}. The format of this
   1.494 +     * information depends on the implementation, but the following
   1.495 +     * example may be regarded as typical:
   1.496 +     * <blockquote><pre>
   1.497 +     * java.lang.NullPointerException
   1.498 +     *         at MyClass.mash(MyClass.java:9)
   1.499 +     *         at MyClass.crunch(MyClass.java:6)
   1.500 +     *         at MyClass.main(MyClass.java:3)
   1.501 +     * </pre></blockquote>
   1.502 +     * This example was produced by running the program:
   1.503 +     * <pre>
   1.504 +     * class MyClass {
   1.505 +     *     public static void main(String[] args) {
   1.506 +     *         crunch(null);
   1.507 +     *     }
   1.508 +     *     static void crunch(int[] a) {
   1.509 +     *         mash(a);
   1.510 +     *     }
   1.511 +     *     static void mash(int[] b) {
   1.512 +     *         System.out.println(b[0]);
   1.513 +     *     }
   1.514 +     * }
   1.515 +     * </pre>
   1.516 +     * The backtrace for a throwable with an initialized, non-null cause
   1.517 +     * should generally include the backtrace for the cause.  The format
   1.518 +     * of this information depends on the implementation, but the following
   1.519 +     * example may be regarded as typical:
   1.520 +     * <pre>
   1.521 +     * HighLevelException: MidLevelException: LowLevelException
   1.522 +     *         at Junk.a(Junk.java:13)
   1.523 +     *         at Junk.main(Junk.java:4)
   1.524 +     * Caused by: MidLevelException: LowLevelException
   1.525 +     *         at Junk.c(Junk.java:23)
   1.526 +     *         at Junk.b(Junk.java:17)
   1.527 +     *         at Junk.a(Junk.java:11)
   1.528 +     *         ... 1 more
   1.529 +     * Caused by: LowLevelException
   1.530 +     *         at Junk.e(Junk.java:30)
   1.531 +     *         at Junk.d(Junk.java:27)
   1.532 +     *         at Junk.c(Junk.java:21)
   1.533 +     *         ... 3 more
   1.534 +     * </pre>
   1.535 +     * Note the presence of lines containing the characters {@code "..."}.
   1.536 +     * These lines indicate that the remainder of the stack trace for this
   1.537 +     * exception matches the indicated number of frames from the bottom of the
   1.538 +     * stack trace of the exception that was caused by this exception (the
   1.539 +     * "enclosing" exception).  This shorthand can greatly reduce the length
   1.540 +     * of the output in the common case where a wrapped exception is thrown
   1.541 +     * from same method as the "causative exception" is caught.  The above
   1.542 +     * example was produced by running the program:
   1.543 +     * <pre>
   1.544 +     * public class Junk {
   1.545 +     *     public static void main(String args[]) {
   1.546 +     *         try {
   1.547 +     *             a();
   1.548 +     *         } catch(HighLevelException e) {
   1.549 +     *             e.printStackTrace();
   1.550 +     *         }
   1.551 +     *     }
   1.552 +     *     static void a() throws HighLevelException {
   1.553 +     *         try {
   1.554 +     *             b();
   1.555 +     *         } catch(MidLevelException e) {
   1.556 +     *             throw new HighLevelException(e);
   1.557 +     *         }
   1.558 +     *     }
   1.559 +     *     static void b() throws MidLevelException {
   1.560 +     *         c();
   1.561 +     *     }
   1.562 +     *     static void c() throws MidLevelException {
   1.563 +     *         try {
   1.564 +     *             d();
   1.565 +     *         } catch(LowLevelException e) {
   1.566 +     *             throw new MidLevelException(e);
   1.567 +     *         }
   1.568 +     *     }
   1.569 +     *     static void d() throws LowLevelException {
   1.570 +     *        e();
   1.571 +     *     }
   1.572 +     *     static void e() throws LowLevelException {
   1.573 +     *         throw new LowLevelException();
   1.574 +     *     }
   1.575 +     * }
   1.576 +     *
   1.577 +     * class HighLevelException extends Exception {
   1.578 +     *     HighLevelException(Throwable cause) { super(cause); }
   1.579 +     * }
   1.580 +     *
   1.581 +     * class MidLevelException extends Exception {
   1.582 +     *     MidLevelException(Throwable cause)  { super(cause); }
   1.583 +     * }
   1.584 +     *
   1.585 +     * class LowLevelException extends Exception {
   1.586 +     * }
   1.587 +     * </pre>
   1.588 +     * As of release 7, the platform supports the notion of
   1.589 +     * <i>suppressed exceptions</i> (in conjunction with the {@code
   1.590 +     * try}-with-resources statement). Any exceptions that were
   1.591 +     * suppressed in order to deliver an exception are printed out
   1.592 +     * beneath the stack trace.  The format of this information
   1.593 +     * depends on the implementation, but the following example may be
   1.594 +     * regarded as typical:
   1.595 +     *
   1.596 +     * <pre>
   1.597 +     * Exception in thread "main" java.lang.Exception: Something happened
   1.598 +     *  at Foo.bar(Foo.java:10)
   1.599 +     *  at Foo.main(Foo.java:5)
   1.600 +     *  Suppressed: Resource$CloseFailException: Resource ID = 0
   1.601 +     *          at Resource.close(Resource.java:26)
   1.602 +     *          at Foo.bar(Foo.java:9)
   1.603 +     *          ... 1 more
   1.604 +     * </pre>
   1.605 +     * Note that the "... n more" notation is used on suppressed exceptions
   1.606 +     * just at it is used on causes. Unlike causes, suppressed exceptions are
   1.607 +     * indented beyond their "containing exceptions."
   1.608 +     *
   1.609 +     * <p>An exception can have both a cause and one or more suppressed
   1.610 +     * exceptions:
   1.611 +     * <pre>
   1.612 +     * Exception in thread "main" java.lang.Exception: Main block
   1.613 +     *  at Foo3.main(Foo3.java:7)
   1.614 +     *  Suppressed: Resource$CloseFailException: Resource ID = 2
   1.615 +     *          at Resource.close(Resource.java:26)
   1.616 +     *          at Foo3.main(Foo3.java:5)
   1.617 +     *  Suppressed: Resource$CloseFailException: Resource ID = 1
   1.618 +     *          at Resource.close(Resource.java:26)
   1.619 +     *          at Foo3.main(Foo3.java:5)
   1.620 +     * Caused by: java.lang.Exception: I did it
   1.621 +     *  at Foo3.main(Foo3.java:8)
   1.622 +     * </pre>
   1.623 +     * Likewise, a suppressed exception can have a cause:
   1.624 +     * <pre>
   1.625 +     * Exception in thread "main" java.lang.Exception: Main block
   1.626 +     *  at Foo4.main(Foo4.java:6)
   1.627 +     *  Suppressed: Resource2$CloseFailException: Resource ID = 1
   1.628 +     *          at Resource2.close(Resource2.java:20)
   1.629 +     *          at Foo4.main(Foo4.java:5)
   1.630 +     *  Caused by: java.lang.Exception: Rats, you caught me
   1.631 +     *          at Resource2$CloseFailException.<init>(Resource2.java:45)
   1.632 +     *          ... 2 more
   1.633 +     * </pre>
   1.634 +     */
   1.635 +    public void printStackTrace() {
   1.636 +        printStackTrace(System.err);
   1.637 +    }
   1.638 +
   1.639 +    /**
   1.640 +     * Prints this throwable and its backtrace to the specified print stream.
   1.641 +     *
   1.642 +     * @param s {@code PrintStream} to use for output
   1.643 +     */
   1.644 +    public void printStackTrace(PrintStream s) {
   1.645 +        printStackTrace(new WrappedPrintStream(s));
   1.646 +    }
   1.647 +
   1.648 +    private void printStackTrace(PrintStreamOrWriter s) {
   1.649 +        // Guard against malicious overrides of Throwable.equals by
   1.650 +        // using a Set with identity equality semantics.
   1.651 +        Set<Throwable> dejaVu =
   1.652 +            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
   1.653 +        dejaVu.add(this);
   1.654 +
   1.655 +        synchronized (s.lock()) {
   1.656 +            // Print our stack trace
   1.657 +            s.println(this);
   1.658 +            StackTraceElement[] trace = getOurStackTrace();
   1.659 +            for (StackTraceElement traceElement : trace)
   1.660 +                s.println("\tat " + traceElement);
   1.661 +
   1.662 +            // Print suppressed exceptions, if any
   1.663 +            for (Throwable se : getSuppressed())
   1.664 +                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
   1.665 +
   1.666 +            // Print cause, if any
   1.667 +            Throwable ourCause = getCause();
   1.668 +            if (ourCause != null)
   1.669 +                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
   1.670 +        }
   1.671 +    }
   1.672 +
   1.673 +    /**
   1.674 +     * Print our stack trace as an enclosed exception for the specified
   1.675 +     * stack trace.
   1.676 +     */
   1.677 +    private void printEnclosedStackTrace(PrintStreamOrWriter s,
   1.678 +                                         StackTraceElement[] enclosingTrace,
   1.679 +                                         String caption,
   1.680 +                                         String prefix,
   1.681 +                                         Set<Throwable> dejaVu) {
   1.682 +        assert Thread.holdsLock(s.lock());
   1.683 +        if (dejaVu.contains(this)) {
   1.684 +            s.println("\t[CIRCULAR REFERENCE:" + this + "]");
   1.685 +        } else {
   1.686 +            dejaVu.add(this);
   1.687 +            // Compute number of frames in common between this and enclosing trace
   1.688 +            StackTraceElement[] trace = getOurStackTrace();
   1.689 +            int m = trace.length - 1;
   1.690 +            int n = enclosingTrace.length - 1;
   1.691 +            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
   1.692 +                m--; n--;
   1.693 +            }
   1.694 +            int framesInCommon = trace.length - 1 - m;
   1.695 +
   1.696 +            // Print our stack trace
   1.697 +            s.println(prefix + caption + this);
   1.698 +            for (int i = 0; i <= m; i++)
   1.699 +                s.println(prefix + "\tat " + trace[i]);
   1.700 +            if (framesInCommon != 0)
   1.701 +                s.println(prefix + "\t... " + framesInCommon + " more");
   1.702 +
   1.703 +            // Print suppressed exceptions, if any
   1.704 +            for (Throwable se : getSuppressed())
   1.705 +                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
   1.706 +                                           prefix +"\t", dejaVu);
   1.707 +
   1.708 +            // Print cause, if any
   1.709 +            Throwable ourCause = getCause();
   1.710 +            if (ourCause != null)
   1.711 +                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
   1.712 +        }
   1.713 +    }
   1.714 +
   1.715 +    /**
   1.716 +     * Prints this throwable and its backtrace to the specified
   1.717 +     * print writer.
   1.718 +     *
   1.719 +     * @param s {@code PrintWriter} to use for output
   1.720 +     * @since   JDK1.1
   1.721 +     */
   1.722 +    public void printStackTrace(PrintWriter s) {
   1.723 +        printStackTrace(new WrappedPrintWriter(s));
   1.724 +    }
   1.725 +
   1.726 +    /**
   1.727 +     * Wrapper class for PrintStream and PrintWriter to enable a single
   1.728 +     * implementation of printStackTrace.
   1.729 +     */
   1.730 +    private abstract static class PrintStreamOrWriter {
   1.731 +        /** Returns the object to be locked when using this StreamOrWriter */
   1.732 +        abstract Object lock();
   1.733 +
   1.734 +        /** Prints the specified string as a line on this StreamOrWriter */
   1.735 +        abstract void println(Object o);
   1.736 +    }
   1.737 +
   1.738 +    private static class WrappedPrintStream extends PrintStreamOrWriter {
   1.739 +        private final PrintStream printStream;
   1.740 +
   1.741 +        WrappedPrintStream(PrintStream printStream) {
   1.742 +            this.printStream = printStream;
   1.743 +        }
   1.744 +
   1.745 +        Object lock() {
   1.746 +            return printStream;
   1.747 +        }
   1.748 +
   1.749 +        void println(Object o) {
   1.750 +            printStream.println(o);
   1.751 +        }
   1.752 +    }
   1.753 +
   1.754 +    private static class WrappedPrintWriter extends PrintStreamOrWriter {
   1.755 +        private final PrintWriter printWriter;
   1.756 +
   1.757 +        WrappedPrintWriter(PrintWriter printWriter) {
   1.758 +            this.printWriter = printWriter;
   1.759 +        }
   1.760 +
   1.761 +        Object lock() {
   1.762 +            return printWriter;
   1.763 +        }
   1.764 +
   1.765 +        void println(Object o) {
   1.766 +            printWriter.println(o);
   1.767 +        }
   1.768 +    }
   1.769 +
   1.770 +    /**
   1.771 +     * Fills in the execution stack trace. This method records within this
   1.772 +     * {@code Throwable} object information about the current state of
   1.773 +     * the stack frames for the current thread.
   1.774 +     *
   1.775 +     * <p>If the stack trace of this {@code Throwable} {@linkplain
   1.776 +     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
   1.777 +     * writable}, calling this method has no effect.
   1.778 +     *
   1.779 +     * @return  a reference to this {@code Throwable} instance.
   1.780 +     * @see     java.lang.Throwable#printStackTrace()
   1.781 +     */
   1.782 +    public synchronized Throwable fillInStackTrace() {
   1.783 +        if (stackTrace != null ||
   1.784 +            backtrace != null /* Out of protocol state */ ) {
   1.785 +            fillInStackTrace(0);
   1.786 +            stackTrace = UNASSIGNED_STACK;
   1.787 +        }
   1.788 +        return this;
   1.789 +    }
   1.790 +
   1.791 +    private native Throwable fillInStackTrace(int dummy);
   1.792 +
   1.793 +    /**
   1.794 +     * Provides programmatic access to the stack trace information printed by
   1.795 +     * {@link #printStackTrace()}.  Returns an array of stack trace elements,
   1.796 +     * each representing one stack frame.  The zeroth element of the array
   1.797 +     * (assuming the array's length is non-zero) represents the top of the
   1.798 +     * stack, which is the last method invocation in the sequence.  Typically,
   1.799 +     * this is the point at which this throwable was created and thrown.
   1.800 +     * The last element of the array (assuming the array's length is non-zero)
   1.801 +     * represents the bottom of the stack, which is the first method invocation
   1.802 +     * in the sequence.
   1.803 +     *
   1.804 +     * <p>Some virtual machines may, under some circumstances, omit one
   1.805 +     * or more stack frames from the stack trace.  In the extreme case,
   1.806 +     * a virtual machine that has no stack trace information concerning
   1.807 +     * this throwable is permitted to return a zero-length array from this
   1.808 +     * method.  Generally speaking, the array returned by this method will
   1.809 +     * contain one element for every frame that would be printed by
   1.810 +     * {@code printStackTrace}.  Writes to the returned array do not
   1.811 +     * affect future calls to this method.
   1.812 +     *
   1.813 +     * @return an array of stack trace elements representing the stack trace
   1.814 +     *         pertaining to this throwable.
   1.815 +     * @since  1.4
   1.816 +     */
   1.817 +    public StackTraceElement[] getStackTrace() {
   1.818 +        return getOurStackTrace().clone();
   1.819 +    }
   1.820 +
   1.821 +    private synchronized StackTraceElement[] getOurStackTrace() {
   1.822 +        // Initialize stack trace field with information from
   1.823 +        // backtrace if this is the first call to this method
   1.824 +        if (stackTrace == UNASSIGNED_STACK ||
   1.825 +            (stackTrace == null && backtrace != null) /* Out of protocol state */) {
   1.826 +            int depth = getStackTraceDepth();
   1.827 +            stackTrace = new StackTraceElement[depth];
   1.828 +            for (int i=0; i < depth; i++)
   1.829 +                stackTrace[i] = getStackTraceElement(i);
   1.830 +        } else if (stackTrace == null) {
   1.831 +            return UNASSIGNED_STACK;
   1.832 +        }
   1.833 +        return stackTrace;
   1.834 +    }
   1.835 +
   1.836 +    /**
   1.837 +     * Sets the stack trace elements that will be returned by
   1.838 +     * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
   1.839 +     * and related methods.
   1.840 +     *
   1.841 +     * This method, which is designed for use by RPC frameworks and other
   1.842 +     * advanced systems, allows the client to override the default
   1.843 +     * stack trace that is either generated by {@link #fillInStackTrace()}
   1.844 +     * when a throwable is constructed or deserialized when a throwable is
   1.845 +     * read from a serialization stream.
   1.846 +     *
   1.847 +     * <p>If the stack trace of this {@code Throwable} {@linkplain
   1.848 +     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
   1.849 +     * writable}, calling this method has no effect other than
   1.850 +     * validating its argument.
   1.851 +     *
   1.852 +     * @param   stackTrace the stack trace elements to be associated with
   1.853 +     * this {@code Throwable}.  The specified array is copied by this
   1.854 +     * call; changes in the specified array after the method invocation
   1.855 +     * returns will have no affect on this {@code Throwable}'s stack
   1.856 +     * trace.
   1.857 +     *
   1.858 +     * @throws NullPointerException if {@code stackTrace} is
   1.859 +     *         {@code null} or if any of the elements of
   1.860 +     *         {@code stackTrace} are {@code null}
   1.861 +     *
   1.862 +     * @since  1.4
   1.863 +     */
   1.864 +    public void setStackTrace(StackTraceElement[] stackTrace) {
   1.865 +        // Validate argument
   1.866 +        StackTraceElement[] defensiveCopy = stackTrace.clone();
   1.867 +        for (int i = 0; i < defensiveCopy.length; i++) {
   1.868 +            if (defensiveCopy[i] == null)
   1.869 +                throw new NullPointerException("stackTrace[" + i + "]");
   1.870 +        }
   1.871 +
   1.872 +        synchronized (this) {
   1.873 +            if (this.stackTrace == null && // Immutable stack
   1.874 +                backtrace == null) // Test for out of protocol state
   1.875 +                return;
   1.876 +            this.stackTrace = defensiveCopy;
   1.877 +        }
   1.878 +    }
   1.879 +
   1.880 +    /**
   1.881 +     * Returns the number of elements in the stack trace (or 0 if the stack
   1.882 +     * trace is unavailable).
   1.883 +     *
   1.884 +     * package-protection for use by SharedSecrets.
   1.885 +     */
   1.886 +    native int getStackTraceDepth();
   1.887 +
   1.888 +    /**
   1.889 +     * Returns the specified element of the stack trace.
   1.890 +     *
   1.891 +     * package-protection for use by SharedSecrets.
   1.892 +     *
   1.893 +     * @param index index of the element to return.
   1.894 +     * @throws IndexOutOfBoundsException if {@code index < 0 ||
   1.895 +     *         index >= getStackTraceDepth() }
   1.896 +     */
   1.897 +    native StackTraceElement getStackTraceElement(int index);
   1.898 +
   1.899 +    /**
   1.900 +     * Reads a {@code Throwable} from a stream, enforcing
   1.901 +     * well-formedness constraints on fields.  Null entries and
   1.902 +     * self-pointers are not allowed in the list of {@code
   1.903 +     * suppressedExceptions}.  Null entries are not allowed for stack
   1.904 +     * trace elements.  A null stack trace in the serial form results
   1.905 +     * in a zero-length stack element array. A single-element stack
   1.906 +     * trace whose entry is equal to {@code new StackTraceElement("",
   1.907 +     * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code
   1.908 +     * stackTrace} field.
   1.909 +     *
   1.910 +     * Note that there are no constraints on the value the {@code
   1.911 +     * cause} field can hold; both {@code null} and {@code this} are
   1.912 +     * valid values for the field.
   1.913 +     */
   1.914 +    private void readObject(ObjectInputStream s)
   1.915 +        throws IOException, ClassNotFoundException {
   1.916 +        s.defaultReadObject();     // read in all fields
   1.917 +        if (suppressedExceptions != null) {
   1.918 +            List<Throwable> suppressed = null;
   1.919 +            if (suppressedExceptions.isEmpty()) {
   1.920 +                // Use the sentinel for a zero-length list
   1.921 +                suppressed = SUPPRESSED_SENTINEL;
   1.922 +            } else { // Copy Throwables to new list
   1.923 +                suppressed = new ArrayList<>(1);
   1.924 +                for (Throwable t : suppressedExceptions) {
   1.925 +                    // Enforce constraints on suppressed exceptions in
   1.926 +                    // case of corrupt or malicious stream.
   1.927 +                    if (t == null)
   1.928 +                        throw new NullPointerException(NULL_CAUSE_MESSAGE);
   1.929 +                    if (t == this)
   1.930 +                        throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
   1.931 +                    suppressed.add(t);
   1.932 +                }
   1.933 +            }
   1.934 +            suppressedExceptions = suppressed;
   1.935 +        } // else a null suppressedExceptions field remains null
   1.936 +
   1.937 +        /*
   1.938 +         * For zero-length stack traces, use a clone of
   1.939 +         * UNASSIGNED_STACK rather than UNASSIGNED_STACK itself to
   1.940 +         * allow identity comparison against UNASSIGNED_STACK in
   1.941 +         * getOurStackTrace.  The identity of UNASSIGNED_STACK in
   1.942 +         * stackTrace indicates to the getOurStackTrace method that
   1.943 +         * the stackTrace needs to be constructed from the information
   1.944 +         * in backtrace.
   1.945 +         */
   1.946 +        if (stackTrace != null) {
   1.947 +            if (stackTrace.length == 0) {
   1.948 +                stackTrace = UNASSIGNED_STACK.clone();
   1.949 +            }  else if (stackTrace.length == 1 &&
   1.950 +                        // Check for the marker of an immutable stack trace
   1.951 +                        SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
   1.952 +                stackTrace = null;
   1.953 +            } else { // Verify stack trace elements are non-null.
   1.954 +                for(StackTraceElement ste : stackTrace) {
   1.955 +                    if (ste == null)
   1.956 +                        throw new NullPointerException("null StackTraceElement in serial stream. ");
   1.957 +                }
   1.958 +            }
   1.959 +        } else {
   1.960 +            // A null stackTrace field in the serial form can result
   1.961 +            // from an exception serialized without that field in
   1.962 +            // older JDK releases; treat such exceptions as having
   1.963 +            // empty stack traces.
   1.964 +            stackTrace = UNASSIGNED_STACK.clone();
   1.965 +        }
   1.966 +    }
   1.967 +
   1.968 +    /**
   1.969 +     * Write a {@code Throwable} object to a stream.
   1.970 +     *
   1.971 +     * A {@code null} stack trace field is represented in the serial
   1.972 +     * form as a one-element array whose element is equal to {@code
   1.973 +     * new StackTraceElement("", "", null, Integer.MIN_VALUE)}.
   1.974 +     */
   1.975 +    private synchronized void writeObject(ObjectOutputStream s)
   1.976 +        throws IOException {
   1.977 +        // Ensure that the stackTrace field is initialized to a
   1.978 +        // non-null value, if appropriate.  As of JDK 7, a null stack
   1.979 +        // trace field is a valid value indicating the stack trace
   1.980 +        // should not be set.
   1.981 +        getOurStackTrace();
   1.982 +
   1.983 +        StackTraceElement[] oldStackTrace = stackTrace;
   1.984 +        try {
   1.985 +            if (stackTrace == null)
   1.986 +                stackTrace = SentinelHolder.STACK_TRACE_SENTINEL;
   1.987 +            s.defaultWriteObject();
   1.988 +        } finally {
   1.989 +            stackTrace = oldStackTrace;
   1.990 +        }
   1.991 +    }
   1.992 +
   1.993 +    /**
   1.994 +     * Appends the specified exception to the exceptions that were
   1.995 +     * suppressed in order to deliver this exception. This method is
   1.996 +     * thread-safe and typically called (automatically and implicitly)
   1.997 +     * by the {@code try}-with-resources statement.
   1.998 +     *
   1.999 +     * <p>The suppression behavior is enabled <em>unless</em> disabled
  1.1000 +     * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
  1.1001 +     * a constructor}.  When suppression is disabled, this method does
  1.1002 +     * nothing other than to validate its argument.
  1.1003 +     *
  1.1004 +     * <p>Note that when one exception {@linkplain
  1.1005 +     * #initCause(Throwable) causes} another exception, the first
  1.1006 +     * exception is usually caught and then the second exception is
  1.1007 +     * thrown in response.  In other words, there is a causal
  1.1008 +     * connection between the two exceptions.
  1.1009 +     *
  1.1010 +     * In contrast, there are situations where two independent
  1.1011 +     * exceptions can be thrown in sibling code blocks, in particular
  1.1012 +     * in the {@code try} block of a {@code try}-with-resources
  1.1013 +     * statement and the compiler-generated {@code finally} block
  1.1014 +     * which closes the resource.
  1.1015 +     *
  1.1016 +     * In these situations, only one of the thrown exceptions can be
  1.1017 +     * propagated.  In the {@code try}-with-resources statement, when
  1.1018 +     * there are two such exceptions, the exception originating from
  1.1019 +     * the {@code try} block is propagated and the exception from the
  1.1020 +     * {@code finally} block is added to the list of exceptions
  1.1021 +     * suppressed by the exception from the {@code try} block.  As an
  1.1022 +     * exception unwinds the stack, it can accumulate multiple
  1.1023 +     * suppressed exceptions.
  1.1024 +     *
  1.1025 +     * <p>An exception may have suppressed exceptions while also being
  1.1026 +     * caused by another exception.  Whether or not an exception has a
  1.1027 +     * cause is semantically known at the time of its creation, unlike
  1.1028 +     * whether or not an exception will suppress other exceptions
  1.1029 +     * which is typically only determined after an exception is
  1.1030 +     * thrown.
  1.1031 +     *
  1.1032 +     * <p>Note that programmer written code is also able to take
  1.1033 +     * advantage of calling this method in situations where there are
  1.1034 +     * multiple sibling exceptions and only one can be propagated.
  1.1035 +     *
  1.1036 +     * @param exception the exception to be added to the list of
  1.1037 +     *        suppressed exceptions
  1.1038 +     * @throws IllegalArgumentException if {@code exception} is this
  1.1039 +     *         throwable; a throwable cannot suppress itself.
  1.1040 +     * @throws NullPointerException if {@code exception} is {@code null}
  1.1041 +     * @since 1.7
  1.1042 +     */
  1.1043 +    public final synchronized void addSuppressed(Throwable exception) {
  1.1044 +        if (exception == this)
  1.1045 +            throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
  1.1046 +
  1.1047 +        if (exception == null)
  1.1048 +            throw new NullPointerException(NULL_CAUSE_MESSAGE);
  1.1049 +
  1.1050 +        if (suppressedExceptions == null) // Suppressed exceptions not recorded
  1.1051 +            return;
  1.1052 +
  1.1053 +        if (suppressedExceptions == SUPPRESSED_SENTINEL)
  1.1054 +            suppressedExceptions = new ArrayList<>(1);
  1.1055 +
  1.1056 +        suppressedExceptions.add(exception);
  1.1057 +    }
  1.1058 +
  1.1059 +    private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
  1.1060 +
  1.1061 +    /**
  1.1062 +     * Returns an array containing all of the exceptions that were
  1.1063 +     * suppressed, typically by the {@code try}-with-resources
  1.1064 +     * statement, in order to deliver this exception.
  1.1065 +     *
  1.1066 +     * If no exceptions were suppressed or {@linkplain
  1.1067 +     * #Throwable(String, Throwable, boolean, boolean) suppression is
  1.1068 +     * disabled}, an empty array is returned.  This method is
  1.1069 +     * thread-safe.  Writes to the returned array do not affect future
  1.1070 +     * calls to this method.
  1.1071 +     *
  1.1072 +     * @return an array containing all of the exceptions that were
  1.1073 +     *         suppressed to deliver this exception.
  1.1074 +     * @since 1.7
  1.1075 +     */
  1.1076 +    public final synchronized Throwable[] getSuppressed() {
  1.1077 +        if (suppressedExceptions == SUPPRESSED_SENTINEL ||
  1.1078 +            suppressedExceptions == null)
  1.1079 +            return EMPTY_THROWABLE_ARRAY;
  1.1080 +        else
  1.1081 +            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
  1.1082 +    }
  1.1083 +}