emul/mini/src/main/java/java/lang/Throwable.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 26 Jan 2013 08:47:05 +0100
changeset 592 5e13b1ac2886
parent 502 a5cd79ee1d96
permissions -rw-r--r--
In order to support fields of the same name in subclasses we are now prefixing them with name of the class that defines them. To provide convenient way to access them from generated bytecode and also directly from JavaScript, there is a getter/setter function for each field. It starts with _ followed by the field name. If called with a parameter, it sets the field, with a parameter it just returns it.
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@83
   641
//    public void printStackTrace() {
jaroslav@83
   642
//        printStackTrace(System.err);
jaroslav@83
   643
//    }
jaroslav@83
   644
//
jaroslav@83
   645
//    /**
jaroslav@83
   646
//     * Prints this throwable and its backtrace to the specified print stream.
jaroslav@83
   647
//     *
jaroslav@83
   648
//     * @param s {@code PrintStream} to use for output
jaroslav@83
   649
//     */
jaroslav@83
   650
//    public void printStackTrace(PrintStream s) {
jaroslav@83
   651
//        printStackTrace(new WrappedPrintStream(s));
jaroslav@83
   652
//    }
jaroslav@83
   653
//
jaroslav@83
   654
//    private void printStackTrace(PrintStreamOrWriter s) {
jaroslav@83
   655
//        // Guard against malicious overrides of Throwable.equals by
jaroslav@83
   656
//        // using a Set with identity equality semantics.
jaroslav@83
   657
////        Set<Throwable> dejaVu =
jaroslav@83
   658
////            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
jaroslav@83
   659
////        dejaVu.add(this);
jaroslav@83
   660
//
jaroslav@83
   661
//        synchronized (s.lock()) {
jaroslav@83
   662
//            // Print our stack trace
jaroslav@83
   663
//            s.println(this);
jaroslav@83
   664
//            StackTraceElement[] trace = getOurStackTrace();
jaroslav@83
   665
//            for (StackTraceElement traceElement : trace)
jaroslav@83
   666
//                s.println("\tat " + traceElement);
jaroslav@83
   667
//
jaroslav@83
   668
//            // Print suppressed exceptions, if any
jaroslav@83
   669
////            for (Throwable se : getSuppressed())
jaroslav@83
   670
////                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
jaroslav@83
   671
//
jaroslav@83
   672
//            // Print cause, if any
jaroslav@83
   673
//            Throwable ourCause = getCause();
jaroslav@83
   674
////            if (ourCause != null)
jaroslav@83
   675
////                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
jaroslav@83
   676
//        }
jaroslav@83
   677
//    }
jaroslav@83
   678
//
jaroslav@83
   679
//    /**
jaroslav@83
   680
//     * Print our stack trace as an enclosed exception for the specified
jaroslav@83
   681
//     * stack trace.
jaroslav@83
   682
//     */
jaroslav@83
   683
//    private void printEnclosedStackTrace(PrintStreamOrWriter s,
jaroslav@83
   684
//                                         StackTraceElement[] enclosingTrace,
jaroslav@83
   685
//                                         String caption,
jaroslav@83
   686
//                                         String prefix,
jaroslav@83
   687
//                                         Object dejaVu) {
jaroslav@83
   688
//        assert Thread.holdsLock(s.lock());
jaroslav@83
   689
//        {
jaroslav@83
   690
//            // Compute number of frames in common between this and enclosing trace
jaroslav@83
   691
//            StackTraceElement[] trace = getOurStackTrace();
jaroslav@83
   692
//            int m = trace.length - 1;
jaroslav@83
   693
//            int n = enclosingTrace.length - 1;
jaroslav@83
   694
//            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
jaroslav@83
   695
//                m--; n--;
jaroslav@83
   696
//            }
jaroslav@83
   697
//            int framesInCommon = trace.length - 1 - m;
jaroslav@83
   698
//
jaroslav@83
   699
//            // Print our stack trace
jaroslav@83
   700
//            s.println(prefix + caption + this);
jaroslav@83
   701
