RFR 8169653: Restore ObjectInputStream::resolveClass call stack default search order
Daniel Fuchs
daniel.fuchs at oracle.com
Tue Dec 6 11:53:51 UTC 2016
Hi Chris,
I have an additional suggestion: could you update the
comment of the private ObjectInputStream::latestUserDefinedLoader()
in the same file to align with what the method is actually
doing?
I looked at what jdk.internal.misc.VM.latestUserDefinedLoader()
does, and the comment in ObjectInputStream::latestUserDefinedLoader()
doesn't seem to match the implementation.
best regards,
-- daniel
On 06/12/16 11:38, Chris Hegarty wrote:
>
>> On 6 Dec 2016, at 11:35, Daniel Fuchs <daniel.fuchs at oracle.com> wrote:
>>
>> Hi Chris,
>>
>> Is that a typo? I see it at two places:
>>
>> otherwise, <code>
>> + * loaded</code> is the {@linkplain ClassLoader#getPlatformClassLoader()
>> * platform class loader}.
>>
>> ("loaded" vs "loader")
>
> It is a typo, thanks. For completeness, here is the updated version:
>
> diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java
> --- a/src/java.base/share/classes/java/io/ObjectInputStream.java
> +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
> @@ -640,46 +640,45 @@
>
> /**
> * Load the local class equivalent of the specified stream class
> * description. Subclasses may implement this method to allow classes to
> * be fetched from an alternate source.
> *
> * <p>The corresponding method in <code>ObjectOutputStream</code> is
> * <code>annotateClass</code>. This method will be invoked only once for
> * each unique class in the stream. This method can be implemented by
> * subclasses to use an alternate loading mechanism but must return a
> * <code>Class</code> object. Once returned, if the class is not an array
> * class, its serialVersionUID is compared to the serialVersionUID of the
> * serialized class, and if there is a mismatch, the deserialization fails
> * and an {@link InvalidClassException} is thrown.
> *
> * <p>The default implementation of this method in
> * <code>ObjectInputStream</code> returns the result of calling
> * <pre>
> * Class.forName(desc.getName(), false, loader)
> * </pre>
> - * where <code>loader</code> is determined as follows: if there is a
> - * method on the current thread's stack whose declaring class is not a
> - * <a href="../lang/ClassLoader.html#builtinLoaders">
> - * <em>platform class</em></a>, then <code>loader</code> is
> - * the class loader of such class; otherwise, <code>loader</code>
> - * is the {@linkplain ClassLoader#getPlatformClassLoader()
> + * where <code>loader</code> is the first class loader on the current
> + * thread's stack (starting from the currently executing method) that is
> + * neither the <a href="../lang/ClassLoader.html#builtinLoaders"><em>
> + * platform class loader</em></a> nor its ancestor; otherwise, <code>
> + * loader</code> is the {@linkplain ClassLoader#getPlatformClassLoader()
> * platform class loader}. If this call results in a
> * <code>ClassNotFoundException</code> and the name of the passed
> * <code>ObjectStreamClass</code> instance is the Java language keyword
> * for a primitive type or void, then the <code>Class</code> object
> * representing that primitive type or void will be returned
> * (e.g., an <code>ObjectStreamClass</code> with the name
> * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
> * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
> * the caller of this method.
> *
> * @param desc an instance of class <code>ObjectStreamClass</code>
> * @return a <code>Class</code> object corresponding to <code>desc</code>
> * @throws IOException any of the usual Input/Output exceptions.
> * @throws ClassNotFoundException if class of a serialized object cannot
> * be found.
> */
> protected Class<?> resolveClass(ObjectStreamClass desc)
> throws IOException, ClassNotFoundException
> {
> String name = desc.getName();
> @@ -704,46 +703,45 @@
> *
> * <p>This method is called exactly once for each unique proxy class
> * descriptor in the stream.
> *
> * <p>The corresponding method in <code>ObjectOutputStream</code> is
> * <code>annotateProxyClass</code>. For a given subclass of
> * <code>ObjectInputStream</code> that overrides this method, the
> * <code>annotateProxyClass</code> method in the corresponding subclass of
> * <code>ObjectOutputStream</code> must write any data or objects read by
> * this method.
> *
> * <p>The default implementation of this method in
> * <code>ObjectInputStream</code> returns the result of calling
> * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
> * objects for the interfaces that are named in the <code>interfaces</code>
> * parameter. The <code>Class</code> object for each interface name
> * <code>i</code> is the value returned by calling
> * <pre>
> * Class.forName(i, false, loader)
> * </pre>
> - * where <code>loader</code> is determined as follows: if there is a
> - * method on the current thread's stack whose declaring class is not a
> - * <a href="../lang/ClassLoader.html#builtinLoaders">
> - * <em>platform class</em></a>, then <code>loader</code> is
> - * the class loader of such class; otherwise, <code>loader</code>
> - * is the {@linkplain ClassLoader#getPlatformClassLoader()
> + * where <code>loader</code> is the first class loader on the current
> + * thread's stack (starting from the currently executing method) that is
> + * neither the <a href="../lang/ClassLoader.html#builtinLoaders"><em>
> + * platform class loader</em></a> nor its ancestor; otherwise, <code>
> + * loader</code> is the {@linkplain ClassLoader#getPlatformClassLoader()
> * platform class loader}.
> * Unless any of the resolved interfaces are non-public, this same value
> * of <code>loader</code> is also the class loader passed to
> * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
> * their class loader is passed instead (if more than one non-public
> * interface class loader is encountered, an
> * <code>IllegalAccessError</code> is thrown).
> * If <code>Proxy.getProxyClass</code> throws an
> * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
> * will throw a <code>ClassNotFoundException</code> containing the
> * <code>IllegalArgumentException</code>.
> *
> * @param interfaces the list of interface names that were
> * deserialized in the proxy class descriptor
> * @return a proxy class for the specified interfaces
> * @throws IOException any exception thrown by the underlying
> * <code>InputStream</code>
> * @throws ClassNotFoundException if the proxy class or any of the
> * named interfaces could not be found
> * @see ObjectOutputStream#annotateProxyClass(Class)
>
>
> -Chris.
>
More information about the core-libs-dev
mailing list