emul/src/main/java/java/lang/Throwable.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 14 Jan 2013 11:30:56 +0100
branchUseFunctionCall
changeset 443 9359b006782b
parent 234 a2f1380f8a28
child 502 a5cd79ee1d96
permissions -rw-r--r--
Using 'this' in @JavaScriptBody instance methods
jaroslav@49
     1
/*
jaroslav@49
     2
 * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
jaroslav@49
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@49
     4
 *
jaroslav@49
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@49
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@49
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@49
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@49
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@49
    10
 *
jaroslav@49
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@49
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@49
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@49
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@49
    15
 * accompanied this code).
jaroslav@49
    16
 *
jaroslav@49
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@49
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@49
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@49
    20
 *
jaroslav@49
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@49
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@49
    23
 * questions.
jaroslav@49
    24
 */
jaroslav@49
    25
jaroslav@49
    26
package java.lang;
jaroslav@49
    27
import  java.io.*;
jaroslav@234
    28
import org.apidesign.bck2brwsr.core.JavaScriptBody;
jaroslav@49
    29
jaroslav@49
    30
/**
jaroslav@49
    31
 * The {@code Throwable} class is the superclass of all errors and
jaroslav@49
    32
 * exceptions in the Java language. Only objects that are instances of this
jaroslav@49
    33
 * class (or one of its subclasses) are thrown by the Java Virtual Machine or
jaroslav@49
    34
 * can be thrown by the Java {@code throw} statement. Similarly, only
jaroslav@49
    35
 * this class or one of its subclasses can be the argument type in a
jaroslav@49
    36
 * {@code catch} clause.
jaroslav@49
    37
 *
jaroslav@49
    38
 * For the purposes of compile-time checking of exceptions, {@code
jaroslav@49
    39
 * Throwable} and any subclass of {@code Throwable} that is not also a
jaroslav@49
    40
 * subclass of either {@link RuntimeException} or {@link Error} are
jaroslav@49
    41
 * regarded as checked exceptions.
jaroslav@49
    42
 *
jaroslav@49
    43
 * <p>Instances of two subclasses, {@link java.lang.Error} and
jaroslav@49
    44
 * {@link java.lang.Exception}, are conventionally used to indicate
jaroslav@49
    45
 * that exceptional situations have occurred. Typically, these instances
jaroslav@49
    46
 * are freshly created in the context of the exceptional situation so
jaroslav@49
    47
 * as to include relevant information (such as stack trace data).
jaroslav@49
    48
 *
jaroslav@49
    49
 * <p>A throwable contains a snapshot of the execution stack of its
jaroslav@49
    50
 * thread at the time it was created. It can also contain a message
jaroslav@49
    51
 * string that gives more information about the error. Over time, a
jaroslav@49
    52
 * throwable can {@linkplain Throwable#addSuppressed suppress} other
jaroslav@49
    53
 * throwables from being propagated.  Finally, the throwable can also
jaroslav@49
    54
 * contain a <i>cause</i>: another throwable that caused this
jaroslav@49
    55
 * throwable to be constructed.  The recording of this causal information
jaroslav@49
    56
 * is referred to as the <i>chained exception</i> facility, as the
jaroslav@49
    57
 * cause can, itself, have a cause, and so on, leading to a "chain" of
jaroslav@49
    58
 * exceptions, each caused by another.
jaroslav@49
    59
 *
jaroslav@49
    60
 * <p>One reason that a throwable may have a cause is that the class that
jaroslav@49
    61
 * throws it is built atop a lower layered abstraction, and an operation on
jaroslav@49
    62
 * the upper layer fails due to a failure in the lower layer.  It would be bad
jaroslav@49
    63
 * design to let the throwable thrown by the lower layer propagate outward, as
jaroslav@49
    64
 * it is generally unrelated to the abstraction provided by the upper layer.
jaroslav@49
    65
 * Further, doing so would tie the API of the upper layer to the details of
jaroslav@49
    66
 * its implementation, assuming the lower layer's exception was a checked
jaroslav@49
    67
 * exception.  Throwing a "wrapped exception" (i.e., an exception containing a
jaroslav@49
    68
 * cause) allows the upper layer to communicate the details of the failure to
jaroslav@49
    69
 * its caller without incurring either of these shortcomings.  It preserves
jaroslav@49
    70
 * the flexibility to change the implementation of the upper layer without
jaroslav@49
    71
 * changing its API (in particular, the set of exceptions thrown by its
jaroslav@49
    72
 * methods).
jaroslav@49
    73
 *
jaroslav@49
    74
 * <p>A second reason that a throwable may have a cause is that the method
jaroslav@49
    75
 * that throws it must conform to a general-purpose interface that does not
jaroslav@49
    76
 * permit the method to throw the cause directly.  For example, suppose
jaroslav@49
    77
 * a persistent collection conforms to the {@link java.util.Collection
jaroslav@49
    78
 * Collection} interface, and that its persistence is implemented atop
jaroslav@49
    79
 * {@code java.io}.  Suppose the internals of the {@code add} method
jaroslav@49
    80
 * can throw an {@link java.io.IOException IOException}.  The implementation
jaroslav@49
    81
 * can communicate the details of the {@code IOException} to its caller
jaroslav@49
    82
 * while conforming to the {@code Collection} interface by wrapping the
jaroslav@49
    83
 * {@code IOException} in an appropriate unchecked exception.  (The
jaroslav@49
    84
 * specification for the persistent collection should indicate that it is
jaroslav@49
    85
 * capable of throwing such exceptions.)
jaroslav@49
    86
 *
jaroslav@49
    87
 * <p>A cause can be associated with a throwable in two ways: via a
jaroslav@49
    88
 * constructor that takes the cause as an argument, or via the
jaroslav@49
    89
 * {@link #initCause(Throwable)} method.  New throwable classes that
jaroslav@49
    90
 * wish to allow causes to be associated with them should provide constructors
jaroslav@49
    91
 * that take a cause and delegate (perhaps indirectly) to one of the
jaroslav@49
    92
 * {@code Throwable} constructors that takes a cause.
jaroslav@49
    93
 *
jaroslav@49
    94
 * Because the {@code initCause} method is public, it allows a cause to be
jaroslav@49
    95
 * associated with any throwable, even a "legacy throwable" whose
jaroslav@49
    96
 * implementation predates the addition of the exception chaining mechanism to
jaroslav@49
    97
 * {@code Throwable}.
jaroslav@49
    98
 *
jaroslav@49
    99
 * <p>By convention, class {@code Throwable} and its subclasses have two
jaroslav@49
   100
 * constructors, one that takes no arguments and one that takes a
jaroslav@49
   101
 * {@code String} argument that can be used to produce a detail message.
jaroslav@49
   102
 * Further, those subclasses that might likely have a cause associated with
jaroslav@49
   103
 * them should have two more constructors, one that takes a
jaroslav@49
   104
 * {@code Throwable} (the cause), and one that takes a
jaroslav@49
   105
 * {@code String} (the detail message) and a {@code Throwable} (the
jaroslav@49
   106
 * cause).
jaroslav@49
   107
 *
jaroslav@49
   108
 * @author  unascribed
jaroslav@49
   109
 * @author  Josh Bloch (Added exception chaining and programmatic access to
jaroslav@49
   110
 *          stack trace in 1.4.)
jaroslav@49
   111
 * @jls 11.2 Compile-Time Checking of Exceptions
jaroslav@49
   112
 * @since JDK1.0
jaroslav@49
   113
 */
jaroslav@49
   114