//            for (int i = 0; i <= m; i++)
jaroslav@83
   702
//                s.println(prefix + "\tat " + trace[i]);
jaroslav@83
   703
//            if (framesInCommon != 0)
jaroslav@83
   704
//                s.println(prefix + "\t... " + framesInCommon + " more");
jaroslav@83
   705
//
jaroslav@83
   706
//            // Print suppressed exceptions, if any
jaroslav@61
   707
//            for (Throwable se : getSuppressed())
jaroslav@83
   708
//                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
jaroslav@83
   709
//                                           prefix +"\t", dejaVu);
jaroslav@83
   710
//
jaroslav@83
   711
//            // Print cause, if any
jaroslav@83
   712
//            Throwable ourCause = getCause();
jaroslav@61
   713
//            if (ourCause != null)
jaroslav@83
   714
//                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
jaroslav@83
   715
//        }
jaroslav@83
   716
//    }
jaroslav@83
   717
//
jaroslav@83
   718
//    /**
jaroslav@83
   719
//     * Prints this throwable and its backtrace to the specified
jaroslav@83
   720
//     * print writer.
jaroslav@83
   721
//     *
jaroslav@83
   722
//     * @param s {@code PrintWriter} to use for output
jaroslav@83
   723
//     * @since   JDK1.1
jaroslav@83
   724
//     */
jaroslav@83
   725
//    public void printStackTrace(PrintWriter s) {
jaroslav@83
   726
//        printStackTrace(new WrappedPrintWriter(s));
jaroslav@83
   727
//    }
jaroslav@83
   728
//
jaroslav@83
   729
//    /**
jaroslav@83
   730
//     * Wrapper class for PrintStream and PrintWriter to enable a single
jaroslav@83
   731
//     * implementation of printStackTrace.
jaroslav@83
   732
//     */
jaroslav@83
   733
//    private abstract static class PrintStreamOrWriter {
jaroslav@83
   734
//        /** Returns the object to be locked when using this StreamOrWriter */
jaroslav@83
   735
//        abstract Object lock();
jaroslav@83
   736
//
jaroslav@83
   737
//        /** Prints the specified string as a line on this StreamOrWriter */
jaroslav@83
   738
//        abstract void println(Object o);
jaroslav@83
   739
//    }
jaroslav@83
   740
//
jaroslav@83
   741
//    private static class WrappedPrintStream extends PrintStreamOrWriter {
jaroslav@83
   742
//        private final PrintStream printStream;
jaroslav@83
   743
//
jaroslav@83
   744
//        WrappedPrintStream(PrintStream printStream) {
jaroslav@83
   745
//            this.printStream = printStream;
jaroslav@83
   746
//        }
jaroslav@83
   747
//
jaroslav@83
   748
//        Object lock() {
jaroslav@83
   749
//            return printStream;
jaroslav@83
   750
//        }
jaroslav@83
   751
//
jaroslav@83
   752
//        void println(Object o) {
jaroslav@83
   753
//            printStream.println(o);
jaroslav@83
   754
//        }
jaroslav@83
   755
//    }
jaroslav@83
   756
//
jaroslav@83
   757
//    private static class WrappedPrintWriter extends PrintStreamOrWriter {
jaroslav@83
   758
//        private final PrintWriter printWriter;
jaroslav@83
   759
//
jaroslav@83
   760
//        WrappedPrintWriter(PrintWriter printWriter) {
jaroslav@83
   761
//            this.printWriter = printWriter;
jaroslav@83
   762
//        }
jaroslav@83
   763
//
jaroslav@83
   764
//        Object lock() {
jaroslav@83
   765
//            return printWriter;
jaroslav@83
   766
//        }
jaroslav@83
   767
//
jaroslav@83
   768
//        void println(Object o) {
jaroslav@83
   769
//            printWriter.println(o);
jaroslav@83
   770
//        }
jaroslav@83
   771
//    }
jaroslav@49
   772
