mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8235521: Replacement API for Unsafe::ensureClassInitialized
Reviewed-by: alanb, chegar, psandoz
This commit is contained in:
parent
6fc6476da8
commit
71d646a160
22 changed files with 708 additions and 83 deletions
|
@ -27,6 +27,7 @@ package java.lang.invoke;
|
|||
|
||||
import jdk.internal.access.JavaLangAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.module.IllegalAccessLogger;
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
|
@ -2243,7 +2244,8 @@ public class MethodHandles {
|
|||
Class<?> lookupClass = lookup.lookupClass();
|
||||
ClassLoader loader = lookupClass.getClassLoader();
|
||||
ProtectionDomain pd = (loader != null) ? lookup.lookupClassProtectionDomain() : null;
|
||||
Class<?> c = JLA.defineClass(loader, lookupClass, name, bytes, pd, initialize, classFlags, classData);
|
||||
Class<?> c = SharedSecrets.getJavaLangAccess()
|
||||
.defineClass(loader, lookupClass, name, bytes, pd, initialize, classFlags, classData);
|
||||
assert !isNestmate() || c.getNestHost() == lookupClass.getNestHost();
|
||||
return c;
|
||||
}
|
||||
|
@ -2263,7 +2265,7 @@ public class MethodHandles {
|
|||
private ProtectionDomain lookupClassProtectionDomain() {
|
||||
ProtectionDomain pd = cachedProtectionDomain;
|
||||
if (pd == null) {
|
||||
cachedProtectionDomain = pd = JLA.protectionDomain(lookupClass);
|
||||
cachedProtectionDomain = pd = SharedSecrets.getJavaLangAccess().protectionDomain(lookupClass);
|
||||
}
|
||||
return pd;
|
||||
}
|
||||
|
@ -2283,8 +2285,6 @@ public class MethodHandles {
|
|||
*/
|
||||
static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, null, UNCONDITIONAL);
|
||||
|
||||
static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
|
||||
String name = lookupClass.getName();
|
||||
if (name.startsWith("java.lang.invoke."))
|
||||
|
@ -2586,6 +2586,43 @@ assertEquals("[x, y, z]", pb.command().toString());
|
|||
return accessClass(targetClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that {@code targetClass} has been initialized. The class
|
||||
* to be initialized must be {@linkplain #accessClass accessible}
|
||||
* to this {@code Lookup} object. This method causes {@code targetClass}
|
||||
* to be initialized if it has not been already initialized,
|
||||
* as specified in JVMS {@jvms 5.5}.
|
||||
*
|
||||
* @param targetClass the class to be initialized
|
||||
* @return {@code targetClass} that has been initialized
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code targetClass} is a primitive type or {@code void}
|
||||
* or array class
|
||||
* @throws IllegalAccessException if {@code targetClass} is not
|
||||
* {@linkplain #accessClass accessible} to this lookup
|
||||
* @throws ExceptionInInitializerError if the class initialization provoked
|
||||
* by this method fails
|
||||
* @throws SecurityException if a security manager is present and it
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @since 15
|
||||
* @jvms 5.5 Initialization
|
||||
*/
|
||||
public Class<?> ensureInitialized(Class<?> targetClass) throws IllegalAccessException {
|
||||
if (targetClass.isPrimitive())
|
||||
throw new IllegalArgumentException(targetClass + " is a primitive class");
|
||||
if (targetClass.isArray())
|
||||
throw new IllegalArgumentException(targetClass + " is an array class");
|
||||
|
||||
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
|
||||
throw new MemberName(targetClass).makeAccessException("access violation", this);
|
||||
}
|
||||
checkSecurityManager(targetClass, null);
|
||||
|
||||
// ensure class initialization
|
||||
Unsafe.getUnsafe().ensureClassInitialized(targetClass);
|
||||
return targetClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a class can be accessed from the lookup context defined by
|
||||
* this {@code Lookup} object. The static initializer of the class is not run.
|
||||
|
|
|
@ -27,6 +27,7 @@ package jdk.internal.access;
|
|||
|
||||
import javax.crypto.SealedObject;
|
||||
import java.io.ObjectInputFilter;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.jar.JarFile;
|
||||
|
@ -37,7 +38,6 @@ import java.io.ObjectInputStream;
|
|||
import java.io.RandomAccessFile;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.Signature;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/** A repository of "shared secrets", which are a mechanism for
|
||||
calling implementation-private methods in another package without
|
||||
|
@ -49,7 +49,7 @@ import jdk.internal.misc.Unsafe;
|
|||
for this purpose, namely the loss of compile-time checking. */
|
||||
|
||||
public class SharedSecrets {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
private static JavaAWTAccess javaAWTAccess;
|
||||
private static JavaAWTFontAccess javaAWTFontAccess;
|
||||
private static JavaBeansAccess javaBeansAccess;
|
||||
|
@ -81,7 +81,7 @@ public class SharedSecrets {
|
|||
if (javaUtilJarAccess == null) {
|
||||
// Ensure JarFile is initialized; we know that this class
|
||||
// provides the shared secret
|
||||
unsafe.ensureClassInitialized(JarFile.class);
|
||||
ensureClassInitialized(JarFile.class);
|
||||
}
|
||||
return javaUtilJarAccess;
|
||||
}
|
||||
|
@ -105,8 +105,7 @@ public class SharedSecrets {
|
|||
public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
|
||||
if (javaLangInvokeAccess == null) {
|
||||
try {
|
||||
Class<?> c = Class.forName("java.lang.invoke.MethodHandleImpl");
|
||||
unsafe.ensureClassInitialized(c);
|
||||
Class.forName("java.lang.invoke.MethodHandleImpl", true, null);
|
||||
} catch (ClassNotFoundException e) {};
|
||||
}
|
||||
return javaLangInvokeAccess;
|
||||
|
@ -118,7 +117,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaLangModuleAccess getJavaLangModuleAccess() {
|
||||
if (javaLangModuleAccess == null) {
|
||||
unsafe.ensureClassInitialized(ModuleDescriptor.class);
|
||||
ensureClassInitialized(ModuleDescriptor.class);
|
||||
}
|
||||
return javaLangModuleAccess;
|
||||
}
|
||||
|
@ -145,7 +144,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaNetUriAccess getJavaNetUriAccess() {
|
||||
if (javaNetUriAccess == null)
|
||||
unsafe.ensureClassInitialized(java.net.URI.class);
|
||||
ensureClassInitialized(java.net.URI.class);
|
||||
return javaNetUriAccess;
|
||||
}
|
||||
|
||||
|
@ -155,7 +154,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaNetURLAccess getJavaNetURLAccess() {
|
||||
if (javaNetURLAccess == null)
|
||||
unsafe.ensureClassInitialized(java.net.URL.class);
|
||||
ensureClassInitialized(java.net.URL.class);
|
||||
return javaNetURLAccess;
|
||||
}
|
||||
|
||||
|
@ -165,7 +164,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaNetInetAddressAccess getJavaNetInetAddressAccess() {
|
||||
if (javaNetInetAddressAccess == null)
|
||||
unsafe.ensureClassInitialized(java.net.InetAddress.class);
|
||||
ensureClassInitialized(java.net.InetAddress.class);
|
||||
return javaNetInetAddressAccess;
|
||||
}
|
||||
|
||||
|
@ -175,7 +174,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
|
||||
if (javaNetHttpCookieAccess == null)
|
||||
unsafe.ensureClassInitialized(java.net.HttpCookie.class);
|
||||
ensureClassInitialized(java.net.HttpCookie.class);
|
||||
return javaNetHttpCookieAccess;
|
||||
}
|
||||
|
||||
|
@ -187,7 +186,7 @@ public class SharedSecrets {
|
|||
if (javaNioAccess == null) {
|
||||
// Ensure java.nio.Buffer is initialized, which provides the
|
||||
// shared secret.
|
||||
unsafe.ensureClassInitialized(java.nio.Buffer.class);
|
||||
ensureClassInitialized(java.nio.Buffer.class);
|
||||
}
|
||||
return javaNioAccess;
|
||||
}
|
||||
|
@ -198,7 +197,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaIOAccess getJavaIOAccess() {
|
||||
if (javaIOAccess == null) {
|
||||
unsafe.ensureClassInitialized(Console.class);
|
||||
ensureClassInitialized(Console.class);
|
||||
}
|
||||
return javaIOAccess;
|
||||
}
|
||||
|
@ -209,7 +208,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
|
||||
if (javaIOFilePermissionAccess == null)
|
||||
unsafe.ensureClassInitialized(FilePermission.class);
|
||||
ensureClassInitialized(FilePermission.class);
|
||||
|
||||
return javaIOFilePermissionAccess;
|
||||
}
|
||||
|
@ -220,7 +219,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
|
||||
if (javaIOFileDescriptorAccess == null)
|
||||
unsafe.ensureClassInitialized(FileDescriptor.class);
|
||||
ensureClassInitialized(FileDescriptor.class);
|
||||
|
||||
return javaIOFileDescriptorAccess;
|
||||
}
|
||||
|
@ -231,14 +230,14 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaSecurityAccess getJavaSecurityAccess() {
|
||||
if (javaSecurityAccess == null) {
|
||||
unsafe.ensureClassInitialized(ProtectionDomain.class);
|
||||
ensureClassInitialized(ProtectionDomain.class);
|
||||
}
|
||||
return javaSecurityAccess;
|
||||
}
|
||||
|
||||
public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
|
||||
if (javaUtilZipFileAccess == null)
|
||||
unsafe.ensureClassInitialized(java.util.zip.ZipFile.class);
|
||||
ensureClassInitialized(java.util.zip.ZipFile.class);
|
||||
return javaUtilZipFileAccess;
|
||||
}
|
||||
|
||||
|
@ -276,7 +275,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaUtilResourceBundleAccess getJavaUtilResourceBundleAccess() {
|
||||
if (javaUtilResourceBundleAccess == null)
|
||||
unsafe.ensureClassInitialized(ResourceBundle.class);
|
||||
ensureClassInitialized(ResourceBundle.class);
|
||||
return javaUtilResourceBundleAccess;
|
||||
}
|
||||
|
||||
|
@ -286,7 +285,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
|
||||
if (javaObjectInputStreamReadString == null) {
|
||||
unsafe.ensureClassInitialized(ObjectInputStream.class);
|
||||
ensureClassInitialized(ObjectInputStream.class);
|
||||
}
|
||||
return javaObjectInputStreamReadString;
|
||||
}
|
||||
|
@ -297,7 +296,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
|
||||
if (javaObjectInputStreamAccess == null) {
|
||||
unsafe.ensureClassInitialized(ObjectInputStream.class);
|
||||
ensureClassInitialized(ObjectInputStream.class);
|
||||
}
|
||||
return javaObjectInputStreamAccess;
|
||||
}
|
||||
|
@ -308,7 +307,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() {
|
||||
if (javaObjectInputFilterAccess == null) {
|
||||
unsafe.ensureClassInitialized(ObjectInputFilter.Config.class);
|
||||
ensureClassInitialized(ObjectInputFilter.Config.class);
|
||||
}
|
||||
return javaObjectInputFilterAccess;
|
||||
}
|
||||
|
@ -323,7 +322,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() {
|
||||
if (javaIORandomAccessFileAccess == null) {
|
||||
unsafe.ensureClassInitialized(RandomAccessFile.class);
|
||||
ensureClassInitialized(RandomAccessFile.class);
|
||||
}
|
||||
return javaIORandomAccessFileAccess;
|
||||
}
|
||||
|
@ -334,7 +333,7 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
|
||||
if (javaSecuritySignatureAccess == null) {
|
||||
unsafe.ensureClassInitialized(Signature.class);
|
||||
ensureClassInitialized(Signature.class);
|
||||
}
|
||||
return javaSecuritySignatureAccess;
|
||||
}
|
||||
|
@ -345,8 +344,14 @@ public class SharedSecrets {
|
|||
|
||||
public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() {
|
||||
if (javaxCryptoSealedObjectAccess == null) {
|
||||
unsafe.ensureClassInitialized(SealedObject.class);
|
||||
ensureClassInitialized(SealedObject.class);
|
||||
}
|
||||
return javaxCryptoSealedObjectAccess;
|
||||
}
|
||||
|
||||
private static void ensureClassInitialized(Class<?> c) {
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(c);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue