1 /* 2 * Copyright (c) 1995, 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 * Thrown when an application tries to load in a class through its 35 * string name using: 36 * <ul> 37 * <li>The {@code forName} method in class {@code Class}. 38 * <li>The {@code findSystemClass} method in class 39 * {@code ClassLoader} . 40 * <li>The {@code loadClass} method in class {@code ClassLoader}. 41 * </ul> 42 * <p> 43 * but no definition for the class with the specified name could be found. 44 * 45 * @see java.lang.Class#forName(java.lang.String) 46 * @see java.lang.ClassLoader#findSystemClass(java.lang.String) 47 * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) 48 * @since 1.0 49 */ 50 public class ClassNotFoundException extends ReflectiveOperationException { 51 /** 52 * use serialVersionUID from JDK 1.1.X for interoperability 53 */ 54 @java.io.Serial 55 private static final long serialVersionUID = 9176873029745254542L; 56 57 /** 58 * Constructs a {@code ClassNotFoundException} with no detail message. 59 */ ClassNotFoundException()60 public ClassNotFoundException() { 61 super((Throwable)null); // Disallow initCause 62 } 63 64 /** 65 * Constructs a {@code ClassNotFoundException} with the 66 * specified detail message. 67 * 68 * @param s the detail message. 69 */ ClassNotFoundException(String s)70 public ClassNotFoundException(String s) { 71 super(s, null); // Disallow initCause 72 } 73 74 /** 75 * Constructs a {@code ClassNotFoundException} with the 76 * specified detail message and optional exception that was 77 * raised while loading the class. 78 * 79 * @param s the detail message 80 * @param ex the exception that was raised while loading the class 81 * @since 1.2 82 */ ClassNotFoundException(String s, Throwable ex)83 public ClassNotFoundException(String s, Throwable ex) { 84 super(s, ex); // Disallow initCause 85 } 86 87 /** 88 * Returns the exception that was raised if an error occurred while 89 * attempting to load the class. Otherwise, returns {@code null}. 90 * 91 * @apiNote 92 * This method predates the general-purpose exception chaining facility. 93 * The {@link Throwable#getCause()} method is now the preferred means of 94 * obtaining this information. 95 * 96 * @return the {@code Exception} that was raised while loading a class 97 * @since 1.2 98 */ getException()99 public Throwable getException() { 100 return super.getCause(); 101 } 102 103 /** 104 * Serializable fields for ClassNotFoundException. 105 * 106 * @serialField ex Throwable the {@code Throwable} 107 */ 108 @java.io.Serial 109 private static final ObjectStreamField[] serialPersistentFields = { 110 new ObjectStreamField("ex", Throwable.class) 111 }; 112 113 /** 114 * Reconstitutes the ClassNotFoundException instance from a stream 115 * and initialize the cause properly when deserializing from an older 116 * version. 117 * 118 * The getException and getCause method returns the private "ex" field 119 * in the older implementation and ClassNotFoundException::cause 120 * was set to null. 121 * 122 * @param s the {@code ObjectInputStream} from which data is read 123 * @throws IOException if an I/O error occurs 124 * @throws ClassNotFoundException if a serialized class cannot be loaded 125 */ 126 @java.io.Serial readObject(ObjectInputStream s)127 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { 128 ObjectInputStream.GetField fields = s.readFields(); 129 Throwable exception = (Throwable) fields.get("ex", null); 130 if (exception != null) { 131 setCause(exception); 132 } 133 } 134 135 /** 136 * To maintain compatibility with older implementation, write a serial 137 * "ex" field with the cause as the value. 138 * 139 * @param out the {@code ObjectOutputStream} to which data is written 140 * @throws IOException if an I/O error occurs 141 */ 142 @java.io.Serial writeObject(ObjectOutputStream out)143 private void writeObject(ObjectOutputStream out) throws IOException { 144 ObjectOutputStream.PutField fields = out.putFields(); 145 fields.put("ex", super.getCause()); 146 out.writeFields(); 147 } 148 } 149