8155977: ObjectInputStream::resolveClass & resolveProxyClass for platform loader
Reviewed-by: acorn, alanb, chegar, dfuchs
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu May 12 16:33:37 2016 +0100
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Thu May 12 11:16:56 2016 -0700
@@ -262,7 +262,7 @@
Java_jdk_internal_reflect_Reflection_getCallerClass__;
Java_jdk_internal_reflect_Reflection_getCallerClass__I;
Java_jdk_internal_reflect_Reflection_getClassAccessFlags;
- Java_jdk_internal_misc_VM_latestUserDefinedLoader;
+ Java_jdk_internal_misc_VM_latestUserDefinedLoader0;
Java_jdk_internal_misc_VM_getuid;
Java_jdk_internal_misc_VM_geteuid;
Java_jdk_internal_misc_VM_getgid;
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Thu May 12 16:33:37 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Thu May 12 11:16:56 2016 -0700
@@ -603,12 +603,12 @@
* 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 was
- * defined by a user-defined class loader (and was not a generated to
- * implement reflective invocations), then <code>loader</code> is class
- * loader corresponding to the closest such method to the currently
- * executing frame; otherwise, <code>loader</code> is
- * <code>null</code>. If this call results in 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()
+ * 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
@@ -666,12 +666,15 @@
* <pre>
* Class.forName(i, false, loader)
* </pre>
- * where <code>loader</code> is that of the first non-<code>null</code>
- * class loader up the execution stack, or <code>null</code> if no
- * non-<code>null</code> class loaders are on the stack (the same class
- * loader choice used by the <code>resolveClass</code> method). Unless any
- * of the resolved interfaces are non-public, this same value of
- * <code>loader</code> is also the class loader passed to
+ * 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()
+ * 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
@@ -2154,10 +2157,11 @@
int ndoubles);
/**
- * Returns the first non-null class loader (not counting class loaders of
- * generated reflection implementation classes) up the execution stack, or
- * null if only code from the null class loader is on the stack. This
- * method is also called via reflection by the following RMI-IIOP class:
+ * Returns the first non-null and non-platform class loader
+ * (not counting class loaders of generated reflection implementation classes)
+ * up the execution stack, or null if only code from the bootstrap and
+ * platform class loader is on the stack.
+ * This method is also called via reflection by the following RMI-IIOP class:
*
* com.sun.corba.se.internal.util.JDKClassLoader
*
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java Thu May 12 16:33:37 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java Thu May 12 11:16:56 2016 -0700
@@ -390,10 +390,25 @@
private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
/*
- * Returns the first non-null class loader up the execution stack,
- * or null if only code from the null class loader is on the stack.
+ * Returns the first user-defined class loader up the execution stack,
+ * or the platform class loader if only code from the platform or
+ * bootstrap class loader is on the stack.
*/
- public static native ClassLoader latestUserDefinedLoader();
+ public static ClassLoader latestUserDefinedLoader() {
+ ClassLoader loader = latestUserDefinedLoader0();
+ return loader != null ? loader : ClassLoader.getPlatformClassLoader();
+ }
+
+ /*
+ * Returns the first user-defined class loader up the execution stack,
+ * or null if only code from the platform or bootstrap class loader is
+ * on the stack. VM does not keep a reference of platform loader and so
+ * it returns null.
+ *
+ * This method should be replaced with StackWalker::walk and then we can
+ * remove the logic in the VM.
+ */
+ private static native ClassLoader latestUserDefinedLoader0();
/**
* Returns {@code true} if we are in a set UID program.
--- a/jdk/src/java.base/share/native/libjava/VM.c Thu May 12 16:33:37 2016 +0100
+++ b/jdk/src/java.base/share/native/libjava/VM.c Thu May 12 11:16:56 2016 -0700
@@ -36,7 +36,7 @@
};
JNIEXPORT jobject JNICALL
-Java_jdk_internal_misc_VM_latestUserDefinedLoader(JNIEnv *env, jclass cls) {
+Java_jdk_internal_misc_VM_latestUserDefinedLoader0(JNIEnv *env, jclass cls) {
return JVM_LatestUserDefinedLoader(env);
}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java Thu May 12 16:33:37 2016 +0100
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java Thu May 12 11:16:56 2016 -0700
@@ -194,7 +194,7 @@
/*
* Unless we were told to skip this consideration, choose the
* "default loader" to simulate the default ObjectInputStream
- * resolveClass mechanism (that is, choose the first non-null
+ * resolveClass mechanism (that is, choose the first non-platform
* loader on the execution stack) to maximize the likelihood of
* type compatibility with calling code. (This consideration
* is skipped during server parameter unmarshalling using the 1.2
@@ -268,8 +268,9 @@
}
/*
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+ * Returns the first non-platform class loader up the execution stack,
+ * or platform class loader if only code from the platform class loader or null
+ * is on the stack.
*/
private static ClassLoader latestUserDefinedLoader() {
return jdk.internal.misc.VM.latestUserDefinedLoader();