jaroslav@49
   773
    /**
jaroslav@49
   774
     * Fills in the execution stack trace. This method records within this
jaroslav@49
   775
     * {@code Throwable} object information about the current state of
jaroslav@49
   776
     * the stack frames for the current thread.
jaroslav@49
   777
     *
jaroslav@49
   778
     * <p>If the stack trace of this {@code Throwable} {@linkplain
jaroslav@49
   779
     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
jaroslav@49
   780
     * writable}, calling this method has no effect.
jaroslav@49
   781
     *
jaroslav@49
   782
     * @return  a reference to this {@code Throwable} instance.
jaroslav@49
   783
     * @see     java.lang.Throwable#printStackTrace()
jaroslav@49
   784
     */
jaroslav@49
   785
    public synchronized Throwable fillInStackTrace() {
jaroslav@49
   786
        if (stackTrace != null ||
jaroslav@49
   787
            backtrace != null /* Out of protocol state */ ) {
jaroslav@49
   788
            fillInStackTrace(0);
jaroslav@49
   789
            stackTrace = UNASSIGNED_STACK;
jaroslav@49
   790
        }
jaroslav@49
   791
        return this;
jaroslav@49
   792
    }
jaroslav@49
   793
jaroslav@443
   794
    @JavaScriptBody(args = { "dummy" }, body = "")
jaroslav@49
   795
    private native Throwable fillInStackTrace(int dummy);
jaroslav@49
   796
jaroslav@49
   797
    /**
jaroslav@49
   798
     * Provides programmatic access to the stack trace information printed by
jaroslav@49
   799
     * {@link #printStackTrace()}.  Returns an array of stack trace elements,
jaroslav@49
   800
     * each representing one stack frame.  The zeroth element of the array
jaroslav@49
   801
     * (assuming the array's length is non-zero) represents the top of the
jaroslav@49
   802
     * stack, which is the last method invocation in the sequence.  Typically,
jaroslav@49
   803
     * this is the point at which this throwable was created and thrown.
jaroslav@49
   804
     * The last element of the array (assuming the array's length is non-zero)
jaroslav@49
   805
     * represents the bottom of the stack, which is the first method invocation
jaroslav@49
   806
     * in the sequence.
jaroslav@49
   807
     *
jaroslav@49
   808
     * <p>Some virtual machines may, under some circumstances, omit one
jaroslav@49
   809
     * or more stack frames from the stack trace.  In the extreme case,
jaroslav@49
   810
     * a virtual machine that has no stack trace information concerning
jaroslav@49
   811
     * this throwable is permitted to return a zero-length array from this
jaroslav@49
   812
     * method.  Generally speaking, the array returned by this method will
jaroslav@49
   813
     * contain one element for every frame that would be printed by
jaroslav@49
   814
     * {@code printStackTrace}.  Writes to the returned array do not
jaroslav@49
   815
     * affect future calls to this method.
jaroslav@49
   816
     *
jaroslav@49
   817
     * @return an array of stack trace elements representing the stack trace
jaroslav@49
   818
     *         pertaining to this throwable.
jaroslav@49
   819
     * @since  1.4
jaroslav@49
   820
     */
jaroslav@49
   821
    public StackTraceElement[] getStackTrace() {
jaroslav@49
   822
        return getOurStackTrace().clone();
jaroslav@49
   823
    }
jaroslav@49
   824
jaroslav@49
   825
    private synchronized StackTraceElement[] getOurStackTrace() {
jaroslav@49
   826
        // Initialize stack trace field with information from
jaroslav@49
   827
        // backtrace if this is the first call to this method
jaroslav@49
   828
        if (stackTrace == UNASSIGNED_STACK ||
jaroslav@49
   829
            (stackTrace == null && backtrace != null) /* Out of protocol state */) {
jaroslav@49
   830
            int depth = getStackTraceDepth();
jaroslav@49
   831
            stackTrace = new StackTraceElement[depth];
jaroslav@49
   832
            for (int i=0; i < depth; i++)
jaroslav@49
   833
                stackTrace[i] = getStackTraceElement(i);
jaroslav@49
   834
        } else if (stackTrace == null) {
jaroslav@49
   835
            return UNASSIGNED_STACK;
jaroslav@49
   836
        }
jaroslav@49
   837
        return stackTrace;
jaroslav@49
   838
    }
