1 /*
   2  * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 import  java.io.*;
  28 
  29 /**
  30  * The <code>Throwable</code> class is the superclass of all errors and
  31  * exceptions in the Java language. Only objects that are instances of this
  32  * class (or one of its subclasses) are thrown by the Java Virtual Machine or
  33  * can be thrown by the Java <code>throw</code> statement. Similarly, only
  34  * this class or one of its subclasses can be the argument type in a
  35  * <code>catch</code> clause.
  36  *
  37  * For the purposes of compile-time checking of exceptions, {@code
  38  * Throwable} and any subclass of {@code Throwable} that is not also a
  39  * subclass of either {@link RuntimeException} or {@link Error} are
  40  * regarded as checked exceptions.
  41  *
  42  * <p>Instances of two subclasses, {@link java.lang.Error} and
  43  * {@link java.lang.Exception}, are conventionally used to indicate
  44  * that exceptional situations have occurred. Typically, these instances
  45  * are freshly created in the context of the exceptional situation so
  46  * as to include relevant information (such as stack trace data).
  47  *
  48  * <p>A throwable contains a snapshot of the execution stack of its thread at
  49  * the time it was created. It can also contain a message string that gives
  50  * more information about the error. Finally, it can contain a <i>cause</i>:
  51  * another throwable that caused this throwable to get thrown.  The cause
  52  * facility is new in release 1.4.  It is also known as the <i>chained
  53  * exception</i> facility, as the cause can, itself, have a cause, and so on,
  54  * leading to a "chain" of exceptions, each caused by another.
  55  *
  56  * <p>One reason that a throwable may have a cause is that the class that
  57  * throws it is built atop a lower layered abstraction, and an operation on
  58  * the upper layer fails due to a failure in the lower layer.  It would be bad
  59  * design to let the throwable thrown by the lower layer propagate outward, as
  60  * it is generally unrelated to the abstraction provided by the upper layer.
  61  * Further, doing so would tie the API of the upper layer to the details of
  62  * its implementation, assuming the lower layer's exception was a checked
  63  * exception.  Throwing a "wrapped exception" (i.e., an exception containing a
  64  * cause) allows the upper layer to communicate the details of the failure to
  65  * its caller without incurring either of these shortcomings.  It preserves
  66  * the flexibility to change the implementation of the upper layer without
  67  * changing its API (in particular, the set of exceptions thrown by its
  68  * methods).
  69  *
  70  * <p>A second reason that a throwable may have a cause is that the method
  71  * that throws it must conform to a general-purpose interface that does not
  72  * permit the method to throw the cause directly.  For example, suppose
  73  * a persistent collection conforms to the {@link java.util.Collection
  74  * Collection} interface, and that its persistence is implemented atop
  75  * <tt>java.io</tt>.  Suppose the internals of the <tt>add</tt> method
  76  * can throw an {@link java.io.IOException IOException}.  The implementation
  77  * can communicate the details of the <tt>IOException</tt> to its caller
  78  * while conforming to the <tt>Collection</tt> interface by wrapping the
  79  * <tt>IOException</tt> in an appropriate unchecked exception.  (The
  80  * specification for the persistent collection should indicate that it is
  81  * capable of throwing such exceptions.)
  82  *
  83  * <p>A cause can be associated with a throwable in two ways: via a
  84  * constructor that takes the cause as an argument, or via the
  85  * {@link #initCause(Throwable)} method.  New throwable classes that
  86  * wish to allow causes to be associated with them should provide constructors
  87  * that take a cause and delegate (perhaps indirectly) to one of the
  88  * <tt>Throwable</tt> constructors that takes a cause.  For example:
  89  * <pre>
  90  *     try {
  91  *         lowLevelOp();
  92  *     } catch (LowLevelException le) {
  93  *         throw new HighLevelException(le);  // Chaining-aware constructor
  94  *     }
  95  * </pre>
  96  * Because the <tt>initCause</tt> method is public, it allows a cause to be
  97  * associated with any throwable, even a "legacy throwable" whose
  98  * implementation predates the addition of the exception chaining mechanism to
  99  * <tt>Throwable</tt>. For example:
 100  * <pre>
 101  *     try {
 102  *         lowLevelOp();
 103  *     } catch (LowLevelException le) {
 104  *         throw (HighLevelException)
 105                  new HighLevelException().initCause(le);  // Legacy constructor
 106  *     }
 107  * </pre>
 108  *
 109  * <p>Prior to release 1.4, there were many throwables that had their own
 110  * non-standard exception chaining mechanisms (
 111  * {@link ExceptionInInitializerError}, {@link ClassNotFoundException},
 112  * {@link java.lang.reflect.UndeclaredThrowableException},
 113  * {@link java.lang.reflect.InvocationTargetException},
 114  * {@link java.io.WriteAbortedException},
 115  * {@link java.security.PrivilegedActionException},
 116  * {@link java.awt.print.PrinterIOException},
 117  * {@link java.rmi.RemoteException} and
 118  * {@link javax.naming.NamingException}).
 119  * All of these throwables have been retrofitted to
 120  * use the standard exception chaining mechanism, while continuing to
 121  * implement their "legacy" chaining mechanisms for compatibility.
 122  *
 123  * <p>Further, as of release 1.4, many general purpose <tt>Throwable</tt>
 124  * classes (for example {@link Exception}, {@link RuntimeException},
 125  * {@link Error}) have been retrofitted with constructors that take
 126  * a cause.  This was not strictly necessary, due to the existence of the
 127  * <tt>initCause</tt> method, but it is more convenient and expressive to
 128  * delegate to a constructor that takes a cause.
 129  *
 130  * <p>By convention, class <code>Throwable</code> and its subclasses have two
 131  * constructors, one that takes no arguments and one that takes a
 132  * <code>String</code> argument that can be used to produce a detail message.
 133  * Further, those subclasses that might likely have a cause associated with
 134  * them should have two more constructors, one that takes a
 135  * <code>Throwable</code> (the cause), and one that takes a
 136  * <code>String</code> (the detail message) and a <code>Throwable</code> (the
 137  * cause).
 138  *
 139  * <p>Also introduced in release 1.4 is the {@link #getStackTrace()} method,
 140  * which allows programmatic access to the stack trace information that was
 141  * previously available only in text form, via the various forms of the
 142  * {@link #printStackTrace()} method.  This information has been added to the
 143  * <i>serialized representation</i> of this class so <tt>getStackTrace</tt>
 144  * and <tt>printStackTrace</tt> will operate properly on a throwable that
 145  * was obtained by deserialization.
 146  *
 147  * @author  unascribed
 148  * @author  Josh Bloch (Added exception chaining and programmatic access to
 149  *          stack trace in 1.4.)
 150  * @jls3 11.2 Compile-Time Checking of Exceptions
 151  * @since JDK1.0
 152  */
 153 public class Throwable implements Serializable {
 154     /** use serialVersionUID from JDK 1.0.2 for interoperability */
 155     private static final long serialVersionUID = -3042686055658047285L;
 156 
 157     /**
 158      * Native code saves some indication of the stack backtrace in this slot.
 159      */
 160     private transient Object backtrace;
 161 
 162     /**
 163      * Specific details about the Throwable.  For example, for
 164      * <tt>FileNotFoundException</tt>, this contains the name of
 165      * the file that could not be found.
 166      *
 167      * @serial
 168      */
 169     private String detailMessage;
 170 
 171     /**
 172      * The throwable that caused this throwable to get thrown, or null if this
 173      * throwable was not caused by another throwable, or if the causative
 174      * throwable is unknown.  If this field is equal to this throwable itself,
 175      * it indicates that the cause of this throwable has not yet been
 176      * initialized.
 177      *
 178      * @serial
 179      * @since 1.4
 180      */
 181     private Throwable cause = this;
 182 
 183     /**
 184      * The stack trace, as returned by {@link #getStackTrace()}.
 185      *
 186      * @serial
 187      * @since 1.4
 188      */
 189     private StackTraceElement[] stackTrace;
 190     /*
 191      * This field is lazily initialized on first use or serialization and
 192      * nulled out when fillInStackTrace is called.
 193      */
 194 
 195     /**
 196      * Constructs a new throwable with <code>null</code> as its detail message.
 197      * The cause is not initialized, and may subsequently be initialized by a
 198      * call to {@link #initCause}.
 199      *
 200      * <p>The {@link #fillInStackTrace()} method is called to initialize
 201      * the stack trace data in the newly created throwable.
 202      */
 203     public Throwable() {
 204         fillInStackTrace();
 205     }
 206 
 207     /**
 208      * Constructs a new throwable with the specified detail message.  The
 209      * cause is not initialized, and may subsequently be initialized by
 210      * a call to {@link #initCause}.
 211      *
 212      * <p>The {@link #fillInStackTrace()} method is called to initialize
 213      * the stack trace data in the newly created throwable.
 214      *
 215      * @param   message   the detail message. The detail message is saved for
 216      *          later retrieval by the {@link #getMessage()} method.
 217      */
 218     public Throwable(String message) {
 219         fillInStackTrace();
 220         detailMessage = message;
 221     }
 222 
 223     /**
 224      * Constructs a new throwable with the specified detail message and
 225      * cause.  <p>Note that the detail message associated with
 226      * <code>cause</code> is <i>not</i> automatically incorporated in
 227      * this throwable's detail message.
 228      *
 229      * <p>The {@link #fillInStackTrace()} method is called to initialize
 230      * the stack trace data in the newly created throwable.
 231      *
 232      * @param  message the detail message (which is saved for later retrieval
 233      *         by the {@link #getMessage()} method).
 234      * @param  cause the cause (which is saved for later retrieval by the
 235      *         {@link #getCause()} method).  (A <tt>null</tt> value is
 236      *         permitted, and indicates that the cause is nonexistent or
 237      *         unknown.)
 238      * @since  1.4
 239      */
 240     public Throwable(String message, Throwable cause) {
 241         fillInStackTrace();
 242         detailMessage = message;
 243         this.cause = cause;
 244     }
 245 
 246     /**
 247      * Constructs a new throwable with the specified cause and a detail
 248      * message of <tt>(cause==null ? null : cause.toString())</tt> (which
 249      * typically contains the class and detail message of <tt>cause</tt>).
 250      * This constructor is useful for throwables that are little more than
 251      * wrappers for other throwables (for example, {@link
 252      * java.security.PrivilegedActionException}).
 253      *
 254      * <p>The {@link #fillInStackTrace()} method is called to initialize
 255      * the stack trace data in the newly created throwable.
 256      *
 257      * @param  cause the cause (which is saved for later retrieval by the
 258      *         {@link #getCause()} method).  (A <tt>null</tt> value is
 259      *         permitted, and indicates that the cause is nonexistent or
 260      *         unknown.)
 261      * @since  1.4
 262      */
 263     public Throwable(Throwable cause) {
 264         fillInStackTrace();
 265         detailMessage = (cause==null ? null : cause.toString());
 266         this.cause = cause;
 267     }
 268 
 269     /**
 270      * Returns the detail message string of this throwable.
 271      *
 272      * @return  the detail message string of this <tt>Throwable</tt> instance
 273      *          (which may be <tt>null</tt>).
 274      */
 275     public String getMessage() {
 276         return detailMessage;
 277     }
 278 
 279     /**
 280      * Creates a localized description of this throwable.
 281      * Subclasses may override this method in order to produce a
 282      * locale-specific message.  For subclasses that do not override this
 283      * method, the default implementation returns the same result as
 284      * <code>getMessage()</code>.
 285      *
 286      * @return  The localized description of this throwable.
 287      * @since   JDK1.1
 288      */
 289     public String getLocalizedMessage() {
 290         return getMessage();
 291     }
 292 
 293     /**
 294      * Returns the cause of this throwable or <code>null</code> if the
 295      * cause is nonexistent or unknown.  (The cause is the throwable that
 296      * caused this throwable to get thrown.)
 297      *
 298      * <p>This implementation returns the cause that was supplied via one of
 299      * the constructors requiring a <tt>Throwable</tt>, or that was set after
 300      * creation with the {@link #initCause(Throwable)} method.  While it is
 301      * typically unnecessary to override this method, a subclass can override
 302      * it to return a cause set by some other means.  This is appropriate for
 303      * a "legacy chained throwable" that predates the addition of chained
 304      * exceptions to <tt>Throwable</tt>.  Note that it is <i>not</i>
 305      * necessary to override any of the <tt>PrintStackTrace</tt> methods,
 306      * all of which invoke the <tt>getCause</tt> method to determine the
 307      * cause of a throwable.
 308      *
 309      * @return  the cause of this throwable or <code>null</code> if the
 310      *          cause is nonexistent or unknown.
 311      * @since 1.4
 312      */
 313     public Throwable getCause() {
 314         return (cause==this ? null : cause);
 315     }
 316 
 317     /**
 318      * Initializes the <i>cause</i> of this throwable to the specified value.
 319      * (The cause is the throwable that caused this throwable to get thrown.)
 320      *
 321      * <p>This method can be called at most once.  It is generally called from
 322      * within the constructor, or immediately after creating the
 323      * throwable.  If this throwable was created
 324      * with {@link #Throwable(Throwable)} or
 325      * {@link #Throwable(String,Throwable)}, this method cannot be called
 326      * even once.
 327      *
 328      * @param  cause the cause (which is saved for later retrieval by the
 329      *         {@link #getCause()} method).  (A <tt>null</tt> value is
 330      *         permitted, and indicates that the cause is nonexistent or
 331      *         unknown.)
 332      * @return  a reference to this <code>Throwable</code> instance.
 333      * @throws IllegalArgumentException if <code>cause</code> is this
 334      *         throwable.  (A throwable cannot be its own cause.)
 335      * @throws IllegalStateException if this throwable was
 336      *         created with {@link #Throwable(Throwable)} or
 337      *         {@link #Throwable(String,Throwable)}, or this method has already
 338      *         been called on this throwable.
 339      * @since  1.4
 340      */
 341     public synchronized Throwable initCause(Throwable cause) {
 342         if (this.cause != this)
 343             throw new IllegalStateException("Can't overwrite cause");
 344         if (cause == this)
 345             throw new IllegalArgumentException("Self-causation not permitted");
 346         this.cause = cause;
 347         return this;
 348     }
 349 
 350     /**
 351      * Returns a short description of this throwable.
 352      * The result is the concatenation of:
 353      * <ul>
 354      * <li> the {@linkplain Class#getName() name} of the class of this object
 355      * <li> ": " (a colon and a space)
 356      * <li> the result of invoking this object's {@link #getLocalizedMessage}
 357      *      method
 358      * </ul>
 359      * If <tt>getLocalizedMessage</tt> returns <tt>null</tt>, then just
 360      * the class name is returned.
 361      *
 362      * @return a string representation of this throwable.
 363      */
 364     public String toString() {
 365         String s = getClass().getName();
 366         String message = getLocalizedMessage();
 367         return (message != null) ? (s + ": " + message) : s;
 368     }
 369 
 370     /**
 371      * Prints this throwable and its backtrace to the
 372      * standard error stream. This method prints a stack trace for this
 373      * <code>Throwable</code> object on the error output stream that is
 374      * the value of the field <code>System.err</code>. The first line of
 375      * output contains the result of the {@link #toString()} method for
 376      * this object.  Remaining lines represent data previously recorded by
 377      * the method {@link #fillInStackTrace()}. The format of this
 378      * information depends on the implementation, but the following
 379      * example may be regarded as typical:
 380      * <blockquote><pre>
 381      * java.lang.NullPointerException
 382      *         at MyClass.mash(MyClass.java:9)
 383      *         at MyClass.crunch(MyClass.java:6)
 384      *         at MyClass.main(MyClass.java:3)
 385      * </pre></blockquote>
 386      * This example was produced by running the program:
 387      * <pre>
 388      * class MyClass {
 389      *     public static void main(String[] args) {
 390      *         crunch(null);
 391      *     }
 392      *     static void crunch(int[] a) {
 393      *         mash(a);
 394      *     }
 395      *     static void mash(int[] b) {
 396      *         System.out.println(b[0]);
 397      *     }
 398      * }
 399      * </pre>
 400      * The backtrace for a throwable with an initialized, non-null cause
 401      * should generally include the backtrace for the cause.  The format
 402      * of this information depends on the implementation, but the following
 403      * example may be regarded as typical:
 404      * <pre>
 405      * HighLevelException: MidLevelException: LowLevelException
 406      *         at Junk.a(Junk.java:13)
 407      *         at Junk.main(Junk.java:4)
 408      * Caused by: MidLevelException: LowLevelException
 409      *         at Junk.c(Junk.java:23)
 410      *         at Junk.b(Junk.java:17)
 411      *         at Junk.a(Junk.java:11)
 412      *         ... 1 more
 413      * Caused by: LowLevelException
 414      *         at Junk.e(Junk.java:30)
 415      *         at Junk.d(Junk.java:27)
 416      *         at Junk.c(Junk.java:21)
 417      *         ... 3 more
 418      * </pre>
 419      * Note the presence of lines containing the characters <tt>"..."</tt>.
 420      * These lines indicate that the remainder of the stack trace for this
 421      * exception matches the indicated number of frames from the bottom of the
 422      * stack trace of the exception that was caused by this exception (the
 423      * "enclosing" exception).  This shorthand can greatly reduce the length
 424      * of the output in the common case where a wrapped exception is thrown
 425      * from same method as the "causative exception" is caught.  The above
 426      * example was produced by running the program:
 427      * <pre>
 428      * public class Junk {
 429      *     public static void main(String args[]) {
 430      *         try {
 431      *             a();
 432      *         } catch(HighLevelException e) {
 433      *             e.printStackTrace();
 434      *         }
 435      *     }
 436      *     static void a() throws HighLevelException {
 437      *         try {
 438      *             b();
 439      *         } catch(MidLevelException e) {
 440      *             throw new HighLevelException(e);
 441      *         }
 442      *     }
 443      *     static void b() throws MidLevelException {
 444      *         c();
 445      *     }
 446      *     static void c() throws MidLevelException {
 447      *         try {
 448      *             d();
 449      *         } catch(LowLevelException e) {
 450      *             throw new MidLevelException(e);
 451      *         }
 452      *     }
 453      *     static void d() throws LowLevelException {
 454      *        e();
 455      *     }
 456      *     static void e() throws LowLevelException {
 457      *         throw new LowLevelException();
 458      *     }
 459      * }
 460      *
 461      * class HighLevelException extends Exception {
 462      *     HighLevelException(Throwable cause) { super(cause); }
 463      * }
 464      *
 465      * class MidLevelException extends Exception {
 466      *     MidLevelException(Throwable cause)  { super(cause); }
 467      * }
 468      *
 469      * class LowLevelException extends Exception {
 470      * }
 471      * </pre>
 472      */
 473     public void printStackTrace() {
 474         printStackTrace(System.err);
 475     }
 476 
 477     /**
 478      * Prints this throwable and its backtrace to the specified print stream.
 479      *
 480      * @param s <code>PrintStream</code> to use for output
 481      */
 482     public void printStackTrace(PrintStream s) {
 483         synchronized (s) {
 484             s.println(this);
 485             StackTraceElement[] trace = getOurStackTrace();
 486             for (int i=0; i < trace.length; i++)
 487                 s.println("\tat " + trace[i]);
 488 
 489             Throwable ourCause = getCause();
 490             if (ourCause != null)
 491                 ourCause.printStackTraceAsCause(s, trace);
 492         }
 493     }
 494 
 495     /**
 496      * Print our stack trace as a cause for the specified stack trace.
 497      */
 498     private void printStackTraceAsCause(PrintStream s,
 499                                         StackTraceElement[] causedTrace)
 500     {
 501         // assert Thread.holdsLock(s);
 502 
 503         // Compute number of frames in common between this and caused
 504         StackTraceElement[] trace = getOurStackTrace();
 505         int m = trace.length-1, n = causedTrace.length-1;
 506         while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
 507             m--; n--;
 508         }
 509         int framesInCommon = trace.length - 1 - m;
 510 
 511         s.println("Caused by: " + this);
 512         for (int i=0; i <= m; i++)
 513             s.println("\tat " + trace[i]);
 514         if (framesInCommon != 0)
 515             s.println("\t... " + framesInCommon + " more");
 516 
 517         // Recurse if we have a cause
 518         Throwable ourCause = getCause();
 519         if (ourCause != null)
 520             ourCause.printStackTraceAsCause(s, trace);
 521     }
 522 
 523     /**
 524      * Prints this throwable and its backtrace to the specified
 525      * print writer.
 526      *
 527      * @param s <code>PrintWriter</code> to use for output
 528      * @since   JDK1.1
 529      */
 530     public void printStackTrace(PrintWriter s) {
 531         synchronized (s) {
 532             s.println(this);
 533             StackTraceElement[] trace = getOurStackTrace();
 534             for (int i=0; i < trace.length; i++)
 535                 s.println("\tat " + trace[i]);
 536 
 537             Throwable ourCause = getCause();
 538             if (ourCause != null)
 539                 ourCause.printStackTraceAsCause(s, trace);
 540         }
 541     }
 542 
 543     /**
 544      * Print our stack trace as a cause for the specified stack trace.
 545      */
 546     private void printStackTraceAsCause(PrintWriter s,
 547                                         StackTraceElement[] causedTrace)
 548     {
 549         // assert Thread.holdsLock(s);
 550 
 551         // Compute number of frames in common between this and caused
 552         StackTraceElement[] trace = getOurStackTrace();
 553         int m = trace.length-1, n = causedTrace.length-1;
 554         while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
 555             m--; n--;
 556         }
 557         int framesInCommon = trace.length - 1 - m;
 558 
 559         s.println("Caused by: " + this);
 560         for (int i=0; i <= m; i++)
 561             s.println("\tat " + trace[i]);
 562         if (framesInCommon != 0)
 563             s.println("\t... " + framesInCommon + " more");
 564 
 565         // Recurse if we have a cause
 566         Throwable ourCause = getCause();
 567         if (ourCause != null)
 568             ourCause.printStackTraceAsCause(s, trace);
 569     }
 570 
 571     /**
 572      * Fills in the execution stack trace. This method records within this
 573      * <code>Throwable</code> object information about the current state of
 574      * the stack frames for the current thread.
 575      *
 576      * @return  a reference to this <code>Throwable</code> instance.
 577      * @see     java.lang.Throwable#printStackTrace()
 578      */
 579     public synchronized native Throwable fillInStackTrace();
 580 
 581     /**
 582      * Provides programmatic access to the stack trace information printed by
 583      * {@link #printStackTrace()}.  Returns an array of stack trace elements,
 584      * each representing one stack frame.  The zeroth element of the array
 585      * (assuming the array's length is non-zero) represents the top of the
 586      * stack, which is the last method invocation in the sequence.  Typically,
 587      * this is the point at which this throwable was created and thrown.
 588      * The last element of the array (assuming the array's length is non-zero)
 589      * represents the bottom of the stack, which is the first method invocation
 590      * in the sequence.
 591      *
 592      * <p>Some virtual machines may, under some circumstances, omit one
 593      * or more stack frames from the stack trace.  In the extreme case,
 594      * a virtual machine that has no stack trace information concerning
 595      * this throwable is permitted to return a zero-length array from this
 596      * method.  Generally speaking, the array returned by this method will
 597      * contain one element for every frame that would be printed by
 598      * <tt>printStackTrace</tt>.
 599      *
 600      * @return an array of stack trace elements representing the stack trace
 601      *         pertaining to this throwable.
 602      * @since  1.4
 603      */
 604     public StackTraceElement[] getStackTrace() {
 605         return getOurStackTrace().clone();
 606     }
 607 
 608     private synchronized StackTraceElement[] getOurStackTrace() {
 609         // Initialize stack trace if this is the first call to this method
 610         if (stackTrace == null) {
 611             int depth = getStackTraceDepth();
 612             stackTrace = new StackTraceElement[depth];
 613             for (int i=0; i < depth; i++)
 614                 stackTrace[i] = getStackTraceElement(i);
 615         }
 616         return stackTrace;
 617     }
 618 
 619     /**
 620      * Sets the stack trace elements that will be returned by
 621      * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
 622      * and related methods.
 623      *
 624      * This method, which is designed for use by RPC frameworks and other
 625      * advanced systems, allows the client to override the default
 626      * stack trace that is either generated by {@link #fillInStackTrace()}
 627      * when a throwable is constructed or deserialized when a throwable is
 628      * read from a serialization stream.
 629      *
 630      * @param   stackTrace the stack trace elements to be associated with
 631      * this <code>Throwable</code>.  The specified array is copied by this
 632      * call; changes in the specified array after the method invocation
 633      * returns will have no affect on this <code>Throwable</code>'s stack
 634      * trace.
 635      *
 636      * @throws NullPointerException if <code>stackTrace</code> is
 637      *         <code>null</code>, or if any of the elements of
 638      *         <code>stackTrace</code> are <code>null</code>
 639      *
 640      * @since  1.4
 641      */
 642     public void setStackTrace(StackTraceElement[] stackTrace) {
 643         StackTraceElement[] defensiveCopy = stackTrace.clone();
 644         for (int i = 0; i < defensiveCopy.length; i++)
 645             if (defensiveCopy[i] == null)
 646                 throw new NullPointerException("stackTrace[" + i + "]");
 647 
 648         this.stackTrace = defensiveCopy;
 649     }
 650 
 651     /**
 652      * Returns the number of elements in the stack trace (or 0 if the stack
 653      * trace is unavailable).
 654      *
 655      * package-protection for use by SharedSecrets.
 656      */
 657     native int getStackTraceDepth();
 658 
 659     /**
 660      * Returns the specified element of the stack trace.
 661      *
 662      * package-protection for use by SharedSecrets.
 663      *
 664      * @param index index of the element to return.
 665      * @throws IndexOutOfBoundsException if <tt>index &lt; 0 ||
 666      *         index &gt;= getStackTraceDepth() </tt>
 667      */
 668     native StackTraceElement getStackTraceElement(int index);
 669 
 670     private synchronized void writeObject(java.io.ObjectOutputStream s)
 671         throws IOException
 672     {
 673         getOurStackTrace();  // Ensure that stackTrace field is initialized.
 674         s.defaultWriteObject();
 675     }
 676 }