src/java.base/share/classes/java/io/ObjectInputStream.java

Print this page
rev 16201 : 8169653: Restore ObjectInputStream::resolveClass call stack default search order
Reviewed-by: dfuchs, mchung


 640 
 641     /**
 642      * Load the local class equivalent of the specified stream class
 643      * description.  Subclasses may implement this method to allow classes to
 644      * be fetched from an alternate source.
 645      *
 646      * <p>The corresponding method in <code>ObjectOutputStream</code> is
 647      * <code>annotateClass</code>.  This method will be invoked only once for
 648      * each unique class in the stream.  This method can be implemented by
 649      * subclasses to use an alternate loading mechanism but must return a
 650      * <code>Class</code> object. Once returned, if the class is not an array
 651      * class, its serialVersionUID is compared to the serialVersionUID of the
 652      * serialized class, and if there is a mismatch, the deserialization fails
 653      * and an {@link InvalidClassException} is thrown.
 654      *
 655      * <p>The default implementation of this method in
 656      * <code>ObjectInputStream</code> returns the result of calling
 657      * <pre>
 658      *     Class.forName(desc.getName(), false, loader)
 659      * </pre>
 660      * where <code>loader</code> is determined as follows: if there is a
 661      * method on the current thread's stack whose declaring class is not a
 662      * <a href="../lang/ClassLoader.html#builtinLoaders">
 663      * <em>platform class</em></a>, then <code>loader</code> is
 664      * the class loader of such class; otherwise, <code>loader</code>
 665      * is the {@linkplain ClassLoader#getPlatformClassLoader()
 666      * platform class loader}.  If this call results in a
 667      * <code>ClassNotFoundException</code> and the name of the passed
 668      * <code>ObjectStreamClass</code> instance is the Java language keyword
 669      * for a primitive type or void, then the <code>Class</code> object
 670      * representing that primitive type or void will be returned
 671      * (e.g., an <code>ObjectStreamClass</code> with the name
 672      * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
 673      * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
 674      * the caller of this method.
 675      *
 676      * @param   desc an instance of class <code>ObjectStreamClass</code>
 677      * @return  a <code>Class</code> object corresponding to <code>desc</code>
 678      * @throws  IOException any of the usual Input/Output exceptions.
 679      * @throws  ClassNotFoundException if class of a serialized object cannot
 680      *          be found.
 681      */
 682     protected Class<?> resolveClass(ObjectStreamClass desc)
 683         throws IOException, ClassNotFoundException
 684     {
 685         String name = desc.getName();


 704      *
 705      * <p>This method is called exactly once for each unique proxy class
 706      * descriptor in the stream.
 707      *
 708      * <p>The corresponding method in <code>ObjectOutputStream</code> is
 709      * <code>annotateProxyClass</code>.  For a given subclass of
 710      * <code>ObjectInputStream</code> that overrides this method, the
 711      * <code>annotateProxyClass</code> method in the corresponding subclass of
 712      * <code>ObjectOutputStream</code> must write any data or objects read by
 713      * this method.
 714      *
 715      * <p>The default implementation of this method in
 716      * <code>ObjectInputStream</code> returns the result of calling
 717      * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
 718      * objects for the interfaces that are named in the <code>interfaces</code>
 719      * parameter.  The <code>Class</code> object for each interface name
 720      * <code>i</code> is the value returned by calling
 721      * <pre>
 722      *     Class.forName(i, false, loader)
 723      * </pre>
 724      * where <code>loader</code> is determined as follows: if there is a
 725      * method on the current thread's stack whose declaring class is not a
 726      * <a href="../lang/ClassLoader.html#builtinLoaders">
 727      * <em>platform class</em></a>, then <code>loader</code> is
 728      * the class loader of such class; otherwise, <code>loader</code>
 729      * is the {@linkplain ClassLoader#getPlatformClassLoader()
 730      * platform class loader}.
 731      * Unless any of the resolved interfaces are non-public, this same value
 732      * of <code>loader</code> is also the class loader passed to
 733      * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
 734      * their class loader is passed instead (if more than one non-public
 735      * interface class loader is encountered, an
 736      * <code>IllegalAccessError</code> is thrown).
 737      * If <code>Proxy.getProxyClass</code> throws an
 738      * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
 739      * will throw a <code>ClassNotFoundException</code> containing the
 740      * <code>IllegalArgumentException</code>.
 741      *
 742      * @param interfaces the list of interface names that were
 743      *                deserialized in the proxy class descriptor
 744      * @return  a proxy class for the specified interfaces
 745      * @throws        IOException any exception thrown by the underlying
 746      *                <code>InputStream</code>
 747      * @throws        ClassNotFoundException if the proxy class or any of the
 748      *                named interfaces could not be found
 749      * @see ObjectOutputStream#annotateProxyClass(Class)


2353         clear();
2354     }
2355 
2356     /**
2357      * Converts specified span of bytes into float values.
2358      */
2359     // REMIND: remove once hotspot inlines Float.intBitsToFloat
2360     private static native void bytesToFloats(byte[] src, int srcpos,
2361                                              float[] dst, int dstpos,
2362                                              int nfloats);
2363 
2364     /**
2365      * Converts specified span of bytes into double values.
2366      */
2367     // REMIND: remove once hotspot inlines Double.longBitsToDouble
2368     private static native void bytesToDoubles(byte[] src, int srcpos,
2369                                               double[] dst, int dstpos,
2370                                               int ndoubles);
2371 
2372     /**
2373      * Returns the first non-null and non-platform class loader
2374      * (not counting class loaders of generated reflection implementation classes)
2375      * up the execution stack, or null if only code from the bootstrap and
2376      * platform class loader is on the stack.
2377      * This method is also called via reflection by the following RMI-IIOP class:
2378      *
2379      *     com.sun.corba.se.internal.util.JDKClassLoader
2380      *
2381      * This method should not be removed or its signature changed without
2382      * corresponding modifications to the above class.
2383      */
2384     private static ClassLoader latestUserDefinedLoader() {
2385         return jdk.internal.misc.VM.latestUserDefinedLoader();
2386     }
2387 
2388     /**
2389      * Default GetField implementation.
2390      */
2391     private class GetFieldImpl extends GetField {
2392 
2393         /** class descriptor describing serializable fields */
2394         private final ObjectStreamClass desc;
2395         /** primitive field values */
2396         private final byte[] primVals;
2397         /** object field values */
2398         private final Object[] objVals;
2399         /** object field value handles */
2400         private final int[] objHandles;
2401 
2402         /**




 640 
 641     /**
 642      * Load the local class equivalent of the specified stream class
 643      * description.  Subclasses may implement this method to allow classes to
 644      * be fetched from an alternate source.
 645      *
 646      * <p>The corresponding method in <code>ObjectOutputStream</code> is
 647      * <code>annotateClass</code>.  This method will be invoked only once for
 648      * each unique class in the stream.  This method can be implemented by
 649      * subclasses to use an alternate loading mechanism but must return a
 650      * <code>Class</code> object. Once returned, if the class is not an array
 651      * class, its serialVersionUID is compared to the serialVersionUID of the
 652      * serialized class, and if there is a mismatch, the deserialization fails
 653      * and an {@link InvalidClassException} is thrown.
 654      *
 655      * <p>The default implementation of this method in
 656      * <code>ObjectInputStream</code> returns the result of calling
 657      * <pre>
 658      *     Class.forName(desc.getName(), false, loader)
 659      * </pre>
 660      * where <code>loader</code> is the first class loader on the current
 661      * thread's stack (starting from the currently executing method) that is
 662      * neither the <a href="../lang/ClassLoader.html#builtinLoaders"><em>
 663      * platform class loader</em></a> nor its ancestor; otherwise, <code>
 664      * loader</code> is the {@linkplain ClassLoader#getPlatformClassLoader()

 665      * platform class loader}.  If this call results in a
 666      * <code>ClassNotFoundException</code> and the name of the passed
 667      * <code>ObjectStreamClass</code> instance is the Java language keyword
 668      * for a primitive type or void, then the <code>Class</code> object
 669      * representing that primitive type or void will be returned
 670      * (e.g., an <code>ObjectStreamClass</code> with the name
 671      * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
 672      * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
 673      * the caller of this method.
 674      *
 675      * @param   desc an instance of class <code>ObjectStreamClass</code>
 676      * @return  a <code>Class</code> object corresponding to <code>desc</code>
 677      * @throws  IOException any of the usual Input/Output exceptions.
 678      * @throws  ClassNotFoundException if class of a serialized object cannot
 679      *          be found.
 680      */
 681     protected Class<?> resolveClass(ObjectStreamClass desc)
 682         throws IOException, ClassNotFoundException
 683     {
 684         String name = desc.getName();


 703      *
 704      * <p>This method is called exactly once for each unique proxy class
 705      * descriptor in the stream.
 706      *
 707      * <p>The corresponding method in <code>ObjectOutputStream</code> is
 708      * <code>annotateProxyClass</code>.  For a given subclass of
 709      * <code>ObjectInputStream</code> that overrides this method, the
 710      * <code>annotateProxyClass</code> method in the corresponding subclass of
 711      * <code>ObjectOutputStream</code> must write any data or objects read by
 712      * this method.
 713      *
 714      * <p>The default implementation of this method in
 715      * <code>ObjectInputStream</code> returns the result of calling
 716      * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
 717      * objects for the interfaces that are named in the <code>interfaces</code>
 718      * parameter.  The <code>Class</code> object for each interface name
 719      * <code>i</code> is the value returned by calling
 720      * <pre>
 721      *     Class.forName(i, false, loader)
 722      * </pre>
 723      * where <code>loader</code> is the first class loader on the current
 724      * thread's stack (starting from the currently executing method) that is
 725      * neither the <a href="../lang/ClassLoader.html#builtinLoaders"><em>
 726      * platform class loader</em></a> nor its ancestor; otherwise, <code>
 727      * loader</code> is the {@linkplain ClassLoader#getPlatformClassLoader()

 728      * platform class loader}.
 729      * Unless any of the resolved interfaces are non-public, this same value
 730      * of <code>loader</code> is also the class loader passed to
 731      * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
 732      * their class loader is passed instead (if more than one non-public
 733      * interface class loader is encountered, an
 734      * <code>IllegalAccessError</code> is thrown).
 735      * If <code>Proxy.getProxyClass</code> throws an
 736      * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
 737      * will throw a <code>ClassNotFoundException</code> containing the
 738      * <code>IllegalArgumentException</code>.
 739      *
 740      * @param interfaces the list of interface names that were
 741      *                deserialized in the proxy class descriptor
 742      * @return  a proxy class for the specified interfaces
 743      * @throws        IOException any exception thrown by the underlying
 744      *                <code>InputStream</code>
 745      * @throws        ClassNotFoundException if the proxy class or any of the
 746      *                named interfaces could not be found
 747      * @see ObjectOutputStream#annotateProxyClass(Class)


2351         clear();
2352     }
2353 
2354     /**
2355      * Converts specified span of bytes into float values.
2356      */
2357     // REMIND: remove once hotspot inlines Float.intBitsToFloat
2358     private static native void bytesToFloats(byte[] src, int srcpos,
2359                                              float[] dst, int dstpos,
2360                                              int nfloats);
2361 
2362     /**
2363      * Converts specified span of bytes into double values.
2364      */
2365     // REMIND: remove once hotspot inlines Double.longBitsToDouble
2366     private static native void bytesToDoubles(byte[] src, int srcpos,
2367                                               double[] dst, int dstpos,
2368                                               int ndoubles);
2369 
2370     /**
2371      * Returns the first non-null and non-platform class loader (not counting
2372      * class loaders of generated reflection implementation classes) up the
2373      * execution stack, or the platform class loader if only code from the
2374      * bootstrap and platform class loader is on the stack.






2375      */
2376     private static ClassLoader latestUserDefinedLoader() {
2377         return jdk.internal.misc.VM.latestUserDefinedLoader();
2378     }
2379 
2380     /**
2381      * Default GetField implementation.
2382      */
2383     private class GetFieldImpl extends GetField {
2384 
2385         /** class descriptor describing serializable fields */
2386         private final ObjectStreamClass desc;
2387         /** primitive field values */
2388         private final byte[] primVals;
2389         /** object field values */
2390         private final Object[] objVals;
2391         /** object field value handles */
2392         private final int[] objHandles;
2393 
2394         /**