jaroslav@49
   839
jaroslav@49
   840
    /**
jaroslav@49
   841
     * Sets the stack trace elements that will be returned by
jaroslav@49
   842
     * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
jaroslav@49
   843
     * and related methods.
jaroslav@49
   844
     *
jaroslav@49
   845
     * This method, which is designed for use by RPC frameworks and other
jaroslav@49
   846
     * advanced systems, allows the client to override the default
jaroslav@49
   847
     * stack trace that is either generated by {@link #fillInStackTrace()}
jaroslav@49
   848
     * when a throwable is constructed or deserialized when a throwable is
jaroslav@49
   849
     * read from a serialization stream.
jaroslav@49
   850
     *
jaroslav@49
   851
     * <p>If the stack trace of this {@code Throwable} {@linkplain
jaroslav@49
   852
     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
jaroslav@49
   853
     * writable}, calling this method has no effect other than
jaroslav@49
   854
     * validating its argument.
jaroslav@49
   855
     *
jaroslav@49
   856
     * @param   stackTrace the stack trace elements to be associated with
jaroslav@49
   857
     * this {@code Throwable}.  The specified array is copied by this
jaroslav@49
   858
     * call; changes in the specified array after the method invocation
jaroslav@49
   859
     * returns will have no affect on this {@code Throwable}'s stack
jaroslav@49
   860
     * trace.
jaroslav@49
   861
     *
jaroslav@49
   862
     * @throws NullPointerException if {@code stackTrace} is
jaroslav@49
   863
     *         {@code null} or if any of the elements of
jaroslav@49
   864
     *         {@code stackTrace} are {@code null}
jaroslav@49
   865
     *
jaroslav@49
   866
     * @since  1.4
jaroslav@49
   867
     */
jaroslav@49
   868
    public void setStackTrace(StackTraceElement[] stackTrace) {
jaroslav@49
   869
        // Validate argument
jaroslav@49
   870
        StackTraceElement[] defensiveCopy = stackTrace.clone();
jaroslav@49
   871
        for (int i = 0; i < defensiveCopy.length; i++) {
jaroslav@49
   872
            if (defensiveCopy[i] == null)
jaroslav@49
   873
                throw new NullPointerException("stackTrace[" + i + "]");
jaroslav@49
   874
        }
jaroslav@49
   875
jaroslav@49
   876
        synchronized (this) {
jaroslav@49
   877
            if (this.stackTrace == null && // Immutable stack
jaroslav@49
   878
                backtrace == null) // Test for out of protocol state
jaroslav@49
   879
                return;
jaroslav@49
   880
            this.stackTrace = defensiveCopy;
jaroslav@49
   881
        }
jaroslav@49
   882
    }
jaroslav@49
   883
jaroslav@49
   884
    /**
jaroslav@49
   885
     * Returns the number of elements in the stack trace (or 0 if the stack
jaroslav@49
   886
     * trace is unavailable).
jaroslav@49
   887
     *
jaroslav@49
   888
     * package-protection for use by SharedSecrets.
jaroslav@49
   889
     */
jaroslav@49
   890
    native int getStackTraceDepth();
jaroslav@49
   891
jaroslav@49
   892
    /**
jaroslav@49
   893
     * Returns the specified element of the stack trace.
jaroslav@49
   894
     *
jaroslav@49
   895
     * package-protection for use by SharedSecrets.
jaroslav@49
   896
     *
jaroslav@49
   897
     * @param index index of the element to return.
jaroslav@49
   898
     * @throws IndexOutOfBoundsException if {@code index < 0 ||
jaroslav@49
   899
     *         index >= getStackTraceDepth() }
jaroslav@49
   900
     */
jaroslav@49
   901
    native StackTraceElement getStackTraceElement(int index);
jaroslav@49
   902
