8212117: Class.forName may return a reference to a loaded but not linked Class

Reviewed-by: dholmes, mchung
This commit is contained in:
Brent Christian 2019-09-09 11:04:04 -07:00
parent 10e4fd4b95
commit a4613d4a8f
13 changed files with 342 additions and 16 deletions

View file

@ -392,6 +392,10 @@ public final class Class<T> implements java.io.Serializable,
*
* @see java.lang.Class#forName(String)
* @see java.lang.ClassLoader
*
* @jls 12.2 Loading of Classes and Interfaces
* @jls 12.3 Linking of Classes and Interfaces
* @jls 12.4 Initialization of Classes and Interfaces
* @since 1.2
*/
@CallerSensitive
@ -438,6 +442,10 @@ public final class Class<T> implements java.io.Serializable,
* <p> This method does not check whether the requested class is
* accessible to its caller. </p>
*
* <p> Note that this method throws errors related to loading and linking as
* specified in Sections 12.2 and 12.3 of <em>The Java Language
* Specification</em>.
*
* @apiNote
* This method returns {@code null} on failure rather than
* throwing a {@link ClassNotFoundException}, as is done by
@ -465,6 +473,8 @@ public final class Class<T> implements java.io.Serializable,
* in a module.</li>
* </ul>
*
* @jls 12.2 Loading of Classes and Interfaces
* @jls 12.3 Linking of Classes and Interfaces
* @since 9
* @spec JPMS
*/
@ -488,13 +498,21 @@ public final class Class<T> implements java.io.Serializable,
cl = module.getClassLoader();
}
Class<?> ret;
if (cl != null) {
return cl.loadClass(module, name);
ret = cl.loadClass(module, name);
} else {
return BootLoader.loadClass(module, name);
ret = BootLoader.loadClass(module, name);
}
if (ret != null) {
// The loaded class should also be linked
linkClass(ret);
}
return ret;
}
private static native void linkClass(Class<?> c);
/**
* Creates a new instance of the class represented by this {@code Class}
* object. The class is instantiated as if by a {@code new}

View file

@ -1927,12 +1927,17 @@ assertEquals("[x, y, z]", pb.command().toString());
}
/**
* Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
* Looks up a class by name from the lookup context defined by this {@code Lookup} object.
* This method attempts to locate, load, and link the class, and then determines whether
* the class is accessible to this {@code Lookup} object. The static
* initializer of the class is not run.
* <p>
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
* loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
* load the requested class, and then determines whether the class is accessible to this lookup object.
* loader, and the {@linkplain #lookupModes() lookup modes}.
* <p>
* Note that this method throws errors related to loading and linking as
* specified in Sections 12.2 and 12.3 of <em>The Java Language
* Specification</em>.
*
* @param targetName the fully qualified name of the class to be looked up.
* @return the requested class.
@ -1944,6 +1949,9 @@ assertEquals("[x, y, z]", pb.command().toString());
* modes.
* @exception SecurityException if a security manager is present and it
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
*
* @jls 12.2 Loading of Classes and Interfaces
* @jls 12.3 Linking of Classes and Interfaces
* @since 9
*/
public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {