1 /* 2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 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 28 import java.io.IOException; 29 import java.io.ObjectInputStream; 30 import java.io.ObjectOutputStream; 31 import java.io.ObjectStreamField; 32 33 /** 34 * Signals that an unexpected exception has occurred in a static initializer. 35 * An {@code ExceptionInInitializerError} is thrown to indicate that an 36 * exception occurred during evaluation of a static initializer or the 37 * initializer for a static variable. 38 * 39 * @author Frank Yellin 40 * @since 1.1 41 */ 42 public class ExceptionInInitializerError extends LinkageError { 43 /** 44 * Use serialVersionUID from JDK 1.1.X for interoperability 45 */ 46 @java.io.Serial 47 private static final long serialVersionUID = 1521711792217232256L; 48 49 /** 50 * Constructs an {@code ExceptionInInitializerError} with 51 * {@code null} as its detail message string and with no saved 52 * throwable object. 53 * A detail message is a String that describes this particular exception. 54 */ ExceptionInInitializerError()55 public ExceptionInInitializerError() { 56 initCause(null); // Disallow subsequent initCause 57 } 58 59 /** 60 * Constructs a new {@code ExceptionInInitializerError} class by 61 * saving a reference to the {@code Throwable} object thrown for 62 * later retrieval by the {@link #getException()} method. The detail 63 * message string is set to {@code null}. 64 * 65 * @param thrown The exception thrown 66 */ ExceptionInInitializerError(Throwable thrown)67 public ExceptionInInitializerError(Throwable thrown) { 68 super(null, thrown); // Disallow subsequent initCause 69 } 70 71 /** 72 * Constructs an {@code ExceptionInInitializerError} with the specified detail 73 * message string. A detail message is a String that describes this 74 * particular exception. The detail message string is saved for later 75 * retrieval by the {@link Throwable#getMessage()} method. There is no 76 * saved throwable object. 77 * 78 * @param s the detail message 79 */ ExceptionInInitializerError(String s)80 public ExceptionInInitializerError(String s) { 81 super(s, null); // Disallow subsequent initCause 82 } 83 84 /** 85 * Returns the exception that occurred during a static initialization that 86 * caused this error to be created. 87 * 88 * @apiNote 89 * This method predates the general-purpose exception chaining facility. 90 * The {@link Throwable#getCause()} method is now the preferred means of 91 * obtaining this information. 92 * 93 * @return the saved throwable object of this 94 * {@code ExceptionInInitializerError}, or {@code null} 95 * if this {@code ExceptionInInitializerError} has no saved 96 * throwable object. 97 */ getException()98 public Throwable getException() { 99 return super.getCause(); 100 } 101 102 /** 103 * Serializable fields for ExceptionInInitializerError. 104 * 105 * @serialField exception Throwable the exception 106 */ 107 @java.io.Serial 108 private static final ObjectStreamField[] serialPersistentFields = { 109 new ObjectStreamField("exception", Throwable.class) 110 }; 111 112 /** 113 * Reconstitutes the ExceptionInInitializerError instance from a stream 114 * and initialize the cause properly when deserializing from an older 115 * version. 116 * 117 * The getException and getCause method returns the private "exception" 118 * field in the older implementation and ExceptionInInitializerError::cause 119 * was set to null. 120 * 121 * @param s the {@code ObjectInputStream} from which data is read 122 * @throws IOException if an I/O error occurs 123 * @throws ClassNotFoundException if a serialized class cannot be loaded 124 */ 125 @java.io.Serial readObject(ObjectInputStream s)126 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { 127 ObjectInputStream.GetField fields = s.readFields(); 128 Throwable exception = (Throwable) fields.get("exception", null); 129 if (exception != null) { 130 setCause(exception); 131 } 132 } 133 134 /** 135 * To maintain compatibility with older implementation, write a serial 136 * "exception" field with the cause as the value. 137 * 138 * @param out the {@code ObjectOutputStream} to which data is written 139 * @throws IOException if an I/O error occurs 140 */ 141 @java.io.Serial writeObject(ObjectOutputStream out)142 private void writeObject(ObjectOutputStream out) throws IOException { 143 ObjectOutputStream.PutField fields = out.putFields(); 144 fields.put("exception", super.getCause()); 145 out.writeFields(); 146 } 147 148 } 149