jaroslav@49
   903
    /**
jaroslav@49
   904
     * Reads a {@code Throwable} from a stream, enforcing
jaroslav@49
   905
     * well-formedness constraints on fields.  Null entries and
jaroslav@49
   906
     * self-pointers are not allowed in the list of {@code
jaroslav@49
   907
     * suppressedExceptions}.  Null entries are not allowed for stack
jaroslav@49
   908
     * trace elements.  A null stack trace in the serial form results
jaroslav@49
   909
     * in a zero-length stack element array. A single-element stack
jaroslav@49
   910
     * trace whose entry is equal to {@code new StackTraceElement("",
jaroslav@49
   911
     * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code
jaroslav@49
   912
     * stackTrace} field.
jaroslav@49
   913
     *
jaroslav@49
   914
     * Note that there are no constraints on the value the {@code
jaroslav@49
   915
     * cause} field can hold; both {@code null} and {@code this} are
jaroslav@49
   916
     * valid values for the field.
jaroslav@49
   917
     */
jaroslav@65
   918
//    private void readObject(ObjectInputStream s)
jaroslav@65
   919
//        throws IOException, ClassNotFoundException {
jaroslav@65
   920
//        s.defaultReadObject();     // read in all fields
jaroslav@61
   921
//        if (suppressedExceptions != null) {
jaroslav@61
   922
//            List<Throwable> suppressed = null;
jaroslav@61
   923
//            if (suppressedExceptions.isEmpty()) {
jaroslav@61
   924
//                // Use the sentinel for a zero-length list
jaroslav@61
   925
//                suppressed = SUPPRESSED_SENTINEL;
jaroslav@61
   926
//            } else { // Copy Throwables to new list
jaroslav@61
   927
//                suppressed = new ArrayList<Throwable>(1);
jaroslav@61
   928
//                for (Throwable t : suppressedExceptions) {
jaroslav@61
   929
//                    // Enforce constraints on suppressed exceptions in
jaroslav@61
   930
//                    // case of corrupt or malicious stream.
jaroslav@61
   931
//                    if (t == null)
jaroslav@61
   932
//                        throw new NullPointerException(NULL_CAUSE_MESSAGE);
jaroslav@61
   933
//                    if (t == this)
jaroslav@61
   934
//                        throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
jaroslav@61
   935
//                    suppressed.add(t);
jaroslav@61
   936
//                }
jaroslav@61
   937
//            }
jaroslav@61
   938
//            suppressedExceptions = suppressed;
jaroslav@61
   939
//        } // else a null suppressedExceptions field remains null
jaroslav@65
   940
//
jaroslav@65
   941
//        /*
jaroslav@65
   942
//         * For zero-length stack traces, use a clone of
jaroslav@65
   943
//         * UNASSIGNED_STACK rather than UNASSIGNED_STACK itself to
jaroslav@65
   944
//         * allow identity comparison against UNASSIGNED_STACK in
jaroslav@65
   945
//         * getOurStackTrace.  The identity of UNASSIGNED_STACK in
jaroslav@65
   946
//         * stackTrace indicates to the getOurStackTrace method that
jaroslav@65
   947
//         * the stackTrace needs to be constructed from the information
jaroslav@65
   948
//         * in backtrace.
jaroslav@65
   949
//         */
jaroslav@65
   950
//        if (stackTrace != null) {
jaroslav@65
   951
//            if (stackTrace.length == 0) {
jaroslav@65
   952
//                stackTrace = UNASSIGNED_STACK.clone();
jaroslav@65
   953
//            }  else if (stackTrace.length == 1 &&
jaroslav@65
   954
//                        // Check for the marker of an immutable stack trace
jaroslav@65
   955
//                        SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
jaroslav@65
   956
//                stackTrace = null;
jaroslav@65
   957
//            } else { // Verify stack trace elements are non-null.
jaroslav@65
   958
//                for(StackTraceElement ste : stackTrace) {
jaroslav@65
   959
//                    if (ste == null)
jaroslav@65
   960
//                        throw new NullPointerException("null StackTraceElement in serial stream. ");
jaroslav@65
   961
//                }
jaroslav@65
   962
//            }
jaroslav@65
   963
//        } else {
jaroslav@65
   964
