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