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 *
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
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
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)
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 < 0 ||
666 * index >= 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 }
|
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 import java.util.*;
29
30 /**
31 * The <code>Throwable</code> class is the superclass of all errors and
32 * exceptions in the Java language. Only objects that are instances of this
33 * class (or one of its subclasses) are thrown by the Java Virtual Machine or
34 * can be thrown by the Java <code>throw</code> statement. Similarly, only
35 * this class or one of its subclasses can be the argument type in a
36 * <code>catch</code> clause.
37 *
38 * For the purposes of compile-time checking of exceptions, {@code
39 * Throwable} and any subclass of {@code Throwable} that is not also a
40 * subclass of either {@link RuntimeException} or {@link Error} are
41 * regarded as checked exceptions.
42 *
43 * <p>Instances of two subclasses, {@link java.lang.Error} and
44 * {@link java.lang.Exception}, are conventionally used to indicate
45 * that exceptional situations have occurred. Typically, these instances
46 * are freshly created in the context of the exceptional situation so
47 * as to include relevant information (such as stack trace data).
48 *
86 * {@link #initCause(Throwable)} method. New throwable classes that
87 * wish to allow causes to be associated with them should provide constructors
88 * that take a cause and delegate (perhaps indirectly) to one of the
89 * <tt>Throwable</tt> constructors that takes a cause. For example:
90 * <pre>
91 * try {
92 * lowLevelOp();
93 * } catch (LowLevelException le) {
94 * throw new HighLevelException(le); // Chaining-aware constructor
95 * }
96 * </pre>
97 * Because the <tt>initCause</tt> method is public, it allows a cause to be
98 * associated with any throwable, even a "legacy throwable" whose
99 * implementation predates the addition of the exception chaining mechanism to
100 * <tt>Throwable</tt>. For example:
101 * <pre>
102 * try {
103 * lowLevelOp();
104 * } catch (LowLevelException le) {
105 * throw (HighLevelException)
106 * new HighLevelException().initCause(le); // Legacy constructor
107 * }
108 * </pre>
109 *
110 * <p>Prior to release 1.4, there were many throwables that had their own
111 * non-standard exception chaining mechanisms (
112 * {@link ExceptionInInitializerError}, {@link ClassNotFoundException},
113 * {@link java.lang.reflect.UndeclaredThrowableException},
114 * {@link java.lang.reflect.InvocationTargetException},
115 * {@link java.io.WriteAbortedException},
116 * {@link java.security.PrivilegedActionException},
117 * {@link java.awt.print.PrinterIOException},
118 * {@link java.rmi.RemoteException} and
119 * {@link javax.naming.NamingException}).
120 * All of these throwables have been retrofitted to
121 * use the standard exception chaining mechanism, while continuing to
122 * implement their "legacy" chaining mechanisms for compatibility.
123 *
124 * <p>Further, as of release 1.4, many general purpose <tt>Throwable</tt>
125 * classes (for example {@link Exception}, {@link RuntimeException},
126 * {@link Error}) have been retrofitted with constructors that take
177 * initialized.
178 *
179 * @serial
180 * @since 1.4
181 */
182 private Throwable cause = this;
183
184 /**
185 * The stack trace, as returned by {@link #getStackTrace()}.
186 *
187 * @serial
188 * @since 1.4
189 */
190 private StackTraceElement[] stackTrace;
191 /*
192 * This field is lazily initialized on first use or serialization and
193 * nulled out when fillInStackTrace is called.
194 */
195
196 /**
197 * The list of suppressed exceptions, as returned by
198 * {@link #getSuppressedExceptions()}.
199 *
200 * @serial
201 * @since 1.7
202 */
203 private List<Throwable> suppressedExceptions = Collections.emptyList();
204
205 /** Caption for labeling causative exception stack traces */
206 private static final String CAUSE_CAPTION = "Caused by: ";
207
208 /** Caption for labeling suppressed exception stack traces */
209 private static final String SUPPRESSED_CAPTION = "Suppressed: ";
210
211 /**
212 * Constructs a new throwable with <code>null</code> as its detail message.
213 * The cause is not initialized, and may subsequently be initialized by a
214 * call to {@link #initCause}.
215 *
216 * <p>The {@link #fillInStackTrace()} method is called to initialize
217 * the stack trace data in the newly created throwable.
218 */
219 public Throwable() {
220 fillInStackTrace();
221 }
222
223 /**
224 * Constructs a new throwable with the specified detail message. The
225 * cause is not initialized, and may subsequently be initialized by
226 * a call to {@link #initCause}.
227 *
228 * <p>The {@link #fillInStackTrace()} method is called to initialize
229 * the stack trace data in the newly created throwable.
230 *
231 * @param message the detail message. The detail message is saved for
468 * }
469 * static void d() throws LowLevelException {
470 * e();
471 * }
472 * static void e() throws LowLevelException {
473 * throw new LowLevelException();
474 * }
475 * }
476 *
477 * class HighLevelException extends Exception {
478 * HighLevelException(Throwable cause) { super(cause); }
479 * }
480 *
481 * class MidLevelException extends Exception {
482 * MidLevelException(Throwable cause) { super(cause); }
483 * }
484 *
485 * class LowLevelException extends Exception {
486 * }
487 * </pre>
488 * As of release 7, the platform supports the notion of
489 * <i>suppressed exceptions</i> (in conjunction with automatic
490 * resource management blocks). Any exceptions that were
491 * suppressed in order to deliver an exception are printed out
492 * beneath the stack trace. The format of this information
493 * depends on the implementation, but the following example may be
494 * regarded as typical:
495 *
496 * <pre>
497 * Exception in thread "main" java.lang.Exception: Something happened
498 * at Foo.bar(Foo.java:10)
499 * at Foo.main(Foo.java:5)
500 * Suppressed: Resource$CloseFailException: Resource ID = 0
501 * at Resource.close(Resource.java:26)
502 * at Foo.bar(Foo.java:9)
503 * ... 1 more
504 * </pre>
505 * Note that the "... n more" notation is used on suppressed exceptions
506 * just at it is used on causes. Unlike causes, suppressed exceptions are
507 * indented beyond their "containing exceptions."
508 *
509 * <p>An exception can have both a cause and one or more suppressed
510 * exceptions:
511 * <pre>
512 * Exception in thread "main" java.lang.Exception: Main block
513 * at Foo3.main(Foo3.java:7)
514 * Suppressed: Resource$CloseFailException: Resource ID = 2
515 * at Resource.close(Resource.java:26)
516 * at Foo3.main(Foo3.java:5)
517 * Suppressed: Resource$CloseFailException: Resource ID = 1
518 * at Resource.close(Resource.java:26)
519 * at Foo3.main(Foo3.java:5)
520 * Caused by: java.lang.Exception: I did it
521 * at Foo3.main(Foo3.java:8)
522 * </pre>
523 * Likewise, a suppressed exception can have a cause:
524 * <pre>
525 * Exception in thread "main" java.lang.Exception: Main block
526 * at Foo4.main(Foo4.java:6)
527 * Suppressed: Resource2$CloseFailException: Resource ID = 1
528 * at Resource2.close(Resource2.java:20)
529 * at Foo4.main(Foo4.java:5)
530 * Caused by: java.lang.Exception: Rats, you caught me
531 * at Resource2$CloseFailException.<init>(Resource2.java:45)
532 * ... 2 more
533 * </pre>
534 */
535 public void printStackTrace() {
536 printStackTrace(System.err);
537 }
538
539 /**
540 * Prints this throwable and its backtrace to the specified print stream.
541 *
542 * @param s <code>PrintStream</code> to use for output
543 */
544 public void printStackTrace(PrintStream s) {
545 printStackTrace(new WrappedPrintStream(s));
546 }
547
548 private void printStackTrace(PrintStreamOrWriter s) {
549 Set<Throwable> dejaVu = new HashSet<Throwable>();
550 dejaVu.add(this);
551
552 synchronized (s.lock()) {
553 // Print our stack trace
554 s.println(this);
555 StackTraceElement[] trace = getOurStackTrace();
556 for (StackTraceElement traceElement : trace)
557 s.println("\tat " + traceElement);
558
559 // Print suppressed exceptions, if any
560 for (Throwable se : suppressedExceptions)
561 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
562
563 // Print cause, if any
564 Throwable ourCause = getCause();
565 if (ourCause != null)
566 ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
567 }
568 }
569
570 /**
571 * Print our stack trace as an enclosed exception for the specified
572 * stack trace.
573 */
574 private void printEnclosedStackTrace(PrintStreamOrWriter s,
575 StackTraceElement[] enclosingTrace,
576 String caption,
577 String prefix,
578 Set<Throwable> dejaVu) {
579 assert Thread.holdsLock(s.lock());
580 if (dejaVu.contains(this)) {
581 s.println("\t[/* Circularly referenced exception */ " +
582 this.toString() + "]");
583 } else {
584 dejaVu.add(this);
585 // Compute number of frames in common between this and enclosing trace
586 StackTraceElement[] trace = getOurStackTrace();
587 int m = trace.length-1, n = enclosingTrace.length-1;
588 while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
589 m--; n--;
590 }
591 int framesInCommon = trace.length - 1 - m;
592
593 // Print our stack trace
594 s.println(prefix + caption + this);
595 for (int i = 0; i <= m; i++)
596 s.println(prefix + "\tat " + trace[i]);
597 if (framesInCommon != 0)
598 s.println(prefix + "\t... " + framesInCommon + " more");
599
600 // Print suppressed exceptions, if any
601 for (Throwable se : suppressedExceptions)
602 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
603 prefix +"\t", dejaVu);
604
605 // Print cause, if any
606 Throwable ourCause = getCause();
607 if (ourCause != null)
608 ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
609 }
610 }
611
612 /**
613 * Prints this throwable and its backtrace to the specified
614 * print writer.
615 *
616 * @param s <code>PrintWriter</code> to use for output
617 * @since JDK1.1
618 */
619 public void printStackTrace(PrintWriter s) {
620 printStackTrace(new WrappedPrintWriter(s));
621 }
622
623 /**
624 * Wrapper class for PrintStream and PrintWirter to enable a single
625 * implementation of printStackTrace.
626 */
627 private abstract static class PrintStreamOrWriter {
628 /** Returns the object to be locked when using this StreamOrWriter */
629 abstract Object lock();
630
631 /** Prints the specified string as a line on this StreamOrWriter */
632 abstract void println(Object o);
633 }
634
635 private static class WrappedPrintStream extends PrintStreamOrWriter {
636 private final PrintStream printStream;
637
638 WrappedPrintStream(PrintStream printStream) {
639 this.printStream = printStream;
640 }
641
642 Object lock() {
643 return printStream;
644 }
645
646 void println(Object o) {
647 printStream.println(o);
648 }
649 }
650
651 private static class WrappedPrintWriter extends PrintStreamOrWriter {
652 private final PrintWriter printWriter;
653
654 WrappedPrintWriter(PrintWriter printWriter) {
655 this.printWriter = printWriter;
656 }
657
658 Object lock() {
659 return printWriter;
660 }
661
662 void println(Object o) {
663 printWriter.println(o);
664 }
665 }
666
667 /**
668 * Fills in the execution stack trace. This method records within this
669 * <code>Throwable</code> object information about the current state of
670 * the stack frames for the current thread.
671 *
672 * @return a reference to this <code>Throwable</code> instance.
673 * @see java.lang.Throwable#printStackTrace()
674 */
675 public synchronized native Throwable fillInStackTrace();
676
677 /**
678 * Provides programmatic access to the stack trace information printed by
679 * {@link #printStackTrace()}. Returns an array of stack trace elements,
680 * each representing one stack frame. The zeroth element of the array
681 * (assuming the array's length is non-zero) represents the top of the
682 * stack, which is the last method invocation in the sequence. Typically,
683 * this is the point at which this throwable was created and thrown.
684 * The last element of the array (assuming the array's length is non-zero)
746
747 /**
748 * Returns the number of elements in the stack trace (or 0 if the stack
749 * trace is unavailable).
750 *
751 * package-protection for use by SharedSecrets.
752 */
753 native int getStackTraceDepth();
754
755 /**
756 * Returns the specified element of the stack trace.
757 *
758 * package-protection for use by SharedSecrets.
759 *
760 * @param index index of the element to return.
761 * @throws IndexOutOfBoundsException if <tt>index < 0 ||
762 * index >= getStackTraceDepth() </tt>
763 */
764 native StackTraceElement getStackTraceElement(int index);
765
766 private void readObject(java.io.ObjectInputStream s)
767 throws java.io.IOException, ClassNotFoundException {
768 s.defaultReadObject(); // read in all fields
769 List<Throwable> impressedExceptions = Collections.emptyList();
770 if (suppressedExceptions != null &&
771 !suppressedExceptions.isEmpty()) { // Copy Throwables to new list
772 impressedExceptions = new ArrayList<Throwable>();
773 for(Throwable t : suppressedExceptions) {
774 impressedExceptions.add(t);
775 }
776 }
777 suppressedExceptions = impressedExceptions;
778 }
779
780 private synchronized void writeObject(java.io.ObjectOutputStream s)
781 throws IOException
782 {
783 getOurStackTrace(); // Ensure that stackTrace field is initialized.
784 s.defaultWriteObject();
785 }
786
787 /**
788 * Adds the specified exception to the list of exceptions that
789 * were suppressed, typically by the automatic resource management
790 * statement, in order to deliver this exception.
791 *
792 * @param exception the exception to be added to the list of
793 * suppressed exceptions
794 * @throws NullPointerException if {@code exception} is null
795 * @since 1.7
796 */
797 public synchronized void addSuppressedException(Throwable exception) {
798 if (exception == null)
799 throw new NullPointerException();
800
801 if (suppressedExceptions.size() == 0)
802 suppressedExceptions = new ArrayList<Throwable>();
803 suppressedExceptions.add(exception);
804 }
805
806 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
807
808 /**
809 * Returns an array containing all of the exceptions that were
810 * suppressed, typically by the automatic resource management
811 * statement, in order to deliver this exception.
812 *
813 * @return an array containing all of the exceptions that were
814 * suppressed to deliver this exception.
815 * @since 1.7
816 */
817 public Throwable[] getSuppressedExceptions() {
818 return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
819 }
820 }
|