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 /** Message for trying to suppress a null exception. */
206 private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
207
208 /** Caption for labeling causative exception stack traces */
209 private static final String CAUSE_CAPTION = "Caused by: ";
210
211 /** Caption for labeling suppressed exception stack traces */
212 private static final String SUPPRESSED_CAPTION = "Suppressed: ";
213
214 /**
215 * Constructs a new throwable with <code>null</code> as its detail message.
216 * The cause is not initialized, and may subsequently be initialized by a
217 * call to {@link #initCause}.
218 *
219 * <p>The {@link #fillInStackTrace()} method is called to initialize
220 * the stack trace data in the newly created throwable.
221 */
222 public Throwable() {
223 fillInStackTrace();
224 }
225
226 /**
227 * Constructs a new throwable with the specified detail message. The
228 * cause is not initialized, and may subsequently be initialized by
229 * a call to {@link #initCause}.
230 *
231 * <p>The {@link #fillInStackTrace()} method is called to initialize
232 * the stack trace data in the newly created throwable.
233 *
234 * @param message the detail message. The detail message is saved for
471 * }
472 * static void d() throws LowLevelException {
473 * e();
474 * }
475 * static void e() throws LowLevelException {
476 * throw new LowLevelException();
477 * }
478 * }
479 *
480 * class HighLevelException extends Exception {
481 * HighLevelException(Throwable cause) { super(cause); }
482 * }
483 *
484 * class MidLevelException extends Exception {
485 * MidLevelException(Throwable cause) { super(cause); }
486 * }
487 *
488 * class LowLevelException extends Exception {
489 * }
490 * </pre>
491 * As of release 7, the platform supports the notion of
492 * <i>suppressed exceptions</i> (in conjunction with automatic
493 * resource management blocks). Any exceptions that were
494 * suppressed in order to deliver an exception are printed out
495 * beneath the stack trace. The format of this information
496 * depends on the implementation, but the following example may be
497 * regarded as typical:
498 *
499 * <pre>
500 * Exception in thread "main" java.lang.Exception: Something happened
501 * at Foo.bar(Foo.java:10)
502 * at Foo.main(Foo.java:5)
503 * Suppressed: Resource$CloseFailException: Resource ID = 0
504 * at Resource.close(Resource.java:26)
505 * at Foo.bar(Foo.java:9)
506 * ... 1 more
507 * </pre>
508 * Note that the "... n more" notation is used on suppressed exceptions
509 * just at it is used on causes. Unlike causes, suppressed exceptions are
510 * indented beyond their "containing exceptions."
511 *
512 * <p>An exception can have both a cause and one or more suppressed
513 * exceptions:
514 * <pre>
515 * Exception in thread "main" java.lang.Exception: Main block
516 * at Foo3.main(Foo3.java:7)
517 * Suppressed: Resource$CloseFailException: Resource ID = 2
518 * at Resource.close(Resource.java:26)
519 * at Foo3.main(Foo3.java:5)
520 * Suppressed: Resource$CloseFailException: Resource ID = 1
521 * at Resource.close(Resource.java:26)
522 * at Foo3.main(Foo3.java:5)
523 * Caused by: java.lang.Exception: I did it
524 * at Foo3.main(Foo3.java:8)
525 * </pre>
526 * Likewise, a suppressed exception can have a cause:
527 * <pre>
528 * Exception in thread "main" java.lang.Exception: Main block
529 * at Foo4.main(Foo4.java:6)
530 * Suppressed: Resource2$CloseFailException: Resource ID = 1
531 * at Resource2.close(Resource2.java:20)
532 * at Foo4.main(Foo4.java:5)
533 * Caused by: java.lang.Exception: Rats, you caught me
534 * at Resource2$CloseFailException.<init>(Resource2.java:45)
535 * ... 2 more
536 * </pre>
537 */
538 public void printStackTrace() {
539 printStackTrace(System.err);
540 }
541
542 /**
543 * Prints this throwable and its backtrace to the specified print stream.
544 *
545 * @param s <code>PrintStream</code> to use for output
546 */
547 public void printStackTrace(PrintStream s) {
548 printStackTrace(new WrappedPrintStream(s));
549 }
550
551 private void printStackTrace(PrintStreamOrWriter s) {
552 Set<Throwable> dejaVu = new HashSet<Throwable>();
553 dejaVu.add(this);
554
555 synchronized (s.lock()) {
556 // Print our stack trace
557 s.println(this);
558 StackTraceElement[] trace = getOurStackTrace();
559 for (StackTraceElement traceElement : trace)
560 s.println("\tat " + traceElement);
561
562 // Print suppressed exceptions, if any
563 for (Throwable se : suppressedExceptions)
564 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
565
566 // Print cause, if any
567 Throwable ourCause = getCause();
568 if (ourCause != null)
569 ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
570 }
571 }
572
573 /**
574 * Print our stack trace as an enclosed exception for the specified
575 * stack trace.
576 */
577 private void printEnclosedStackTrace(PrintStreamOrWriter s,
578 StackTraceElement[] enclosingTrace,
579 String caption,
580 String prefix,
581 Set<Throwable> dejaVu) {
582 assert Thread.holdsLock(s.lock());
583 if (dejaVu.contains(this)) {
584 s.println("\t[CIRCULAR REFERENCE:" + this + "]");
585 } else {
586 dejaVu.add(this);
587 // Compute number of frames in common between this and enclosing trace
588 StackTraceElement[] trace = getOurStackTrace();
589 int m = trace.length - 1;
590 int n = enclosingTrace.length - 1;
591 while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
592 m--; n--;
593 }
594 int framesInCommon = trace.length - 1 - m;
595
596 // Print our stack trace
597 s.println(prefix + caption + this);
598 for (int i = 0; i <= m; i++)
599 s.println(prefix + "\tat " + trace[i]);
600 if (framesInCommon != 0)
601 s.println(prefix + "\t... " + framesInCommon + " more");
602
603 // Print suppressed exceptions, if any
604 for (Throwable se : suppressedExceptions)
605 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
606 prefix +"\t", dejaVu);
607
608 // Print cause, if any
609 Throwable ourCause = getCause();
610 if (ourCause != null)
611 ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
612 }
613 }
614
615 /**
616 * Prints this throwable and its backtrace to the specified
617 * print writer.
618 *
619 * @param s <code>PrintWriter</code> to use for output
620 * @since JDK1.1
621 */
622 public void printStackTrace(PrintWriter s) {
623 printStackTrace(new WrappedPrintWriter(s));
624 }
625
626 /**
627 * Wrapper class for PrintStream and PrintWriter to enable a single
628 * implementation of printStackTrace.
629 */
630 private abstract static class PrintStreamOrWriter {
631 /** Returns the object to be locked when using this StreamOrWriter */
632 abstract Object lock();
633
634 /** Prints the specified string as a line on this StreamOrWriter */
635 abstract void println(Object o);
636 }
637
638 private static class WrappedPrintStream extends PrintStreamOrWriter {
639 private final PrintStream printStream;
640
641 WrappedPrintStream(PrintStream printStream) {
642 this.printStream = printStream;
643 }
644
645 Object lock() {
646 return printStream;
647 }
648
649 void println(Object o) {
650 printStream.println(o);
651 }
652 }
653
654 private static class WrappedPrintWriter extends PrintStreamOrWriter {
655 private final PrintWriter printWriter;
656
657 WrappedPrintWriter(PrintWriter printWriter) {
658 this.printWriter = printWriter;
659 }
660
661 Object lock() {
662 return printWriter;
663 }
664
665 void println(Object o) {
666 printWriter.println(o);
667 }
668 }
669
670 /**
671 * Fills in the execution stack trace. This method records within this
672 * <code>Throwable</code> object information about the current state of
673 * the stack frames for the current thread.
674 *
675 * @return a reference to this <code>Throwable</code> instance.
676 * @see java.lang.Throwable#printStackTrace()
677 */
678 public synchronized native Throwable fillInStackTrace();
679
680 /**
681 * Provides programmatic access to the stack trace information printed by
682 * {@link #printStackTrace()}. Returns an array of stack trace elements,
683 * each representing one stack frame. The zeroth element of the array
684 * (assuming the array's length is non-zero) represents the top of the
685 * stack, which is the last method invocation in the sequence. Typically,
686 * this is the point at which this throwable was created and thrown.
687 * The last element of the array (assuming the array's length is non-zero)
749
750 /**
751 * Returns the number of elements in the stack trace (or 0 if the stack
752 * trace is unavailable).
753 *
754 * package-protection for use by SharedSecrets.
755 */
756 native int getStackTraceDepth();
757
758 /**
759 * Returns the specified element of the stack trace.
760 *
761 * package-protection for use by SharedSecrets.
762 *
763 * @param index index of the element to return.
764 * @throws IndexOutOfBoundsException if <tt>index < 0 ||
765 * index >= getStackTraceDepth() </tt>
766 */
767 native StackTraceElement getStackTraceElement(int index);
768
769 private void readObject(ObjectInputStream s)
770 throws IOException, ClassNotFoundException {
771 s.defaultReadObject(); // read in all fields
772 List<Throwable> suppressed = Collections.emptyList();
773 if (suppressedExceptions != null &&
774 !suppressedExceptions.isEmpty()) { // Copy Throwables to new list
775 suppressed = new ArrayList<Throwable>();
776 for(Throwable t : suppressedExceptions) {
777 if (t == null)
778 throw new NullPointerException(NULL_CAUSE_MESSAGE);
779 suppressed.add(t);
780 }
781 }
782 suppressedExceptions = suppressed;
783 }
784
785 private synchronized void writeObject(ObjectOutputStream s)
786 throws IOException
787 {
788 getOurStackTrace(); // Ensure that stackTrace field is initialized.
789 s.defaultWriteObject();
790 }
791
792 /**
793 * Adds the specified exception to the list of exceptions that
794 * were suppressed, typically by the automatic resource management
795 * statement, in order to deliver this exception.
796 *
797 * @param exception the exception to be added to the list of
798 * suppressed exceptions
799 * @throws NullPointerException if {@code exception} is null
800 * @since 1.7
801 */
802 public synchronized void addSuppressedException(Throwable exception) {
803 if (exception == null)
804 throw new NullPointerException(NULL_CAUSE_MESSAGE);
805
806 if (suppressedExceptions.size() == 0)
807 suppressedExceptions = new ArrayList<Throwable>();
808 suppressedExceptions.add(exception);
809 }
810
811 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
812
813 /**
814 * Returns an array containing all of the exceptions that were
815 * suppressed, typically by the automatic resource management
816 * statement, in order to deliver this exception.
817 *
818 * @return an array containing all of the exceptions that were
819 * suppressed to deliver this exception.
820 * @since 1.7
821 */
822 public Throwable[] getSuppressedExceptions() {
823 return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
824 }
825 }
|