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