194 * initialized. 195 * 196 * @serial 197 * @since 1.4 198 */ 199 private Throwable cause = this; 200 201 /** 202 * The stack trace, as returned by {@link #getStackTrace()}. 203 * 204 * The field is initialized to a zero-length array. A {@code 205 * null} value of this field indicates subsequent calls to {@link 206 * #setStackTrace(StackTraceElement[])} and {@link 207 * #fillInStackTrace()} will be no-ops. 208 * 209 * @serial 210 * @since 1.4 211 */ 212 private StackTraceElement[] stackTrace = UNASSIGNED_STACK; 213 214 // Setting this static field introduces an acceptable 215 // initialization dependency on a few java.util classes. 216 private static final List<Throwable> SUPPRESSED_SENTINEL = Collections.emptyList(); 217 218 /** 219 * The list of suppressed exceptions, as returned by {@link 220 * #getSuppressed()}. The list is initialized to a zero-element 221 * unmodifiable sentinel list. When a serialized Throwable is 222 * read in, if the {@code suppressedExceptions} field points to a 223 * zero-element list, the field is reset to the sentinel value. 224 * 225 * @serial 226 * @since 1.7 227 */ 228 private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL; 229 230 /** Message for trying to suppress a null exception. */ 231 private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception."; 232 233 /** Message for trying to suppress oneself. */ 811 * contain one element for every frame that would be printed by 812 * {@code printStackTrace}. Writes to the returned array do not 813 * affect future calls to this method. 814 * 815 * @return an array of stack trace elements representing the stack trace 816 * pertaining to this throwable. 817 * @since 1.4 818 */ 819 public StackTraceElement[] getStackTrace() { 820 return getOurStackTrace().clone(); 821 } 822 823 private synchronized StackTraceElement[] getOurStackTrace() { 824 // Initialize stack trace field with information from 825 // backtrace if this is the first call to this method 826 if (stackTrace == UNASSIGNED_STACK || 827 (stackTrace == null && backtrace != null) /* Out of protocol state */) { 828 if (backtrace instanceof StackStreamFactory.StackTrace) { 829 stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements(); 830 } else { 831 int depth = getStackTraceDepth(); 832 stackTrace = new StackTraceElement[depth]; 833 for (int i = 0; i < depth; i++) 834 stackTrace[i] = getStackTraceElement(i); 835 } 836 } else if (stackTrace == null) { 837 return UNASSIGNED_STACK; 838 } 839 return stackTrace; 840 } 841 842 /** 843 * Sets the stack trace elements that will be returned by 844 * {@link #getStackTrace()} and printed by {@link #printStackTrace()} 845 * and related methods. 846 * 847 * This method, which is designed for use by RPC frameworks and other 848 * advanced systems, allows the client to override the default 849 * stack trace that is either generated by {@link #fillInStackTrace()} 850 * when a throwable is constructed or deserialized when a throwable is 851 * read from a serialization stream. 852 * 853 * <p>If the stack trace of this {@code Throwable} {@linkplain 854 * Throwable#Throwable(String, Throwable, boolean, boolean) is not 867 * 868 * @since 1.4 869 */ 870 public void setStackTrace(StackTraceElement[] stackTrace) { 871 // Validate argument 872 StackTraceElement[] defensiveCopy = stackTrace.clone(); 873 for (int i = 0; i < defensiveCopy.length; i++) { 874 if (defensiveCopy[i] == null) 875 throw new NullPointerException("stackTrace[" + i + "]"); 876 } 877 878 synchronized (this) { 879 if (this.stackTrace == null && // Immutable stack 880 backtrace == null) // Test for out of protocol state 881 return; 882 this.stackTrace = defensiveCopy; 883 } 884 } 885 886 /** 887 * Returns the number of elements in the stack trace (or 0 if the stack 888 * trace is unavailable). 889 * 890 * package-protection for use by SharedSecrets. 891 */ 892 native int getStackTraceDepth(); 893 894 /** 895 * Returns the specified element of the stack trace. 896 * 897 * package-protection for use by SharedSecrets. 898 * 899 * @param index index of the element to return. 900 * @throws IndexOutOfBoundsException if {@code index < 0 || 901 * index >= getStackTraceDepth() } 902 */ 903 native StackTraceElement getStackTraceElement(int index); 904 905 /** 906 * Reads a {@code Throwable} from a stream, enforcing 907 * well-formedness constraints on fields. Null entries and 908 * self-pointers are not allowed in the list of {@code 909 * suppressedExceptions}. Null entries are not allowed for stack 910 * trace elements. A null stack trace in the serial form results 911 * in a zero-length stack element array. A single-element stack 912 * trace whose entry is equal to {@code new StackTraceElement("", 913 * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code 914 * stackTrace} field. 915 * 916 * Note that there are no constraints on the value the {@code 917 * cause} field can hold; both {@code null} and {@code this} are 918 * valid values for the field. 919 */ 920 private void readObject(ObjectInputStream s) 921 throws IOException, ClassNotFoundException { 922 s.defaultReadObject(); // read in all fields 923 if (suppressedExceptions != null) { | 194 * initialized. 195 * 196 * @serial 197 * @since 1.4 198 */ 199 private Throwable cause = this; 200 201 /** 202 * The stack trace, as returned by {@link #getStackTrace()}. 203 * 204 * The field is initialized to a zero-length array. A {@code 205 * null} value of this field indicates subsequent calls to {@link 206 * #setStackTrace(StackTraceElement[])} and {@link 207 * #fillInStackTrace()} will be no-ops. 208 * 209 * @serial 210 * @since 1.4 211 */ 212 private StackTraceElement[] stackTrace = UNASSIGNED_STACK; 213 214 /** 215 * Native code sets the depth of the backtrace for later retrieval 216 */ 217 private transient int depth; 218 219 // Setting this static field introduces an acceptable 220 // initialization dependency on a few java.util classes. 221 private static final List<Throwable> SUPPRESSED_SENTINEL = Collections.emptyList(); 222 223 /** 224 * The list of suppressed exceptions, as returned by {@link 225 * #getSuppressed()}. The list is initialized to a zero-element 226 * unmodifiable sentinel list. When a serialized Throwable is 227 * read in, if the {@code suppressedExceptions} field points to a 228 * zero-element list, the field is reset to the sentinel value. 229 * 230 * @serial 231 * @since 1.7 232 */ 233 private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL; 234 235 /** Message for trying to suppress a null exception. */ 236 private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception."; 237 238 /** Message for trying to suppress oneself. */ 816 * contain one element for every frame that would be printed by 817 * {@code printStackTrace}. Writes to the returned array do not 818 * affect future calls to this method. 819 * 820 * @return an array of stack trace elements representing the stack trace 821 * pertaining to this throwable. 822 * @since 1.4 823 */ 824 public StackTraceElement[] getStackTrace() { 825 return getOurStackTrace().clone(); 826 } 827 828 private synchronized StackTraceElement[] getOurStackTrace() { 829 // Initialize stack trace field with information from 830 // backtrace if this is the first call to this method 831 if (stackTrace == UNASSIGNED_STACK || 832 (stackTrace == null && backtrace != null) /* Out of protocol state */) { 833 if (backtrace instanceof StackStreamFactory.StackTrace) { 834 stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements(); 835 } else { 836 stackTrace = new StackTraceElement[depth]; 837 for (int i = 0; i < depth; i++) { 838 stackTrace[i] = new StackTraceElement(); 839 } 840 getStackTraceElements(stackTrace); 841 } 842 } else if (stackTrace == null) { 843 return UNASSIGNED_STACK; 844 } 845 return stackTrace; 846 } 847 848 /** 849 * Sets the stack trace elements that will be returned by 850 * {@link #getStackTrace()} and printed by {@link #printStackTrace()} 851 * and related methods. 852 * 853 * This method, which is designed for use by RPC frameworks and other 854 * advanced systems, allows the client to override the default 855 * stack trace that is either generated by {@link #fillInStackTrace()} 856 * when a throwable is constructed or deserialized when a throwable is 857 * read from a serialization stream. 858 * 859 * <p>If the stack trace of this {@code Throwable} {@linkplain 860 * Throwable#Throwable(String, Throwable, boolean, boolean) is not 873 * 874 * @since 1.4 875 */ 876 public void setStackTrace(StackTraceElement[] stackTrace) { 877 // Validate argument 878 StackTraceElement[] defensiveCopy = stackTrace.clone(); 879 for (int i = 0; i < defensiveCopy.length; i++) { 880 if (defensiveCopy[i] == null) 881 throw new NullPointerException("stackTrace[" + i + "]"); 882 } 883 884 synchronized (this) { 885 if (this.stackTrace == null && // Immutable stack 886 backtrace == null) // Test for out of protocol state 887 return; 888 this.stackTrace = defensiveCopy; 889 } 890 } 891 892 /** 893 * @param elements 894 * @throws IndexOutOfBoundsException if {@code elements.length != depth } 895 */ 896 private native void getStackTraceElements(StackTraceElement[] elements); 897 898 /** 899 * Reads a {@code Throwable} from a stream, enforcing 900 * well-formedness constraints on fields. Null entries and 901 * self-pointers are not allowed in the list of {@code 902 * suppressedExceptions}. Null entries are not allowed for stack 903 * trace elements. A null stack trace in the serial form results 904 * in a zero-length stack element array. A single-element stack 905 * trace whose entry is equal to {@code new StackTraceElement("", 906 * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code 907 * stackTrace} field. 908 * 909 * Note that there are no constraints on the value the {@code 910 * cause} field can hold; both {@code null} and {@code this} are 911 * valid values for the field. 912 */ 913 private void readObject(ObjectInputStream s) 914 throws IOException, ClassNotFoundException { 915 s.defaultReadObject(); // read in all fields 916 if (suppressedExceptions != null) { |