//            // A null stackTrace field in the serial form can result
jaroslav@65
   965
//            // from an exception serialized without that field in
jaroslav@65
   966
//            // older JDK releases; treat such exceptions as having
jaroslav@65
   967
//            // empty stack traces.
jaroslav@65
   968
//            stackTrace = UNASSIGNED_STACK.clone();
jaroslav@65
   969
//        }
jaroslav@65
   970
//    }
jaroslav@49
   971
jaroslav@49
   972
    /**
jaroslav@49
   973
     * Write a {@code Throwable} object to a stream.
jaroslav@49
   974
     *
jaroslav@49
   975
     * A {@code null} stack trace field is represented in the serial
jaroslav@49
   976
     * form as a one-element array whose element is equal to {@code
jaroslav@49
   977
     * new StackTraceElement("", "", null, Integer.MIN_VALUE)}.
jaroslav@49
   978
     */
jaroslav@83
   979
//    private synchronized void writeObject(ObjectOutputStream s)
jaroslav@83
   980
//        throws IOException {
jaroslav@83
   981
//        // Ensure that the stackTrace field is initialized to a
jaroslav@83
   982
//        // non-null value, if appropriate.  As of JDK 7, a null stack
jaroslav@83
   983
//        // trace field is a valid value indicating the stack trace
jaroslav@83
   984
//        // should not be set.
jaroslav@83
   985
//        getOurStackTrace();
jaroslav@83
   986
//
jaroslav@83
   987
//        StackTraceElement[] oldStackTrace = stackTrace;
jaroslav@83
   988
//        try {
jaroslav@83
   989
//            if (stackTrace == null)
jaroslav@83
   990
//                stackTrace = SentinelHolder.STACK_TRACE_SENTINEL;
jaroslav@83
   991
//            s.defaultWriteObject();
jaroslav@83
   992
//        } finally {
jaroslav@83
   993
//            stackTrace = oldStackTrace;
jaroslav@83
   994
//        }
jaroslav@83
   995
//    }
jaroslav@49
   996
jaroslav@49
   997
    /**
jaroslav@49
   998
     * Appends the specified exception to the exceptions that were
jaroslav@49
   999
     * suppressed in order to deliver this exception. This method is
jaroslav@49
  1000
     * thread-safe and typically called (automatically and implicitly)
jaroslav@49
  1001
     * by the {@code try}-with-resources statement.
jaroslav@49
  1002
     *
jaroslav@49
  1003
     * <p>The suppression behavior is enabled <em>unless</em> disabled
jaroslav@49
  1004
     * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
jaroslav@49
  1005
     * a constructor}.  When suppression is disabled, this method does
jaroslav@49
  1006
     * nothing other than to validate its argument.
jaroslav@49
  1007
     *
jaroslav@49
  1008
     * <p>Note that when one exception {@linkplain
jaroslav@49
  1009
     * #initCause(Throwable) causes} another exception, the first
jaroslav@49
  1010
     * exception is usually caught and then the second exception is
jaroslav@49
  1011
     * thrown in response.  In other words, there is a causal
jaroslav@49
  1012
     * connection between the two exceptions.
jaroslav@49
  1013
     *
jaroslav@49
  1014
     * In contrast, there are situations where two independent
jaroslav@49
  1015
     * exceptions can be thrown in sibling code blocks, in particular
jaroslav@49
  1016
     * in the {@code try} block of a {@code try}-with-resources
jaroslav@49
  1017
     * statement and the compiler-generated {@code finally} block
jaroslav@49
  1018
     * which closes the resource.
jaroslav@49
  1019
     *
jaroslav@49
  1020
     * In these situations, only one of the thrown exceptions can be
jaroslav@49
  1021
     * propagated.  In the {@code try}-with-resources statement, when
jaroslav@49
  1022
     * there are two such exceptions, the exception originating from
jaroslav@49
  1023
     * the {@code try} block is propagated and the exception from the
jaroslav@49
  1024
     * {@code finally} block is added to the list of exceptions
jaroslav@49
  1025
     * suppressed by the exception from the {@code try} block.  As an
jaroslav@49
  1026
     * exception unwinds the stack, it can accumulate multiple
jaroslav@49
  1027
     * suppressed exceptions.
jaroslav@49
  1028
     *
jaroslav@49
  1029
     * <p>An exception may have suppressed exceptions while also being
jaroslav@49
  1030
     * caused by another exception.  Whether or not an exception has a
jaroslav@49
  1031
     * cause is semantically known at the time of its creation, unlike
jaroslav@49
  1032
     * whether or not an exception will suppress other exceptions
jaroslav@49
  1033
     * which is typically only determined after an exception is
jaroslav@49
  1034
     * thrown.
jaroslav@49
  1035
     *
jaroslav@49
  1036
     * <p>Note that programmer written code is also able to take
jaroslav@49
  1037
     * advantage of calling this method in situations where there are
jaroslav@49
  1038
     * multiple sibling exceptions and only one can be propagated.
jaroslav@49
  1039
     *
jaroslav@49
  1040
     * @param exception the exception to be added to the list of
jaroslav@49
  1041
     *        suppressed exceptions
jaroslav@49
  1042
     * @throws IllegalArgumentException if {@code exception} is this
jaroslav@49
  1043
     *         throwable; a throwable cannot suppress itself.
jaroslav@49
  1044
     * @throws NullPointerException if {@code exception} is {@code null}
jaroslav@49
  1045
     * @since 1.7
jaroslav@49
  1046
     */
