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