< prev index next >

src/java.base/share/classes/java/lang/Throwable.java

Print this page

  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 
  28 import java.io.*;
  29 import java.util.*;


  30 
  31 /**
  32  * The {@code Throwable} class is the superclass of all errors and
  33  * exceptions in the Java language. Only objects that are instances of this
  34  * class (or one of its subclasses) are thrown by the Java Virtual Machine or
  35  * can be thrown by the Java {@code throw} statement. Similarly, only
  36  * this class or one of its subclasses can be the argument type in a
  37  * {@code catch} clause.
  38  *
  39  * For the purposes of compile-time checking of exceptions, {@code
  40  * Throwable} and any subclass of {@code Throwable} that is not also a
  41  * subclass of either {@link RuntimeException} or {@link Error} are
  42  * regarded as checked exceptions.
  43  *
  44  * <p>Instances of two subclasses, {@link java.lang.Error} and
  45  * {@link java.lang.Exception}, are conventionally used to indicate
  46  * that exceptional situations have occurred. Typically, these instances
  47  * are freshly created in the context of the exceptional situation so
  48  * as to include relevant information (such as stack trace data).
  49  *

 642      *                 at Foo4.main(Foo4.java:5)
 643      *         Caused by: java.lang.Exception: Rats, you caught me
 644      *                 at Resource2$CloseFailException.&lt;init&gt;(Resource2.java:45)
 645      *                 ... 2 more
 646      * </pre>
 647      */
 648     public void printStackTrace() {
 649         printStackTrace(System.err);
 650     }
 651 
 652     /**
 653      * Prints this throwable and its backtrace to the specified print stream.
 654      *
 655      * @param s {@code PrintStream} to use for output
 656      */
 657     public void printStackTrace(PrintStream s) {
 658         printStackTrace(new WrappedPrintStream(s));
 659     }
 660 
 661     private void printStackTrace(PrintStreamOrWriter s) {














 662         // Guard against malicious overrides of Throwable.equals by
 663         // using a Set with identity equality semantics.
 664         Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<>());
 665         dejaVu.add(this);
 666 
 667         synchronized (s.lock()) {
 668             // Print our stack trace
 669             s.println(this);
 670             StackTraceElement[] trace = getOurStackTrace();
 671             for (StackTraceElement traceElement : trace)
 672                 s.println("\tat " + traceElement);
 673 
 674             // Print suppressed exceptions, if any
 675             for (Throwable se : getSuppressed())
 676                 se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
 677 
 678             // Print cause, if any
 679             Throwable ourCause = getCause();
 680             if (ourCause != null)
 681                 ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
 682         }
 683     }
 684 
 685     /**
 686      * Print our stack trace as an enclosed exception for the specified
 687      * stack trace.
 688      */
 689     private void printEnclosedStackTrace(PrintStreamOrWriter s,
 690                                          StackTraceElement[] enclosingTrace,
 691                                          String caption,
 692                                          String prefix,
 693                                          Set<Throwable> dejaVu) {
 694         assert Thread.holdsLock(s.lock());
 695         if (dejaVu.contains(this)) {
 696             s.println(prefix + caption + "[CIRCULAR REFERENCE: " + this + "]");
 697         } else {
 698             dejaVu.add(this);
 699             // Compute number of frames in common between this and enclosing trace
 700             StackTraceElement[] trace = getOurStackTrace();
 701             int m = trace.length - 1;
 702             int n = enclosingTrace.length - 1;
 703             while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
 704                 m--; n--;
 705             }
 706             int framesInCommon = trace.length - 1 - m;
 707 
 708             // Print our stack trace
 709             s.println(prefix + caption + this);
 710             for (int i = 0; i <= m; i++)
 711                 s.println(prefix + "\tat " + trace[i]);
 712             if (framesInCommon != 0)
 713                 s.println(prefix + "\t... " + framesInCommon + " more");
 714 

 726 
 727     /**
 728      * Prints this throwable and its backtrace to the specified
 729      * print writer.
 730      *
 731      * @param s {@code PrintWriter} to use for output
 732      * @since   1.1
 733      */
 734     public void printStackTrace(PrintWriter s) {
 735         printStackTrace(new WrappedPrintWriter(s));
 736     }
 737 
 738     /**
 739      * Wrapper class for PrintStream and PrintWriter to enable a single
 740      * implementation of printStackTrace.
 741      */
 742     private abstract static class PrintStreamOrWriter {
 743         /** Returns the object to be locked when using this StreamOrWriter */
 744         abstract Object lock();
 745 









 746         /** Prints the specified string as a line on this StreamOrWriter */
 747         abstract void println(Object o);
 748     }
 749 
 750     private static class WrappedPrintStream extends PrintStreamOrWriter {
 751         private final PrintStream printStream;
 752 
 753         WrappedPrintStream(PrintStream printStream) {
 754             this.printStream = printStream;
 755         }
 756 
 757         Object lock() {
 758             return printStream;
 759         }
 760 
 761         void println(Object o) {
 762             printStream.println(o);
 763         }
 764     }
 765 
 766     private static class WrappedPrintWriter extends PrintStreamOrWriter {
 767         private final PrintWriter printWriter;
 768 
 769         WrappedPrintWriter(PrintWriter printWriter) {
 770             this.printWriter = printWriter;
 771         }
 772 
 773         Object lock() {
 774             return printWriter;
 775         }
 776 
 777         void println(Object o) {
 778             printWriter.println(o);
 779         }
 780     }
 781 
 782     /**
 783      * Fills in the execution stack trace. This method records within this
 784      * {@code Throwable} object information about the current state of
 785      * the stack frames for the current thread.
 786      *
 787      * <p>If the stack trace of this {@code Throwable} {@linkplain
 788      * Throwable#Throwable(String, Throwable, boolean, boolean) is not
 789      * writable}, calling this method has no effect.
 790      *
 791      * @return  a reference to this {@code Throwable} instance.
 792      * @see     java.lang.Throwable#printStackTrace()
 793      */
 794     public synchronized Throwable fillInStackTrace() {

 816      * <p>Some virtual machines may, under some circumstances, omit one
 817      * or more stack frames from the stack trace.  In the extreme case,
 818      * a virtual machine that has no stack trace information concerning
 819      * this throwable is permitted to return a zero-length array from this
 820      * method.  Generally speaking, the array returned by this method will
 821      * contain one element for every frame that would be printed by
 822      * {@code printStackTrace}.  Writes to the returned array do not
 823      * affect future calls to this method.
 824      *
 825      * @return an array of stack trace elements representing the stack trace
 826      *         pertaining to this throwable.
 827      * @since  1.4
 828      */
 829     public StackTraceElement[] getStackTrace() {
 830         return getOurStackTrace().clone();
 831     }
 832 
 833     private synchronized StackTraceElement[] getOurStackTrace() {
 834         // Initialize stack trace field with information from
 835         // backtrace if this is the first call to this method
 836         if (stackTrace == UNASSIGNED_STACK ||
 837             (stackTrace == null && backtrace != null) /* Out of protocol state */) {
 838             stackTrace = StackTraceElement.of(this, depth);
 839         } else if (stackTrace == null) {
 840             return UNASSIGNED_STACK;


 841         }
 842         return stackTrace;
 843     }
 844 
 845     /**
 846      * Sets the stack trace elements that will be returned by
 847      * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
 848      * and related methods.
 849      *
 850      * This method, which is designed for use by RPC frameworks and other
 851      * advanced systems, allows the client to override the default
 852      * stack trace that is either generated by {@link #fillInStackTrace()}
 853      * when a throwable is constructed or deserialized when a throwable is
 854      * read from a serialization stream.
 855      *
 856      * <p>If the stack trace of this {@code Throwable} {@linkplain
 857      * Throwable#Throwable(String, Throwable, boolean, boolean) is not
 858      * writable}, calling this method has no effect other than
 859      * validating its argument.
 860      *

  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 
  28 import java.io.*;
  29 import java.util.*;
  30 import jdk.internal.access.SharedSecrets;
  31 import jdk.internal.misc.InternalLock;
  32 
  33 /**
  34  * The {@code Throwable} class is the superclass of all errors and
  35  * exceptions in the Java language. Only objects that are instances of this
  36  * class (or one of its subclasses) are thrown by the Java Virtual Machine or
  37  * can be thrown by the Java {@code throw} statement. Similarly, only
  38  * this class or one of its subclasses can be the argument type in a
  39  * {@code catch} clause.
  40  *
  41  * For the purposes of compile-time checking of exceptions, {@code
  42  * Throwable} and any subclass of {@code Throwable} that is not also a
  43  * subclass of either {@link RuntimeException} or {@link Error} are
  44  * regarded as checked exceptions.
  45  *
  46  * <p>Instances of two subclasses, {@link java.lang.Error} and
  47  * {@link java.lang.Exception}, are conventionally used to indicate
  48  * that exceptional situations have occurred. Typically, these instances
  49  * are freshly created in the context of the exceptional situation so
  50  * as to include relevant information (such as stack trace data).
  51  *

 644      *                 at Foo4.main(Foo4.java:5)
 645      *         Caused by: java.lang.Exception: Rats, you caught me
 646      *                 at Resource2$CloseFailException.&lt;init&gt;(Resource2.java:45)
 647      *                 ... 2 more
 648      * </pre>
 649      */
 650     public void printStackTrace() {
 651         printStackTrace(System.err);
 652     }
 653 
 654     /**
 655      * Prints this throwable and its backtrace to the specified print stream.
 656      *
 657      * @param s {@code PrintStream} to use for output
 658      */
 659     public void printStackTrace(PrintStream s) {
 660         printStackTrace(new WrappedPrintStream(s));
 661     }
 662 
 663     private void printStackTrace(PrintStreamOrWriter s) {
 664         Object lock = s.lock();
 665         if (lock instanceof InternalLock locker) {
 666             locker.lock();
 667             try {
 668                 lockedPrintStackTrace(s);
 669             } finally {
 670                 locker.unlock();
 671             }
 672         } else synchronized (lock) {
 673             lockedPrintStackTrace(s);
 674         }
 675     }
 676 
 677     private void lockedPrintStackTrace(PrintStreamOrWriter s) {
 678         // Guard against malicious overrides of Throwable.equals by
 679         // using a Set with identity equality semantics.
 680         Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<>());
 681         dejaVu.add(this);
 682 
 683         // Print our stack trace
 684         s.println(this);
 685         StackTraceElement[] trace = getOurStackTrace();
 686         for (StackTraceElement traceElement : trace)
 687             s.println("\tat " + traceElement);

 688 
 689         // Print suppressed exceptions, if any
 690         for (Throwable se : getSuppressed())
 691             se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
 692 
 693         // Print cause, if any
 694         Throwable ourCause = getCause();
 695         if (ourCause != null)
 696             ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);

 697     }
 698 
 699     /**
 700      * Print our stack trace as an enclosed exception for the specified
 701      * stack trace.
 702      */
 703     private void printEnclosedStackTrace(PrintStreamOrWriter s,
 704                                          StackTraceElement[] enclosingTrace,
 705                                          String caption,
 706                                          String prefix,
 707                                          Set<Throwable> dejaVu) {
 708         assert s.isLockedByCurrentThread();
 709         if (dejaVu.contains(this)) {
 710             s.println(prefix + caption + "[CIRCULAR REFERENCE: " + this + "]");
 711         } else {
 712             dejaVu.add(this);
 713             // Compute number of frames in common between this and enclosing trace
 714             StackTraceElement[] trace = getOurStackTrace();
 715             int m = trace.length - 1;
 716             int n = enclosingTrace.length - 1;
 717             while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
 718                 m--; n--;
 719             }
 720             int framesInCommon = trace.length - 1 - m;
 721 
 722             // Print our stack trace
 723             s.println(prefix + caption + this);
 724             for (int i = 0; i <= m; i++)
 725                 s.println(prefix + "\tat " + trace[i]);
 726             if (framesInCommon != 0)
 727                 s.println(prefix + "\t... " + framesInCommon + " more");
 728 

 740 
 741     /**
 742      * Prints this throwable and its backtrace to the specified
 743      * print writer.
 744      *
 745      * @param s {@code PrintWriter} to use for output
 746      * @since   1.1
 747      */
 748     public void printStackTrace(PrintWriter s) {
 749         printStackTrace(new WrappedPrintWriter(s));
 750     }
 751 
 752     /**
 753      * Wrapper class for PrintStream and PrintWriter to enable a single
 754      * implementation of printStackTrace.
 755      */
 756     private abstract static class PrintStreamOrWriter {
 757         /** Returns the object to be locked when using this StreamOrWriter */
 758         abstract Object lock();
 759 
 760         boolean isLockedByCurrentThread() {
 761             Object lock = lock();
 762             if (lock instanceof InternalLock locker) {
 763                 return locker.isHeldByCurrentThread();
 764             } else {
 765                 return Thread.holdsLock(lock);
 766             }
 767         }
 768 
 769         /** Prints the specified string as a line on this StreamOrWriter */
 770         abstract void println(Object o);
 771     }
 772 
 773     private static class WrappedPrintStream extends PrintStreamOrWriter {
 774         private final PrintStream printStream;
 775 
 776         WrappedPrintStream(PrintStream printStream) {
 777             this.printStream = printStream;
 778         }
 779 
 780         Object lock() {
 781             return SharedSecrets.getJavaIOPrintStreamAccess().lock(printStream);
 782         }
 783 
 784         void println(Object o) {
 785             printStream.println(o);
 786         }
 787     }
 788 
 789     private static class WrappedPrintWriter extends PrintStreamOrWriter {
 790         private final PrintWriter printWriter;
 791 
 792         WrappedPrintWriter(PrintWriter printWriter) {
 793             this.printWriter = printWriter;
 794         }
 795 
 796         Object lock() {
 797             return SharedSecrets.getJavaIOPrintWriterAccess().lock(printWriter);
 798         }
 799 
 800         void println(Object o) {
 801             printWriter.println(o);
 802         }
 803     }
 804 
 805     /**
 806      * Fills in the execution stack trace. This method records within this
 807      * {@code Throwable} object information about the current state of
 808      * the stack frames for the current thread.
 809      *
 810      * <p>If the stack trace of this {@code Throwable} {@linkplain
 811      * Throwable#Throwable(String, Throwable, boolean, boolean) is not
 812      * writable}, calling this method has no effect.
 813      *
 814      * @return  a reference to this {@code Throwable} instance.
 815      * @see     java.lang.Throwable#printStackTrace()
 816      */
 817     public synchronized Throwable fillInStackTrace() {

 839      * <p>Some virtual machines may, under some circumstances, omit one
 840      * or more stack frames from the stack trace.  In the extreme case,
 841      * a virtual machine that has no stack trace information concerning
 842      * this throwable is permitted to return a zero-length array from this
 843      * method.  Generally speaking, the array returned by this method will
 844      * contain one element for every frame that would be printed by
 845      * {@code printStackTrace}.  Writes to the returned array do not
 846      * affect future calls to this method.
 847      *
 848      * @return an array of stack trace elements representing the stack trace
 849      *         pertaining to this throwable.
 850      * @since  1.4
 851      */
 852     public StackTraceElement[] getStackTrace() {
 853         return getOurStackTrace().clone();
 854     }
 855 
 856     private synchronized StackTraceElement[] getOurStackTrace() {
 857         // Initialize stack trace field with information from
 858         // backtrace if this is the first call to this method
 859         if (stackTrace == UNASSIGNED_STACK || stackTrace == null) {
 860             if (backtrace != null) { /* Out of protocol state */
 861                 stackTrace = StackTraceElement.of(backtrace, depth);
 862             } else {
 863                 // no backtrace, fillInStackTrace overridden or not called
 864                 return UNASSIGNED_STACK;
 865             }
 866         }
 867         return stackTrace;
 868     }
 869 
 870     /**
 871      * Sets the stack trace elements that will be returned by
 872      * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
 873      * and related methods.
 874      *
 875      * This method, which is designed for use by RPC frameworks and other
 876      * advanced systems, allows the client to override the default
 877      * stack trace that is either generated by {@link #fillInStackTrace()}
 878      * when a throwable is constructed or deserialized when a throwable is
 879      * read from a serialization stream.
 880      *
 881      * <p>If the stack trace of this {@code Throwable} {@linkplain
 882      * Throwable#Throwable(String, Throwable, boolean, boolean) is not
 883      * writable}, calling this method has no effect other than
 884      * validating its argument.
 885      *
< prev index next >