jaroslav@49
  1047
    public final synchronized void addSuppressed(Throwable exception) {
jaroslav@49
  1048
        if (exception == this)
jaroslav@49
  1049
            throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
jaroslav@49
  1050
jaroslav@49
  1051
        if (exception == null)
jaroslav@49
  1052
            throw new NullPointerException(NULL_CAUSE_MESSAGE);
jaroslav@49
  1053
jaroslav@61
  1054
//        if (suppressedExceptions == null) // Suppressed exceptions not recorded
jaroslav@61
  1055
//            return;
jaroslav@61
  1056
//
jaroslav@61
  1057
//        if (suppressedExceptions == SUPPRESSED_SENTINEL)
jaroslav@61
  1058
//            suppressedExceptions = new ArrayList<Throwable>(1);
jaroslav@61
  1059
//
jaroslav@61
  1060
//        suppressedExceptions.add(exception);
jaroslav@49
  1061
    }
jaroslav@49
  1062
jaroslav@49
  1063
    private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
jaroslav@49
  1064
jaroslav@49
  1065
    /**
jaroslav@49
  1066
     * Returns an array containing all of the exceptions that were
jaroslav@49
  1067
     * suppressed, typically by the {@code try}-with-resources
jaroslav@49
  1068
     * statement, in order to deliver this exception.
jaroslav@49
  1069
     *
jaroslav@49
  1070
     * If no exceptions were suppressed or {@linkplain
jaroslav@49
  1071
     * #Throwable(String, Throwable, boolean, boolean) suppression is
jaroslav@49
  1072
     * disabled}, an empty array is returned.  This method is
jaroslav@49
  1073
     * thread-safe.  Writes to the returned array do not affect future
jaroslav@49
  1074
     * calls to this method.
jaroslav@49
  1075
     *
jaroslav@49
  1076
     * @return an array containing all of the exceptions that were
jaroslav@49
  1077
     *         suppressed to deliver this exception.
jaroslav@49
  1078
     * @since 1.7
jaroslav@49
  1079
     */
jaroslav@49
  1080
    public final synchronized Throwable[] getSuppressed() {
jaroslav@61
  1081
        return new Throwable[0];
jaroslav@61
  1082
//        if (suppressedExceptions == SUPPRESSED_SENTINEL ||
jaroslav@61
  1083
//            suppressedExceptions == null)
jaroslav@61
  1084
//            return EMPTY_THROWABLE_ARRAY;
jaroslav@61
  1085
//        else
jaroslav@61
  1086
//            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
jaroslav@49
  1087
    }
jaroslav@49
  1088
}