Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8235521: Replacement API for Unsafe::ensureClassInitialized
Reviewed-by: alanb, chegar, psandoz
  • Loading branch information
Mandy Chung committed Jun 8, 2020
1 parent 6fc6476 commit 71d646a16018778fc09f9ec407e35cf12c9e8f1d
Showing with 708 additions and 83 deletions.
  1. +41 −4 src/java.base/share/classes/java/lang/invoke/MethodHandles.java
  2. +28 −23 src/java.base/share/classes/jdk/internal/access/SharedSecrets.java
  3. +36 −35 src/java.desktop/share/classes/sun/awt/AWTAccessor.java
  4. +14 −11 src/java.desktop/share/classes/sun/swing/SwingAccessor.java
  5. +4 −2 src/java.management/share/classes/sun/management/ManagementFactoryHelper.java
  6. +6 −4 src/java.security.jgss/share/classes/sun/security/krb5/KerberosSecrets.java
  7. +8 −1 ...m.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
  8. +5 −3 src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java
  9. +15 −0 src/jdk.unsupported/share/classes/sun/misc/Unsafe.java
  10. +80 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/Main.java
  11. +30 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/java.base/java/lang/DefaultInit.java
  12. +32 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/java.base/java/lang/Helper.java
  13. +30 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/java.base/java/lang/PublicInit.java
  14. +27 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m1/module-info.java
  15. +38 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m1/p1/A.java
  16. +28 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m1/p1/B.java
  17. +152 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m1/p1/Test.java
  18. +27 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m1/p1/internal/C.java
  19. +27 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m1/p1/internal/D.java
  20. +26 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m2/module-info.java
  21. +27 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m2/p2/T.java
  22. +27 −0 test/jdk/java/lang/invoke/MethodHandles/ensureInitialized/m2/p2/internal/X.java
@@ -27,6 +27,7 @@

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 @@ Class<?> defineClass(boolean initialize, Object classData) {
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 @@ private boolean isNestmate() {
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 @@ private ProtectionDomain lookupClassProtectionDomain() {
*/
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 @@ public Class<?> findClass(String targetName) throws ClassNotFoundException, Ille
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 @@

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.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 @@ interface and provides the ability to call package-private methods
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 static JavaUtilJarAccess javaUtilJarAccess() {
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 static void setJavaLangInvokeAccess(JavaLangInvokeAccess jlia) {
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 static void setJavaLangModuleAccess(JavaLangModuleAccess jlrma) {

public static JavaLangModuleAccess getJavaLangModuleAccess() {
if (javaLangModuleAccess == null) {
unsafe.ensureClassInitialized(ModuleDescriptor.class);
ensureClassInitialized(ModuleDescriptor.class);
}
return javaLangModuleAccess;
}
@@ -145,7 +144,7 @@ public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {

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 static void setJavaNetURLAccess(JavaNetURLAccess jnua) {

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 static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {

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 static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {

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 static JavaNioAccess getJavaNioAccess() {
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 static void setJavaIOAccess(JavaIOAccess jia) {

public static JavaIOAccess getJavaIOAccess() {
if (javaIOAccess == null) {
unsafe.ensureClassInitialized(Console.class);
ensureClassInitialized(Console.class);
}
return javaIOAccess;
}
@@ -209,7 +208,7 @@ public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiof

public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
if (javaIOFilePermissionAccess == null)
unsafe.ensureClassInitialized(FilePermission.class);
ensureClassInitialized(FilePermission.class);

return javaIOFilePermissionAccess;
}
@@ -220,7 +219,7 @@ public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiof

public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
if (javaIOFileDescriptorAccess == null)
unsafe.ensureClassInitialized(FileDescriptor.class);
ensureClassInitialized(FileDescriptor.class);

return javaIOFileDescriptorAccess;
}
@@ -231,14 +230,14 @@ public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {

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 static void setJavaBeansAccess(JavaBeansAccess access) {

public static JavaUtilResourceBundleAccess getJavaUtilResourceBundleAccess() {
if (javaUtilResourceBundleAccess == null)
unsafe.ensureClassInitialized(ResourceBundle.class);
ensureClassInitialized(ResourceBundle.class);
return javaUtilResourceBundleAccess;
}

@@ -286,7 +285,7 @@ public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess

public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
if (javaObjectInputStreamReadString == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
ensureClassInitialized(ObjectInputStream.class);
}
return javaObjectInputStreamReadString;
}
@@ -297,7 +296,7 @@ public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadS

public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
if (javaObjectInputStreamAccess == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
ensureClassInitialized(ObjectInputStream.class);
}
return javaObjectInputStreamAccess;
}
@@ -308,7 +307,7 @@ public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess ac

public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() {
if (javaObjectInputFilterAccess == null) {
unsafe.ensureClassInitialized(ObjectInputFilter.Config.class);
ensureClassInitialized(ObjectInputFilter.Config.class);
}
return javaObjectInputFilterAccess;
}
@@ -323,7 +322,7 @@ public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess

public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() {
if (javaIORandomAccessFileAccess == null) {
unsafe.ensureClassInitialized(RandomAccessFile.class);
ensureClassInitialized(RandomAccessFile.class);
}
return javaIORandomAccessFileAccess;
}
@@ -334,7 +333,7 @@ public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess js

public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
if (javaSecuritySignatureAccess == null) {
unsafe.ensureClassInitialized(Signature.class);
ensureClassInitialized(Signature.class);
}
return javaSecuritySignatureAccess;
}
@@ -345,8 +344,14 @@ public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAcces

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) {}
}
}

0 comments on commit 71d646a

Please sign in to comment.