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