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