public class Throwable implements Serializable {
jaroslav@49
   115
    /** use serialVersionUID from JDK 1.0.2 for interoperability */
jaroslav@49
   116
    private static final long serialVersionUID = -3042686055658047285L;
jaroslav@49
   117
jaroslav@49
   118
    /**
jaroslav@49
   119
     * Native code saves some indication of the stack backtrace in this slot.
jaroslav@49
   120
     */
jaroslav@49
   121
    private transient Object backtrace;
jaroslav@49
   122
jaroslav@49
   123
    /**
jaroslav@49
   124
     * Specific details about the Throwable.  For example, for
jaroslav@49
   125
     * {@code FileNotFoundException}, this contains the name of
jaroslav@49
   126
     * the file that could not be found.
jaroslav@49
   127
     *
jaroslav@49
   128
     * @serial
jaroslav@49
   129
     */
jaroslav@49
   130
    private String detailMessage;
jaroslav@49
   131
jaroslav@49
   132
jaroslav@49
   133
    /**
jaroslav@49
   134
     * Holder class to defer initializing sentinel objects only used
jaroslav@49
   135
     * for serialization.
jaroslav@49
   136
     */
jaroslav@49
   137
    private static class SentinelHolder {
jaroslav@49
   138
        /**
jaroslav@49
   139
         * {@linkplain #setStackTrace(StackTraceElement[]) Setting the
jaroslav@49
   140
         * stack trace} to a one-element array containing this sentinel
jaroslav@49
   141
         * value indicates future attempts to set the stack trace will be
jaroslav@49
   142
         * ignored.  The sentinal is equal to the result of calling:<br>
jaroslav@49
   143
         * {@code new StackTraceElement("", "", null, Integer.MIN_VALUE)}
jaroslav@49
   144
         */
jaroslav@49
   145
        public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
jaroslav@49
   146
            new StackTraceElement("", "", null, Integer.MIN_VALUE);
jaroslav@49
   147
jaroslav@49
   148
        /**
jaroslav@49
   149
         * Sentinel value used in the serial form to indicate an immutable
jaroslav@49
   150
         * stack trace.
jaroslav@49
   151
         */
jaroslav@49
   152
        public static final StackTraceElement[] STACK_TRACE_SENTINEL =
jaroslav@49
   153
            new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
jaroslav@49
   154
    }
jaroslav@49
   155
jaroslav@49
   156
    /**
jaroslav@49
   157
     * A shared value for an empty stack.
jaroslav@49
   158
     */
jaroslav@49
   159
    private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
jaroslav@49
   160
jaroslav@49
   161
    /*
jaroslav@49
   162
     * To allow Throwable objects to be made immutable and safely
jaroslav@49
   163
     * reused by the JVM, such as OutOfMemoryErrors, fields of
jaroslav@49
   164
     * Throwable that are writable in response to user actions, cause,
jaroslav@49
   165
     * stackTrace, and suppressedExceptions obey the following
jaroslav@49
   166
     * protocol:
jaroslav@49
   167
     *
jaroslav@49
   168
     * 1) The fields are initialized to a non-null sentinel value
jaroslav@49
   169
     * which indicates the value has logically not been set.
jaroslav@49
   170
     *
jaroslav@49
   171
     * 2) Writing a null to the field indicates further writes
jaroslav@49
   172
     * are forbidden
jaroslav@49
   173
     *
jaroslav@49
   174
     * 3) The sentinel value may be replaced with another non-null
jaroslav@49
   175
     * value.
jaroslav@49
   176
     *
jaroslav@49
   177
     * For example, implementations of the HotSpot JVM have
jaroslav@49
   178
     * preallocated OutOfMemoryError objects to provide for better
jaroslav@49
   179
     * diagnosability of that situation.  These objects are created
jaroslav@49
   180
     * without calling the constructor for that class and the fields
jaroslav@49
   181
     * in question are initialized to null.  To support this
jaroslav@49
   182
     * capability, any new fields added to Throwable that require
jaroslav@49
   183
     * being initialized to a non-null value require a coordinated JVM
jaroslav@49
   184
     * change.
jaroslav@49
   185
     */
jaroslav@49
   186
jaroslav@49
   187
    /**
jaroslav@49
   188
     * The throwable that caused this throwable to get thrown, or null if this
jaroslav@49
   189
     * throwable was not caused by another throwable, or if the causative
jaroslav@49
   190
     * throwable is unknown.  If this field is equal to this throwable itself,
jaroslav@49
   191
     * it indicates that the cause of this throwable has not yet been
jaroslav@49
   192
     * initialized.
jaroslav@49
   193
     *
jaroslav@49
   194
     * @serial
jaroslav@49
   195
     * @since 1.4
jaroslav@49
   196
     */
jaroslav@49
   197
    private Throwable cause = this;
jaroslav@49
   198
jaroslav@49
   199
    /**
jaroslav@49
   200
     * The stack trace, as returned by {@link #getStackTrace()}.
jaroslav@49
   201
     *
jaroslav@49
   202
     * The field is initialized to a zero-length array.  A {@code
jaroslav@49
   203
     * null} value of this field indicates subsequent calls to {@link
jaroslav@49
   204
     * #setStackTrace(StackTraceElement[])} and {@link
jaroslav@49
   205
     * #fillInStackTrace()} will be be no-ops.
jaroslav@49
   206
     *
jaroslav@49
   207
     * @serial
jaroslav@49
   208
     * @since 1.4
jaroslav@49
   209
     */
jaroslav@49
   210
    private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
jaroslav@49
   211
jaroslav@49
   212
    // Setting this static field introduces an acceptable
jaroslav@49
   213
    // initialization dependency on a few java.util classes.
jaroslav@61
   214
// I don't think this dependency is acceptable
jaroslav@61
   215
//    private static final List<Throwable> SUPPRESSED_SENTINEL =
jaroslav@61
   216
//        Collections.unmodifiableList(new ArrayList<Throwable>(0));
jaroslav@49
   217
jaroslav@49
   218
    /**
jaroslav@49
   219
     * The list of suppressed exceptions, as returned by {@link
jaroslav@49
   220
     * #getSuppressed()}.  The list is initialized to a zero-element
jaroslav@49
   221
     * unmodifiable sentinel list.  When a serialized Throwable is
jaroslav@49
   222
     * read in, if the {@code suppressedExceptions} field points to a
jaroslav@49
   223
     * zero-element list, the field is reset to the sentinel value.
jaroslav@49
   224
     *
jaroslav@49
   225
     * @serial
jaroslav@49
   226
     * @since 1.7
jaroslav@49
   227
     */
jaroslav@61
   228
//    private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
jaroslav@49
   229
jaroslav@49
   230
    /** Message for trying to suppress a null exception. */
jaroslav@49
   231
    private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
jaroslav@49
   232
jaroslav@49
   233
    /** Message for trying to suppress oneself. */
jaroslav@49
   234
    private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";
jaroslav@49
   235
jaroslav@49
   236
    /** Caption  for labeling causative exception stack traces */
jaroslav@49
   237
    private static final String CAUSE_CAPTION = "Caused by: ";
jaroslav@49
   238
jaroslav@49
   239
    /** Caption for labeling suppressed exception stack traces */
jaroslav@49
   240
    private static final String SUPPRESSED_CAPTION = "Suppressed: ";
jaroslav@49
   241
jaroslav@49
   242
    /**
jaroslav@49
   243
     * Constructs a new throwable with {@code null} as its detail message.
jaroslav@49
   244
     * The cause is not initialized, and may subsequently be initialized by a
jaroslav@49
   245
     * call to {@link #initCause}.
jaroslav@49
   246
     *
jaroslav@49
   247
     * <p>The {@link #fillInStackTrace()} method is called to initialize
jaroslav@49
   248
     * the stack trace data in the newly created throwable.
jaroslav@49
   249
     */
jaroslav@49
   250
    public Throwable() {
jaroslav@49
   251
        fillInStackTrace();
jaroslav@49
   252
    }
jaroslav@49
   253
jaroslav@49
   254
    /**
jaroslav@49
   255
     * Constructs a new throwable with the specified detail message.  The
jaroslav@49
   256
     * cause is not initialized, and may subsequently be initialized by
jaroslav@49
   257
     * a call to {@link #initCause}.
jaroslav@49
   258
     *
jaroslav@49
   259
     * <p>The {@link #fillInStackTrace()} method is called to initialize
jaroslav@49
   260
     * the stack trace data in the newly created throwable.
jaroslav@49
   261
     *
jaroslav@49
   262
     * @param   message   the detail message. The detail message is saved for
jaroslav@49
   263
     *          later retrieval by the {@link #getMessage()} method.
jaroslav@49
   264
     */
jaroslav@49
   265
    public Throwable(String message) {
jaroslav@49
   266
        fillInStackTrace();
jaroslav@49
   267
        detailMessage = message;
jaroslav@49
   268
    }
jaroslav@49
   269
jaroslav@49
   270
    /**
jaroslav@49
   271
     * Constructs a new throwable with the specified detail message and
jaroslav@49
   272
     * cause.  <p>Note that the detail message associated with
jaroslav@49
   273
     * {@code cause} is <i>not</i> automatically incorporated in
jaroslav@49
   274
     * this throwable's detail message.
jaroslav@49
   275
     *
jaroslav@49
   276
     * <p>The {@link #fillInStackTrace()} method is called to initialize
jaroslav@49
   277
     * the stack trace data in the newly created throwable.
jaroslav@49
   278
     *
jaroslav@49
   279
     * @param  message the detail message (which is saved for later retrieval
jaroslav@49
   280
     *         by the {@link #getMessage()} method).
jaroslav@49
   281
     * @param  cause the cause (which is saved for later retrieval by the
jaroslav@49
   282
     *         {@link #getCause()} method).  (A {@code null} value is
jaroslav@49
   283
     *         permitted, and indicates that the cause is nonexistent or
jaroslav@49
   284
     *         unknown.)
jaroslav@49
   285
     * @since  1.4
jaroslav@49
   286
     */
jaroslav@49
   287
    public Throwable(String message, Throwable cause) {
jaroslav@49
   288
        fillInStackTrace();
jaroslav@49
   289
        detailMessage = message;
jaroslav@49
   290
        this.cause = cause;
jaroslav@49
   291
    }
jaroslav@49
   292
jaroslav@49
   293
    /**
jaroslav@49
   294
     * Constructs a new throwable with the specified cause and a detail
jaroslav@49
   295
     * message of {@code (cause==null ? null : cause.toString())} (which
jaroslav@49
   296
     * typically contains the class and detail message of {@code cause}).
jaroslav@49
   297
     * This constructor is useful for throwables that are little more than
jaroslav@49
   298
     * wrappers for other throwables (for example, {@link
jaroslav@49
   299
     * java.security.PrivilegedActionException}).
jaroslav@49
   300
     *
jaroslav@49
   301
     * <p>The {@link #fillInStackTrace()} method is called to initialize
jaroslav@49
   302
     * the stack trace data in the newly created throwable.
jaroslav@49
   303
     *
jaroslav@49
   304
     * @param  cause the cause (which is saved for later retrieval by the
jaroslav@49
   305
     *         {@link #getCause()} method).  (A {@code null} value is
jaroslav@49
   306
     *         permitted, and indicates that the cause is nonexistent or
jaroslav@49
   307
     *         unknown.)
jaroslav@49
   308
     * @since  1.4
jaroslav@49
   309
     */
jaroslav@49
   310
    public Throwable(Throwable cause) {
jaroslav@49
   311
        fillInStackTrace();
jaroslav@49
   312
        detailMessage = (cause==null ? null : cause.toString());
jaroslav@49
   313
        this.cause = cause;
jaroslav@49
   314
    }
jaroslav@49
   315
jaroslav@49
   316
    /**
jaroslav@49
   317
     * Constructs a new throwable with the specified detail message,
jaroslav@49
   318
     * cause, {@linkplain #addSuppressed suppression} enabled or
jaroslav@49
   319
     * disabled, and writable stack trace enabled or disabled.  If
jaroslav@49
   320
     * suppression is disabled, {@link #getSuppressed} for this object
jaroslav@49
   321
     * will return a zero-length array and calls to {@link
jaroslav@49
   322
     * #addSuppressed} that would otherwise append an exception to the
jaroslav@49
   323
     * suppressed list will have no effect.  If the writable stack
jaroslav@49
   324
     * trace is false, this constructor will not call {@link
jaroslav@49
   325
     * #fillInStackTrace()}, a {@code null} will be written to the
jaroslav@49
   326
     * {@code stackTrace} field, and subsequent calls to {@code
jaroslav@49
   327
     * fillInStackTrace} and {@link
jaroslav@49
   328
     * #setStackTrace(StackTraceElement[])} will not set the stack
jaroslav@49
   329
     * trace.  If the writable stack trace is false, {@link
jaroslav@49
   330
     * #getStackTrace} will return a zero length array.
jaroslav@49
   331
     *
jaroslav@49
   332
     * <p>Note that the other constructors of {@code Throwable} treat
jaroslav@49
   333
     * suppression as being enabled and the stack trace as being
jaroslav@49
   334
     * writable.  Subclasses of {@code Throwable} should document any
jaroslav@49
   335
     * conditions under which suppression is disabled and document
jaroslav@49
   336
     * conditions under which the stack trace is not writable.
jaroslav@49
   337
     * Disabling of suppression should only occur in exceptional
jaroslav@49
   338
     * circumstances where special requirements exist, such as a
jaroslav@49
   339
     * virtual machine reusing exception objects under low-memory
jaroslav@49
   340
     * situations.  Circumstances where a given exception object is
jaroslav@49
   341
     * repeatedly caught and rethrown, such as to implement control
jaroslav@49
   342
     * flow between two sub-systems, is another situation where
jaroslav@49
   343
     * immutable throwable objects would be appropriate.
jaroslav@49
   344
     *
jaroslav@49
   345
     * @param  message the detail message.
jaroslav@49
   346
     * @param cause the cause.  (A {@code null} value is permitted,
jaroslav@49
   347
     * and indicates that the cause is nonexistent or unknown.)
jaroslav@49
   348
     * @param enableSuppression whether or not suppression is enabled or disabled
jaroslav@49
   349
     * @param writableStackTrace whether or not the stack trace should be
jaroslav@49
   350
     *                           writable
jaroslav@49
   351
     *
jaroslav@49
   352
     * @see OutOfMemoryError
jaroslav@49
   353
     * @see NullPointerException
jaroslav@49
   354
     * @see ArithmeticException
jaroslav@49
   355
     * @since 1.7
jaroslav@49
   356
     */
jaroslav@49
   357
    protected Throwable(String message, Throwable cause,
jaroslav@49
   358
                        boolean enableSuppression,
jaroslav@49
   359
                        boolean writableStackTrace) {
jaroslav@49
   360
        if (writableStackTrace) {
jaroslav@49
   361
            fillInStackTrace();
jaroslav@49
   362
        } else {
jaroslav@49
   363
            stackTrace = null;
jaroslav@49
   364
        }
jaroslav@49
   365
        detailMessage = message;
jaroslav@49
   366
        this.cause = cause;
jaroslav@61
   367
//        if (!enableSuppression)
jaroslav@61
   368
//            suppressedExceptions = null;
jaroslav@49
   369
    }
jaroslav@49
   370
jaroslav@49
   371
    /**
jaroslav@49
   372
     * Returns the detail message string of this throwable.
jaroslav@49
   373
     *
jaroslav@49
   374
     * @return  the detail message string of this {@code Throwable} instance
jaroslav@49
   375
     *          (which may be {@code null}).
jaroslav@49
   376
     */
jaroslav@49
   377
    public String getMessage() {
jaroslav@49
   378
        return detailMessage;
jaroslav@49
   379
    }
jaroslav@49
   380
jaroslav@49
   381
    /**
jaroslav@49
   382
     * Creates a localized description of this throwable.
jaroslav@49
   383
     * Subclasses may override this method in order to produce a
jaroslav@49
   384
     * locale-specific message.  For subclasses that do not override this
jaroslav@49
   385
     * method, the default implementation returns the same result as
jaroslav@49
   386
     * {@code getMessage()}.
jaroslav@49
   387
     *
jaroslav@49
   388
     * @return  The localized description of this throwable.
jaroslav@49
   389
     * @since   JDK1.1
jaroslav@49
   390
     */
jaroslav@49
   391
    public String getLocalizedMessage() {
jaroslav@49
   392
        return getMessage();
jaroslav@49
   393
    }
jaroslav@49
   394
jaroslav@49
   395
    /**
jaroslav@49
   396
     * Returns the cause of this throwable or {@code null} if the
jaroslav@49
   397
     * cause is nonexistent or unknown.  (The cause is the throwable that
jaroslav@49
   398
     * caused this throwable to get thrown.)
jaroslav@49
   399
     *
jaroslav@49
   400
     * <p>This implementation returns the cause that was supplied via one of
jaroslav@49
   401
     * the constructors requiring a {@code Throwable}, or that was set after
jaroslav@49
   402
     * creation with the {@link #initCause(Throwable)} method.  While it is
jaroslav@49
   403
     * typically unnecessary to override this method, a subclass can override
jaroslav@49
   404
     * it to return a cause set by some other means.  This is appropriate for
jaroslav@49
   405
     * a "legacy chained throwable" that predates the addition of chained
jaroslav@49
   406
     * exceptions to {@code Throwable}.  Note that it is <i>not</i>
jaroslav@49
   407
     * necessary to override any of the {@code PrintStackTrace} methods,
jaroslav@49
   408
     * all of which invoke the {@code getCause} method to determine the
jaroslav@49
   409
     * cause of a throwable.
jaroslav@49
   410
     *
jaroslav@49
   411
     * @return  the cause of this throwable or {@code null} if the
jaroslav@49
   412
     *          cause is nonexistent or unknown.
jaroslav@49
   413
     * @since 1.4
jaroslav@49
   414
     */
jaroslav@49
   415
    public synchronized Throwable getCause() {
jaroslav@49
   416
        return (cause==this ? null : cause);
jaroslav@49
   417
    }
jaroslav@49
   418
jaroslav@49
   419
    /**
jaroslav@49
   420
     * Initializes the <i>cause</i> of this throwable to the specified value.
jaroslav@49
   421
     * (The cause is the throwable that caused this throwable to get thrown.)
jaroslav@49
   422
     *
jaroslav@49
   423
     * <p>This method can be called at most once.  It is generally called from
jaroslav@49
   424
     * within the constructor, or immediately after creating the
jaroslav@49
   425
     * throwable.  If this throwable was created
jaroslav@49
   426
     * with {@link #Throwable(Throwable)} or
jaroslav@49
   427
     * {@link #Throwable(String,Throwable)}, this method cannot be called
jaroslav@49
   428
     * even once.
jaroslav@49
   429
     *
jaroslav@49
   430
     * <p>An example of using this method on a legacy throwable type
jaroslav@49
   431
     * without other support for setting the cause is:
jaroslav@49
   432
     *
jaroslav@49
   433
     * <pre>
jaroslav@49
   434
     * try {
jaroslav@49
   435
     *     lowLevelOp();
jaroslav@49
   436
     * } catch (LowLevelException le) {
jaroslav@49
   437
     *     throw (HighLevelException)
jaroslav@49
   438
     *           new HighLevelException().initCause(le); // Legacy constructor
jaroslav@49
   439
     * }
jaroslav@49
   440
     * </pre>
jaroslav@49
   441
     *
jaroslav@49
   442
     * @param  cause the cause (which is saved for later retrieval by the
jaroslav@49
   443
     *         {@link #getCause()} method).  (A {@code null} value is
jaroslav@49
   444
     *         permitted, and indicates that the cause is nonexistent or
jaroslav@49
   445
     *         unknown.)
jaroslav@49
   446
     * @return  a reference to this {@code Throwable} instance.
jaroslav@49
   447
     * @throws IllegalArgumentException if {@code cause} is this
jaroslav@49
   448
     *         throwable.  (A throwable cannot be its own cause.)
jaroslav@49
   449
     * @throws IllegalStateException if this throwable was
jaroslav@49
   450
     *         created with {@link #Throwable(Throwable)} or
jaroslav@49
   451
     *         {@link #Throwable(String,Throwable)}, or this method has already
jaroslav@49
   452
     *         been called on this throwable.
jaroslav@49
   453
     * @since  1.4
jaroslav@49
   454
     */
jaroslav@49
   455
    public synchronized Throwable initCause(Throwable cause) {
jaroslav@49
   456
        if (this.cause != this)
jaroslav@49
   457
            throw new IllegalStateException("Can't overwrite cause");
jaroslav@49
   458
        if (cause == this)
jaroslav@49
   459
            throw new IllegalArgumentException("Self-causation not permitted");
jaroslav@49
   460
        this.cause = cause;
jaroslav@49
   461
        return this;
jaroslav@49
   462
    }
jaroslav@49
   463
jaroslav@49
   464
    /**
jaroslav@49
   465
     * Returns a short description of this throwable.
jaroslav@49
   466
     * The result is the concatenation of:
jaroslav@49
   467
     * <ul>
jaroslav@49
   468
     * <li> the {@linkplain Class#getName() name} of the class of this object
jaroslav@49
   469
     * <li> ": " (a colon and a space)
jaroslav@49
   470
     * <li> the result of invoking this object's {@link #getLocalizedMessage}
jaroslav@49
   471
     *      method
jaroslav@49
   472
     * </ul>
jaroslav@49
   473
     * If {@code getLocalizedMessage} returns {@code null}, then just
jaroslav@49
   474
     * the class name is returned.
jaroslav@49
   475
     *
jaroslav@49
   476
     * @return a string representation of this throwable.
jaroslav@49
   477
     */
jaroslav@49
   478
    public String toString() {
jaroslav@49
   479
        String s = getClass().getName();
jaroslav@49
   480
        String message = getLocalizedMessage();
jaroslav@49
   481
        return (message != null) ? (s + ": " + message) : s;
jaroslav@49
   482
    }
jaroslav@49
   483
jaroslav@49
   484
    /**
jaroslav@49
   485
     * Prints this throwable and its backtrace to the
jaroslav@49
   486
     * standard error stream. This method prints a stack trace for this
jaroslav@49
   487
     * {@code Throwable} object on the error output stream that is
jaroslav@49
   488
     * the value of the field {@code System.err}. The first line of
jaroslav@49
   489
     * output contains the result of the {@link #toString()} method for
jaroslav@49
   490
     * this object.  Remaining lines represent data previously recorded by
jaroslav@49
   491
     * the method {@link #fillInStackTrace()}. The format of this
jaroslav@49
   492
     * information depends on the implementation, but the following
jaroslav@49
   493
     * example may be regarded as typical:
jaroslav@49
   494
     * <blockquote><pre>
jaroslav@49
   495
     * java.lang.NullPointerException
jaroslav@49
   496
     *         at MyClass.mash(MyClass.java:9)
jaroslav@49
   497
     *         at MyClass.crunch(MyClass.java:6)
jaroslav@49
   498
     *         at MyClass.main(MyClass.java:3)
jaroslav@49
   499
     * </pre></blockquote>
jaroslav@49
   500
     * This example was produced by running the program:
jaroslav@49
   501
     * <pre>
jaroslav@49
   502
     * class MyClass {
jaroslav@49
   503
     *     public static void main(String[] args) {
jaroslav@49
   504
     *         crunch(null);
jaroslav@49
   505
     *     }
jaroslav@49
   506
     *     static void crunch(int[] a) {
jaroslav@49
   507
     *         mash(a);
jaroslav@49
   508
     *     }
jaroslav@49
   509
     *     static void mash(int[] b) {
jaroslav@49
   510
     *         System.out.println(b[0]);
jaroslav@49
   511
     *     }
jaroslav@49
   512
     * }
jaroslav@49
   513
     * </pre>
jaroslav@49
   514
     * The backtrace for a throwable with an initialized, non-null cause
jaroslav@49
   515
     * should generally include the backtrace for the cause.  The format
jaroslav@49
   516
     * of this information depends on the implementation, but the following
jaroslav@49
   517
     * example may be regarded as typical:
jaroslav@49
   518
     * <pre>
jaroslav@49
   519
     * HighLevelException: MidLevelException: LowLevelException
jaroslav@49
   520
     *         at Junk.a(Junk.java:13)
jaroslav@49
   521
     *         at Junk.main(Junk.java:4)
jaroslav@49
   522
     * Caused by: MidLevelException: LowLevelException
jaroslav@49
   523
     *         at Junk.c(Junk.java:23)
jaroslav@49
   524
     *         at Junk.b(Junk.java:17)
jaroslav@49
   525
     *         at Junk.a(Junk.java:11)
jaroslav@49
   526
     *         ... 1 more
jaroslav@49
   527
     * Caused by: LowLevelException
jaroslav@49
   528
     *         at Junk.e(Junk.java:30)
jaroslav@49
   529
     *         at Junk.d(Junk.java:27)
jaroslav@49
   530
     *         at Junk.c(Junk.java:21)
jaroslav@49
   531
     *         ... 3 more
jaroslav@49
   532
     * </pre>
jaroslav@49
   533
     * Note the presence of lines containing the characters {@code "..."}.
jaroslav@49
   534
     * These lines indicate that the remainder of the stack trace for this
jaroslav@49
   535
     * exception matches the indicated number of frames from the bottom of the
jaroslav@49
   536
     * stack trace of the exception that was caused by this exception (the
jaroslav@49
   537
     * "enclosing" exception).  This shorthand can greatly reduce the length
jaroslav@49
   538
     * of the output in the common case where a wrapped exception is thrown
jaroslav@49
   539
     * from same method as the "causative exception" is caught.  The above
jaroslav@49
   540
     * example was produced by running the program:
jaroslav@49
   541
     * <pre>
jaroslav@49
   542
     * public class Junk {
jaroslav@49
   543
     *     public static void main(String args[]) {
jaroslav@49
   544
     *         try {
jaroslav@49
   545
     *             a();
jaroslav@49
   546
     *         } catch(HighLevelException e) {
jaroslav@49
   547
     *             e.printStackTrace();
jaroslav@49
   548
     *         }
jaroslav@49
   549
     *     }
jaroslav@49
   550
     *     static void a() throws HighLevelException {
jaroslav@49
   551
     *         try {
jaroslav@49
   552
     *             b();
jaroslav@49
   553
     *         } catch(MidLevelException e) {
jaroslav@49
   554
     *             throw new HighLevelException(e);
jaroslav@49
   555
     *         }
jaroslav@49
   556
     *     }
jaroslav@49
   557
     *     static void b() throws MidLevelException {
jaroslav@49
   558
     *         c();
jaroslav@49
   559
     *     }
jaroslav@49
   560
     *     static void c() throws MidLevelException {
jaroslav@49
   561
     *         try {
jaroslav@49
   562
     *             d();
jaroslav@49
   563
     *         } catch(LowLevelException e) {
jaroslav@49
   564
     *             throw new MidLevelException(e);
jaroslav@49
   565
     *         }
jaroslav@49
   566
     *     }
jaroslav@49
   567
     *     static void d() throws LowLevelException {
jaroslav@49
   568
     *        e();
jaroslav@49
   569
     *     }
jaroslav@49
   570
     *     static void e() throws LowLevelException {
jaroslav@49
   571
     *         throw new LowLevelException();
jaroslav@49
   572
     *     }
jaroslav@49
   573
     * }
jaroslav@49
   574
     *
jaroslav@49
   575
     * class HighLevelException extends Exception {
jaroslav@49
   576
     *     HighLevelException(Throwable cause) { super(cause); }
jaroslav@49
   577
     * }
jaroslav@49
   578
     *
jaroslav@49
   579
     * class MidLevelException extends Exception {
jaroslav@49
   580
     *     MidLevelException(Throwable cause)  { super(cause); }
jaroslav@49
   581
     * }
jaroslav@49
   582
     *
jaroslav@49
   583
     * class LowLevelException extends Exception {
jaroslav@49
   584
     * }
jaroslav@49
   585
     * </pre>
jaroslav@49
   586
     * As of release 7, the platform supports the notion of
jaroslav@49
   587
     * <i>suppressed exceptions</i> (in conjunction with the {@code
jaroslav@49
   588
     * try}-with-resources statement). Any exceptions that were
jaroslav@49
   589
     * suppressed in order to deliver an exception are printed out
jaroslav@49
   590
     * beneath the stack trace.  The format of this information
jaroslav@49
   591
     * depends on the implementation, but the following example may be
jaroslav@49
   592
     * regarded as typical:
jaroslav@49
   593
     *
jaroslav@49
   594
     * <pre>
jaroslav@49
   595
     * Exception in thread "main" java.lang.Exception: Something happened
jaroslav@49
   596
     *  at Foo.bar(Foo.java:10)
jaroslav@49
   597
     *  at Foo.main(Foo.java:5)
jaroslav@49
   598
     *  Suppressed: Resource$CloseFailException: Resource ID = 0
jaroslav@49
   599
     *          at Resource.close(Resource.java:26)
jaroslav@49
   600
     *          at Foo.bar(Foo.java:9)
jaroslav@49
   601
     *          ... 1 more
jaroslav@49
   602
     * </pre>
jaroslav@49
   603
     * Note that the "... n more" notation is used on suppressed exceptions
jaroslav@49
   604
     * just at it is used on causes. Unlike causes, suppressed exceptions are
jaroslav@49
   605
     * indented beyond their "containing exceptions."
jaroslav@49
   606
     *
jaroslav@49
   607
     * <p>An exception can have both a cause and one or more suppressed
jaroslav@49
   608
     * exceptions:
jaroslav@49
   609
     * <pre>
jaroslav@49
   610
     * Exception in thread "main" java.lang.Exception: Main block
jaroslav@49
   611
     *  at Foo3.main(Foo3.java:7)
jaroslav@49
   612
     *  Suppressed: Resource$CloseFailException: Resource ID = 2
jaroslav@49
   613
     *          at Resource.close(Resource.java:26)
jaroslav@49
   614
     *          at Foo3.main(Foo3.java:5)
jaroslav@49
   615
     *  Suppressed: Resource$CloseFailException: Resource ID = 1
jaroslav@49
   616
     *          at Resource.close(Resource.java:26)
jaroslav@49
   617
     *          at Foo3.main(Foo3.java:5)
jaroslav@49
   618
     * Caused by: java.lang.Exception: I did it
jaroslav@49
   619
     *  at Foo3.main(Foo3.java:8)
jaroslav@49
   620
     * </pre>
jaroslav@49
   621
     * Likewise, a suppressed exception can have a cause:
jaroslav@49
   622
     * <pre>
jaroslav@49
   623
     * Exception in thread "main" java.lang.Exception: Main block
jaroslav@49
   624
     *  at Foo4.main(Foo4.java:6)
jaroslav@49
   625
     *  Suppressed: Resource2$CloseFailException: Resource ID = 1
jaroslav@49
   626
     *          at Resource2.close(Resource2.java:20)
jaroslav@49
   627
     *          at Foo4.main(Foo4.java:5)
jaroslav@49
   628
     *  Caused by: java.lang.Exception: Rats, you caught me
jaroslav@49
   629
     *          at Resource2$CloseFailException.<init>(Resource2.java:45)
jaroslav@49
   630
     *          ... 2 more
jaroslav@49
   631
     * </pre>
jaroslav@49
   632
     */
jaroslav@83
   633
//    public void printStackTrace() {
jaroslav@83
   634
//        printStackTrace(System.err);
jaroslav@83
   635
//    }
jaroslav@83
   636
//
jaroslav@83
   637
//    /**
jaroslav@83
   638
//     * Prints this throwable and its backtrace to the specified print stream.
jaroslav@83
   639
//     *
jaroslav@83
   640
//     * @param s {@code PrintStream} to use for output
jaroslav@83
   641
//     */
jaroslav@83
   642
//    public void printStackTrace(PrintStream s) {
jaroslav@83
   643
//        printStackTrace(new WrappedPrintStream(s));
jaroslav@83
   644
//    }
jaroslav@83
   645
//
jaroslav@83
   646
//    private void printStackTrace(PrintStreamOrWriter s) {
jaroslav@83
   647
//        // Guard against malicious overrides of Throwable.equals by
jaroslav@83
   648
//        // using a Set with identity equality semantics.
jaroslav@83
   649
////        Set<Throwable> dejaVu =
jaroslav@83
   650
////            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
jaroslav@83
   651
////        dejaVu.add(this);
jaroslav@83
   652
//
jaroslav@83
   653
//        synchronized (s.lock()) {
jaroslav@83
   654
//            // Print our stack trace
jaroslav@83
   655
//            s.println(this);
jaroslav@83
   656
//            StackTraceElement[] trace = getOurStackTrace();
jaroslav@83
   657
//            for (StackTraceElement traceElement : trace)
jaroslav@83
   658
//                s.println("\tat " + traceElement);
jaroslav@83
   659
//
jaroslav@83
   660
//            // Print suppressed exceptions, if any
jaroslav@83
   661
////            for (Throwable se : getSuppressed())
jaroslav@83
   662
////                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
jaroslav@83
   663
//
jaroslav@83
   664
//            // Print cause, if any
jaroslav@83
   665
//            Throwable ourCause = getCause();
jaroslav@83
   666
////            if (ourCause != null)
jaroslav@83
   667
////                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
jaroslav@83
   668
//        }
jaroslav@83
   669
//    }
jaroslav@83
   670
//
jaroslav@83
   671
//    /**
jaroslav@83
   672
//     * Print our stack trace as an enclosed exception for the specified
jaroslav@83
   673
//     * stack trace.
jaroslav@83
   674
//     */
jaroslav@83
   675
//    private void printEnclosedStackTrace(PrintStreamOrWriter s,
jaroslav@83
   676
//                                         StackTraceElement[] enclosingTrace,
jaroslav@83
   677
//                                         String caption,
jaroslav@83
   678
//                                         String prefix,
jaroslav@83
   679
//                                         Object dejaVu) {
jaroslav@83
   680
//        assert Thread.holdsLock(s.lock());
jaroslav@83
   681
//        {
jaroslav@83
   682
//            // Compute number of frames in common between this and enclosing trace
jaroslav@83
   683
//            StackTraceElement[] trace = getOurStackTrace();
jaroslav@83
   684
//            int m = trace.length - 1;
jaroslav@83
   685
//            int n = enclosingTrace.length - 1;
jaroslav@83
   686
//            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
jaroslav@83
   687
//                m--; n--;
jaroslav@83
   688
//            }
jaroslav@83
   689
//            int framesInCommon = trace.length - 1 - m;
jaroslav@83
   690
//
jaroslav@83
   691
//            // Print our stack trace
jaroslav@83
   692
//            s.println(prefix + caption + this);
jaroslav@83
   693
//            for (int i = 0; i <= m; i++)
jaroslav@83
   694
//                s.println(prefix + "\tat " + trace[i]);
jaroslav@83
   695
//            if (framesInCommon != 0)
jaroslav@83
   696
//                s.println(prefix + "\t... " + framesInCommon + " more");
jaroslav@83
   697
//
jaroslav@83
   698
//            // Print suppressed exceptions, if any
jaroslav@61
   699
//            for (Throwable se : getSuppressed())
jaroslav@83
   700
//                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
jaroslav@83
   701
//                                           prefix +"\t", dejaVu);
jaroslav@83
   702
//
jaroslav@83
   703
//            // Print cause, if any
jaroslav@83
   704
//            Throwable ourCause = getCause();
jaroslav@61
   705
//            if (ourCause != null)
jaroslav@83
   706
//                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
jaroslav@83
   707
//        }
jaroslav@83
   708
//    }
jaroslav@83
   709
//
jaroslav@83
   710
//    /**
jaroslav@83
   711
//     * Prints this throwable and its backtrace to the specified
jaroslav@83
   712
//     * print writer.
jaroslav@83
   713
//     *
jaroslav@83
   714
//     * @param s {@code PrintWriter} to use for output
jaroslav@83
   715
//     * @since   JDK1.1
jaroslav@83
   716
//     */
jaroslav@83
   717
//    public void printStackTrace(PrintWriter s) {
jaroslav@83
   718
//        printStackTrace(new WrappedPrintWriter(s));
jaroslav@83
   719
//    }
jaroslav@83
   720
//
jaroslav@83
   721
//    /**
jaroslav@83
   722
//     * Wrapper class for PrintStream and PrintWriter to enable a single
jaroslav@83
   723
//     * implementation of printStackTrace.
jaroslav@83
   724
//     */
jaroslav@83
   725
//    private abstract static class PrintStreamOrWriter {
jaroslav@83
   726
//        /** Returns the object to be locked when using this StreamOrWriter */
jaroslav@83
   727
//        abstract Object lock();
jaroslav@83
   728
//
jaroslav@83
   729
//        /** Prints the specified string as a line on this StreamOrWriter */
jaroslav@83
   730
//        abstract void println(Object o);
jaroslav@83
   731
//    }
jaroslav@83
   732
//
jaroslav@83
   733
//    private static class WrappedPrintStream extends PrintStreamOrWriter {
jaroslav@83
   734
//        private final PrintStream printStream;
jaroslav@83
   735
//
jaroslav@83
   736
//        WrappedPrintStream(PrintStream printStream) {
jaroslav@83
   737
//            this.printStream = printStream;
jaroslav@83
   738
//        }
jaroslav@83
   739
//
jaroslav@83
   740
//        Object lock() {
jaroslav@83
   741
//            return printStream;
jaroslav@83
   742
//        }
jaroslav@83
   743
//
jaroslav@83
   744
//        void println(Object o) {
jaroslav@83
   745
//            printStream.println(o);
jaroslav@83
   746
//        }
jaroslav@83
   747
//    }
jaroslav@83
   748
//
jaroslav@83
   749
//    private static class WrappedPrintWriter extends PrintStreamOrWriter {
jaroslav@83
   750
//        private final PrintWriter printWriter;
jaroslav@83
   751
//
jaroslav@83
   752
//        WrappedPrintWriter(PrintWriter printWriter) {
jaroslav@83
   753
//            this.printWriter = printWriter;
jaroslav@83
   754
//        }
jaroslav@83
   755
//
jaroslav@83
   756
//        Object lock() {
jaroslav@83
   757
//            return printWriter;
jaroslav@83
   758
//        }
jaroslav@83
   759
//
jaroslav@83
   760
//        void println(Object o) {
jaroslav@83
   761
//            printWriter.println(o);
jaroslav@83
   762
//        }
jaroslav@83
   763
//    }
jaroslav@49
   764
jaroslav@49
   765
    /**
jaroslav@49
   766
     * Fills in the execution stack trace. This method records within this
jaroslav@49
   767
     * {@code Throwable} object information about the current state of
jaroslav@49
   768
     * the stack frames for the current thread.
jaroslav@49
   769
     *
jaroslav@49
   770
     * <p>If the stack trace of this {@code Throwable} {@linkplain
jaroslav@49
   771
     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
jaroslav@49
   772
     * writable}, calling this method has no effect.
jaroslav@49
   773
     *
jaroslav@49
   774
     * @return  a reference to this {@code Throwable} instance.
jaroslav@49
   775
     * @see     java.lang.Throwable#printStackTrace()
jaroslav@49
   776
     */
jaroslav@49
   777
    public synchronized Throwable fillInStackTrace() {
jaroslav@49
   778
        if (stackTrace != null ||
jaroslav@49
   779
            backtrace != null /* Out of protocol state */ ) {
jaroslav@49
   780
            fillInStackTrace(0);
jaroslav@49
   781
            stackTrace = UNASSIGNED_STACK;
jaroslav@49
   782
        }
jaroslav@49
   783
        return this;
jaroslav@49
   784
    }
jaroslav@49
   785
jaroslav@443
   786
    @JavaScriptBody(args = { "dummy" }, body = "")
jaroslav@49
   787
    private native Throwable fillInStackTrace(int dummy);
jaroslav@49
   788
jaroslav@49
   789
    /**
jaroslav@49
   790
     * Provides programmatic access to the stack trace information printed by
jaroslav@49
   791
     * {@link #printStackTrace()}.  Returns an array of stack trace elements,
jaroslav@49
   792
     * each representing one stack frame.  The zeroth element of the array
jaroslav@49
   793
     * (assuming the array's length is non-zero) represents the top of the
jaroslav@49
   794
     * stack, which is the last method invocation in the sequence.  Typically,
jaroslav@49
   795
     * this is the point at which this throwable was created and thrown.
jaroslav@49
   796
     * The last element of the array (assuming the array's length is non-zero)
jaroslav@49
   797
     * represents the bottom of the stack, which is the first method invocation
jaroslav@49
   798
     * in the sequence.
jaroslav@49
   799
     *
jaroslav@49
   800
     * <p>Some virtual machines may, under some circumstances, omit one
jaroslav@49
   801
     * or more stack frames from the stack trace.  In the extreme case,
jaroslav@49
   802
     * a virtual machine that has no stack trace information concerning
jaroslav@49
   803
     * this throwable is permitted to return a zero-length array from this
jaroslav@49
   804
     * method.  Generally speaking, the array returned by this method will
jaroslav@49
   805
     * contain one element for every frame that would be printed by
jaroslav@49
   806
     * {@code printStackTrace}.  Writes to the returned array do not
jaroslav@49
   807
     * affect future calls to this method.
jaroslav@49
   808
     *
jaroslav@49
   809
     * @return an array of stack trace elements representing the stack trace
jaroslav@49
   810
     *         pertaining to this throwable.
jaroslav@49
   811
     * @since  1.4
jaroslav@49
   812
     */
jaroslav@49
   813
    public StackTraceElement[] getStackTrace() {
jaroslav@49
   814
        return getOurStackTrace().clone();
jaroslav@49
   815
    }
jaroslav@49
   816
jaroslav@49
   817
    private synchronized StackTraceElement[] getOurStackTrace() {
jaroslav@49
   818
        // Initialize stack trace field with information from
jaroslav@49
   819
        // backtrace if this is the first call to this method
jaroslav@49
   820
        if (stackTrace == UNASSIGNED_STACK ||
jaroslav@49
   821
            (stackTrace == null && backtrace != null) /* Out of protocol state */) {
jaroslav@49
   822
            int depth = getStackTraceDepth();
jaroslav@49
   823
            stackTrace = new StackTraceElement[depth];
jaroslav@49
   824
            for (int i=0; i < depth; i++)
jaroslav@49
   825
                stackTrace[i] = getStackTraceElement(i);
jaroslav@49
   826
        } else if (stackTrace == null) {
jaroslav@49
   827
            return UNASSIGNED_STACK;
jaroslav@49
   828
        }
jaroslav@49
   829
        return stackTrace;
jaroslav@49
   830
    }
jaroslav@49
   831
jaroslav@49
   832
    /**
jaroslav@49
   833
     * Sets the stack trace elements that will be returned by
jaroslav@49
   834
     * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
jaroslav@49
   835
     * and related methods.
jaroslav@49
   836
     *
jaroslav@49
   837
     * This method, which is designed for use by RPC frameworks and other
jaroslav@49
   838
     * advanced systems, allows the client to override the default
jaroslav@49
   839
     * stack trace that is either generated by {@link #fillInStackTrace()}
jaroslav@49
   840
     * when a throwable is constructed or deserialized when a throwable is
jaroslav@49
   841
     * read from a serialization stream.
jaroslav@49
   842
     *
jaroslav@49
   843
     * <p>If the stack trace of this {@code Throwable} {@linkplain
jaroslav@49
   844
     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
jaroslav@49
   845
     * writable}, calling this method has no effect other than
jaroslav@49
   846
     * validating its argument.
jaroslav@49
   847
     *
jaroslav@49
   848
     * @param   stackTrace the stack trace elements to be associated with
jaroslav@49
   849
     * this {@code Throwable}.  The specified array is copied by this
jaroslav@49
   850
     * call; changes in the specified array after the method invocation
jaroslav@49
   851
     * returns will have no affect on this {@code Throwable}'s stack
jaroslav@49
   852
     * trace.
jaroslav@49
   853
     *
jaroslav@49
   854
     * @throws NullPointerException if {@code stackTrace} is
jaroslav@49
   855
     *         {@code null} or if any of the elements of
jaroslav@49
   856
     *         {@code stackTrace} are {@code null}
jaroslav@49
   857
     *
jaroslav@49
   858
     * @since  1.4
jaroslav@49
   859
     */
jaroslav@49
   860
    public void setStackTrace(StackTraceElement[] stackTrace) {
jaroslav@49
   861
        // Validate argument
jaroslav@49
   862
        StackTraceElement[] defensiveCopy = stackTrace.clone();
jaroslav@49
   863
        for (int i = 0; i < defensiveCopy.length; i++) {
jaroslav@49
   864
            if (defensiveCopy[i] == null)
jaroslav@49
   865
                throw new NullPointerException("stackTrace[" + i + "]");
jaroslav@49
   866
        }
jaroslav@49
   867
jaroslav@49
   868
        synchronized (this) {
jaroslav@49
   869
            if (this.stackTrace == null && // Immutable stack
jaroslav@49
   870
                backtrace == null) // Test for out of protocol state
jaroslav@49
   871
                return;
jaroslav@49
   872
            this.stackTrace = defensiveCopy;
jaroslav@49
   873
        }
jaroslav@49
   874
    }
jaroslav@49
   875
jaroslav@49
   876
    /**
jaroslav@49
   877
     * Returns the number of elements in the stack trace (or 0 if the stack
jaroslav@49
   878
     * trace is unavailable).
jaroslav@49
   879
     *
jaroslav@49
   880
     * package-protection for use by SharedSecrets.
jaroslav@49
   881
     */
jaroslav@49
   882
    native int getStackTraceDepth();
jaroslav@49
   883
jaroslav@49
   884
    /**
jaroslav@49
   885
     * Returns the specified element of the stack trace.
jaroslav@49
   886
     *
jaroslav@49
   887
     * package-protection for use by SharedSecrets.
jaroslav@49
   888
     *
jaroslav@49
   889
     * @param index index of the element to return.
jaroslav@49
   890
     * @throws IndexOutOfBoundsException if {@code index < 0 ||
jaroslav@49
   891
     *         index >= getStackTraceDepth() }
jaroslav@49
   892
     */
jaroslav@49
   893
    native StackTraceElement getStackTraceElement(int index);
jaroslav@49
   894
jaroslav@49
   895
    /**
jaroslav@49
   896
     * Reads a {@code Throwable} from a stream, enforcing
jaroslav@49
   897
     * well-formedness constraints on fields.  Null entries and
jaroslav@49
   898
     * self-pointers are not allowed in the list of {@code
jaroslav@49
   899
     * suppressedExceptions}.  Null entries are not allowed for stack
jaroslav@49
   900
     * trace elements.  A null stack trace in the serial form results
jaroslav@49
   901
     * in a zero-length stack element array. A single-element stack
jaroslav@49
   902
     * trace whose entry is equal to {@code new StackTraceElement("",
jaroslav@49
   903
     * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code
jaroslav@49
   904
     * stackTrace} field.
jaroslav@49
   905
     *
jaroslav@49
   906
     * Note that there are no constraints on the value the {@code
jaroslav@49
   907
     * cause} field can hold; both {@code null} and {@code this} are
jaroslav@49
   908
     * valid values for the field.
jaroslav@49
   909
     */
jaroslav@65
   910
//    private void readObject(ObjectInputStream s)
jaroslav@65
   911
//        throws IOException, ClassNotFoundException {
jaroslav@65
   912
//        s.defaultReadObject();     // read in all fields
jaroslav@61
   913
//        if (suppressedExceptions != null) {
jaroslav@61
   914
//            List<Throwable> suppressed = null;
jaroslav@61
   915
//            if (suppressedExceptions.isEmpty()) {
jaroslav@61
   916
//                // Use the sentinel for a zero-length list
jaroslav@61
   917
//                suppressed = SUPPRESSED_SENTINEL;
jaroslav@61
   918
//            } else { // Copy Throwables to new list
jaroslav@61
   919
//                suppressed = new ArrayList<Throwable>(1);
jaroslav@61
   920
//                for (Throwable t : suppressedExceptions) {
jaroslav@61
   921
//                    // Enforce constraints on suppressed exceptions in
jaroslav@61
   922
//                    // case of corrupt or malicious stream.
jaroslav@61
   923
//                    if (t == null)
jaroslav@61
   924
//                        throw new NullPointerException(NULL_CAUSE_MESSAGE);
jaroslav@61
   925
//                    if (t == this)
jaroslav@61
   926
//                        throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
jaroslav@61
   927
//                    suppressed.add(t);
jaroslav@61
   928
//                }
jaroslav@61
   929
//            }
jaroslav@61
   930
//            suppressedExceptions = suppressed;
jaroslav@61
   931
//        } // else a null suppressedExceptions field remains null
jaroslav@65
   932
//
jaroslav@65
   933
//        /*
jaroslav@65
   934
//         * For zero-length stack traces, use a clone of
jaroslav@65
   935
//         * UNASSIGNED_STACK rather than UNASSIGNED_STACK itself to
jaroslav@65
   936
//         * allow identity comparison against UNASSIGNED_STACK in
jaroslav@65
   937
//         * getOurStackTrace.  The identity of UNASSIGNED_STACK in
jaroslav@65
   938
//         * stackTrace indicates to the getOurStackTrace method that
jaroslav@65
   939
//         * the stackTrace needs to be constructed from the information
jaroslav@65
   940
//         * in backtrace.
jaroslav@65
   941
//         */
jaroslav@65
   942
//        if (stackTrace != null) {
jaroslav@65
   943
//            if (stackTrace.length == 0) {
jaroslav@65
   944
//                stackTrace = UNASSIGNED_STACK.clone();
jaroslav@65
   945
//            }  else if (stackTrace.length == 1 &&
jaroslav@65
   946
//                        // Check for the marker of an immutable stack trace
jaroslav@65
   947
//                        SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
jaroslav@65
   948
//                stackTrace = null;
jaroslav@65
   949
//            } else { // Verify stack trace elements are non-null.
jaroslav@65
   950
//                for(StackTraceElement ste : stackTrace) {
jaroslav@65
   951
//                    if (ste == null)
jaroslav@65
   952
//                        throw new NullPointerException("null StackTraceElement in serial stream. ");
jaroslav@65
   953
//                }
jaroslav@65
   954
//            }
jaroslav@65
   955
//        } else {
jaroslav@65
   956
//            // A null stackTrace field in the serial form can result
jaroslav@65
   957
//            // from an exception serialized without that field in
jaroslav@65
   958
//            // older JDK releases; treat such exceptions as having
jaroslav@65
   959
//            // empty stack traces.
jaroslav@65
   960
//            stackTrace = UNASSIGNED_STACK.clone();
jaroslav@65
   961
//        }
jaroslav@65
   962
//    }
jaroslav@49
   963
jaroslav@49
   964
    /**
jaroslav@49
   965
     * Write a {@code Throwable} object to a stream.
jaroslav@49
   966
     *
jaroslav@49
   967
     * A {@code null} stack trace field is represented in the serial
jaroslav@49
   968
     * form as a one-element array whose element is equal to {@code
jaroslav@49
   969
     * new StackTraceElement("", "", null, Integer.MIN_VALUE)}.
jaroslav@49
   970
     */
jaroslav@83
   971
//    private synchronized void writeObject(ObjectOutputStream s)
jaroslav@83
   972
//        throws IOException {
jaroslav@83
   973
//        // Ensure that the stackTrace field is initialized to a
jaroslav@83
   974
//        // non-null value, if appropriate.  As of JDK 7, a null stack
jaroslav@83
   975
//        // trace field is a valid value indicating the stack trace
jaroslav@83
   976
//        // should not be set.
jaroslav@83
   977
//        getOurStackTrace();
jaroslav@83
   978
//
jaroslav@83
   979
//        StackTraceElement[] oldStackTrace = stackTrace;
jaroslav@83
   980
//        try {
jaroslav@83
   981
//            if (stackTrace == null)
jaroslav@83
   982
//                stackTrace = SentinelHolder.STACK_TRACE_SENTINEL;
jaroslav@83
   983
//            s.defaultWriteObject();
jaroslav@83
   984
//        } finally {
jaroslav@83
   985
//            stackTrace = oldStackTrace;
jaroslav@83
   986
//        }
jaroslav@83
   987
//    }
jaroslav@49
   988
jaroslav@49
   989
    /**
jaroslav@49
   990
     * Appends the specified exception to the exceptions that were
jaroslav@49
   991
     * suppressed in order to deliver this exception. This method is
jaroslav@49
   992
     * thread-safe and typically called (automatically and implicitly)
jaroslav@49
   993
     * by the {@code try}-with-resources statement.
jaroslav@49
   994
     *
jaroslav@49
   995
     * <p>The suppression behavior is enabled <em>unless</em> disabled
jaroslav@49
   996
     * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
jaroslav@49
   997
     * a constructor}.  When suppression is disabled, this method does
jaroslav@49
   998
     * nothing other than to validate its argument.
jaroslav@49
   999
     *
jaroslav@49
  1000
     * <p>Note that when one exception {@linkplain
jaroslav@49
  1001
     * #initCause(Throwable) causes} another exception, the first
jaroslav@49
  1002
     * exception is usually caught and then the second exception is
jaroslav@49
  1003
     * thrown in response.  In other words, there is a causal
jaroslav@49
  1004
     * connection between the two exceptions.
jaroslav@49
  1005
     *
jaroslav@49
  1006
     * In contrast, there are situations where two independent
jaroslav@49
  1007
     * exceptions can be thrown in sibling code blocks, in particular
jaroslav@49
  1008
     * in the {@code try} block of a {@code try}-with-resources
jaroslav@49
  1009
     * statement and the compiler-generated {@code finally} block
jaroslav@49
  1010
     * which closes the resource.
jaroslav@49
  1011
     *
jaroslav@49
  1012
     * In these situations, only one of the thrown exceptions can be
jaroslav@49
  1013
     * propagated.  In the {@code try}-with-resources statement, when
jaroslav@49
  1014
     * there are two such exceptions, the exception originating from
jaroslav@49
  1015
     * the {@code try} block is propagated and the exception from the
jaroslav@49
  1016
     * {@code finally} block is added to the list of exceptions
jaroslav@49
  1017
     * suppressed by the exception from the {@code try} block.  As an
jaroslav@49
  1018
     * exception unwinds the stack, it can accumulate multiple
jaroslav@49
  1019
     * suppressed exceptions.
jaroslav@49
  1020
     *
jaroslav@49
  1021
     * <p>An exception may have suppressed exceptions while also being
jaroslav@49
  1022
     * caused by another exception.  Whether or not an exception has a
jaroslav@49
  1023
     * cause is semantically known at the time of its creation, unlike
jaroslav@49
  1024
     * whether or not an exception will suppress other exceptions
jaroslav@49
  1025
     * which is typically only determined after an exception is
jaroslav@49
  1026
     * thrown.
jaroslav@49
  1027
     *
jaroslav@49
  1028
     * <p>Note that programmer written code is also able to take
jaroslav@49
  1029
     * advantage of calling this method in situations where there are
jaroslav@49
  1030
     * multiple sibling exceptions and only one can be propagated.
jaroslav@49
  1031
     *
jaroslav@49
  1032
     * @param exception the exception to be added to the list of
jaroslav@49
  1033
     *        suppressed exceptions
jaroslav@49
  1034
     * @throws IllegalArgumentException if {@code exception} is this
jaroslav@49
  1035
     *         throwable; a throwable cannot suppress itself.
jaroslav@49
  1036
     * @throws NullPointerException if {@code exception} is {@code null}
jaroslav@49
  1037
     * @since 1.7
jaroslav@49
  1038
     */
jaroslav@49
  1039
    public final synchronized void addSuppressed(Throwable exception) {
jaroslav@49
  1040
        if (exception == this)
jaroslav@49
  1041
            throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
jaroslav@49
  1042
jaroslav@49
  1043
        if (exception == null)
jaroslav@49
  1044
            throw new NullPointerException(NULL_CAUSE_MESSAGE);
jaroslav@49
  1045
jaroslav@61
  1046
//        if (suppressedExceptions == null) // Suppressed exceptions not recorded
jaroslav@61
  1047
//            return;
jaroslav@61
  1048
//
jaroslav@61
  1049
//        if (suppressedExceptions == SUPPRESSED_SENTINEL)
jaroslav@61
  1050
//            suppressedExceptions = new ArrayList<Throwable>(1);
jaroslav@61
  1051
//
jaroslav@61
  1052
//        suppressedExceptions.add(exception);
jaroslav@49
  1053
    }
jaroslav@49
  1054
jaroslav@49
  1055
    private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
jaroslav@49
  1056
jaroslav@49
  1057
    /**
jaroslav@49
  1058
     * Returns an array containing all of the exceptions that were
jaroslav@49
  1059
     * suppressed, typically by the {@code try}-with-resources
jaroslav@49
  1060
     * statement, in order to deliver this exception.
jaroslav@49
  1061
     *
jaroslav@49
  1062
     * If no exceptions were suppressed or {@linkplain
jaroslav@49
  1063
     * #Throwable(String, Throwable, boolean, boolean) suppression is
jaroslav@49
  1064
     * disabled}, an empty array is returned.  This method is
jaroslav@49
  1065
     * thread-safe.  Writes to the returned array do not affect future
jaroslav@49
  1066
     * calls to this method.
jaroslav@49
  1067
     *
jaroslav@49
  1068
     * @return an array containing all of the exceptions that were
jaroslav@49
  1069
     *         suppressed to deliver this exception.
jaroslav@49
  1070
     * @since 1.7
jaroslav@49
  1071
     */
jaroslav@49
  1072
    public final synchronized Throwable[] getSuppressed() {
jaroslav@61
  1073
        return new Throwable[0];
jaroslav@61
  1074
//        if (suppressedExceptions == SUPPRESSED_SENTINEL ||
jaroslav@61
  1075
//            suppressedExceptions == null)
jaroslav@61
  1076
//            return EMPTY_THROWABLE_ARRAY;
jaroslav@61
  1077
//        else
jaroslav@61
  1078
//            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
jaroslav@49
  1079
    }
jaroslav@49
  1080
}