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