8235521: Replacement API for Unsafe::ensureClassInitialized
Reviewed-by: alanb, chegar, psandoz
This commit is contained in:
parent
6fc6476da8
commit
71d646a160
@ -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) {}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package sun.awt;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import javax.accessibility.AccessibleContext;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent.Cause;
|
||||
@ -34,7 +32,6 @@ import java.awt.dnd.DragSourceContext;
|
||||
import java.awt.dnd.DropTargetContext;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.dnd.peer.DropTargetContextPeer;
|
||||
import java.awt.event.AWTEventListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.InvocationEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
@ -44,6 +41,7 @@ import java.awt.image.BufferStrategy;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
|
||||
import java.awt.peer.MenuComponentPeer;
|
||||
import java.lang.invoke.MethodHandles;;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
@ -61,8 +59,6 @@ import javax.accessibility.AccessibleBundle;
|
||||
*/
|
||||
public final class AWTAccessor {
|
||||
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
/*
|
||||
* We don't need any objects of this class.
|
||||
* It's rather a collection of static methods
|
||||
@ -877,7 +873,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static ComponentAccessor getComponentAccessor() {
|
||||
if (componentAccessor == null) {
|
||||
unsafe.ensureClassInitialized(Component.class);
|
||||
ensureClassInitialized(Component.class);
|
||||
}
|
||||
|
||||
return componentAccessor;
|
||||
@ -895,7 +891,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static ContainerAccessor getContainerAccessor() {
|
||||
if (containerAccessor == null) {
|
||||
unsafe.ensureClassInitialized(Container.class);
|
||||
ensureClassInitialized(Container.class);
|
||||
}
|
||||
|
||||
return containerAccessor;
|
||||
@ -913,7 +909,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static WindowAccessor getWindowAccessor() {
|
||||
if (windowAccessor == null) {
|
||||
unsafe.ensureClassInitialized(Window.class);
|
||||
ensureClassInitialized(Window.class);
|
||||
}
|
||||
return windowAccessor;
|
||||
}
|
||||
@ -930,7 +926,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static AWTEventAccessor getAWTEventAccessor() {
|
||||
if (awtEventAccessor == null) {
|
||||
unsafe.ensureClassInitialized(AWTEvent.class);
|
||||
ensureClassInitialized(AWTEvent.class);
|
||||
}
|
||||
return awtEventAccessor;
|
||||
}
|
||||
@ -947,7 +943,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static InputEventAccessor getInputEventAccessor() {
|
||||
if (inputEventAccessor == null) {
|
||||
unsafe.ensureClassInitialized(InputEvent.class);
|
||||
ensureClassInitialized(InputEvent.class);
|
||||
}
|
||||
return inputEventAccessor;
|
||||
}
|
||||
@ -964,7 +960,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static MouseEventAccessor getMouseEventAccessor() {
|
||||
if (mouseEventAccessor == null) {
|
||||
unsafe.ensureClassInitialized(MouseEvent.class);
|
||||
ensureClassInitialized(MouseEvent.class);
|
||||
}
|
||||
return mouseEventAccessor;
|
||||
}
|
||||
@ -981,7 +977,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static FrameAccessor getFrameAccessor() {
|
||||
if (frameAccessor == null) {
|
||||
unsafe.ensureClassInitialized(Frame.class);
|
||||
ensureClassInitialized(Frame.class);
|
||||
}
|
||||
return frameAccessor;
|
||||
}
|
||||
@ -998,7 +994,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static KeyboardFocusManagerAccessor getKeyboardFocusManagerAccessor() {
|
||||
if (kfmAccessor == null) {
|
||||
unsafe.ensureClassInitialized(KeyboardFocusManager.class);
|
||||
ensureClassInitialized(KeyboardFocusManager.class);
|
||||
}
|
||||
return kfmAccessor;
|
||||
}
|
||||
@ -1015,7 +1011,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static MenuComponentAccessor getMenuComponentAccessor() {
|
||||
if (menuComponentAccessor == null) {
|
||||
unsafe.ensureClassInitialized(MenuComponent.class);
|
||||
ensureClassInitialized(MenuComponent.class);
|
||||
}
|
||||
return menuComponentAccessor;
|
||||
}
|
||||
@ -1032,7 +1028,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static EventQueueAccessor getEventQueueAccessor() {
|
||||
if (eventQueueAccessor == null) {
|
||||
unsafe.ensureClassInitialized(EventQueue.class);
|
||||
ensureClassInitialized(EventQueue.class);
|
||||
}
|
||||
return eventQueueAccessor;
|
||||
}
|
||||
@ -1049,7 +1045,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static PopupMenuAccessor getPopupMenuAccessor() {
|
||||
if (popupMenuAccessor == null) {
|
||||
unsafe.ensureClassInitialized(PopupMenu.class);
|
||||
ensureClassInitialized(PopupMenu.class);
|
||||
}
|
||||
return popupMenuAccessor;
|
||||
}
|
||||
@ -1066,7 +1062,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static FileDialogAccessor getFileDialogAccessor() {
|
||||
if (fileDialogAccessor == null) {
|
||||
unsafe.ensureClassInitialized(FileDialog.class);
|
||||
ensureClassInitialized(FileDialog.class);
|
||||
}
|
||||
return fileDialogAccessor;
|
||||
}
|
||||
@ -1084,7 +1080,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static ScrollPaneAdjustableAccessor getScrollPaneAdjustableAccessor() {
|
||||
if (scrollPaneAdjustableAccessor == null) {
|
||||
unsafe.ensureClassInitialized(ScrollPaneAdjustable.class);
|
||||
ensureClassInitialized(ScrollPaneAdjustable.class);
|
||||
}
|
||||
return scrollPaneAdjustableAccessor;
|
||||
}
|
||||
@ -1101,7 +1097,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static CheckboxMenuItemAccessor getCheckboxMenuItemAccessor() {
|
||||
if (checkboxMenuItemAccessor == null) {
|
||||
unsafe.ensureClassInitialized(CheckboxMenuItemAccessor.class);
|
||||
ensureClassInitialized(CheckboxMenuItemAccessor.class);
|
||||
}
|
||||
return checkboxMenuItemAccessor;
|
||||
}
|
||||
@ -1118,7 +1114,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static CursorAccessor getCursorAccessor() {
|
||||
if (cursorAccessor == null) {
|
||||
unsafe.ensureClassInitialized(CursorAccessor.class);
|
||||
ensureClassInitialized(CursorAccessor.class);
|
||||
}
|
||||
return cursorAccessor;
|
||||
}
|
||||
@ -1135,7 +1131,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static MenuBarAccessor getMenuBarAccessor() {
|
||||
if (menuBarAccessor == null) {
|
||||
unsafe.ensureClassInitialized(MenuBarAccessor.class);
|
||||
ensureClassInitialized(MenuBarAccessor.class);
|
||||
}
|
||||
return menuBarAccessor;
|
||||
}
|
||||
@ -1152,7 +1148,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static MenuItemAccessor getMenuItemAccessor() {
|
||||
if (menuItemAccessor == null) {
|
||||
unsafe.ensureClassInitialized(MenuItemAccessor.class);
|
||||
ensureClassInitialized(MenuItemAccessor.class);
|
||||
}
|
||||
return menuItemAccessor;
|
||||
}
|
||||
@ -1169,7 +1165,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static MenuAccessor getMenuAccessor() {
|
||||
if (menuAccessor == null) {
|
||||
unsafe.ensureClassInitialized(MenuAccessor.class);
|
||||
ensureClassInitialized(MenuAccessor.class);
|
||||
}
|
||||
return menuAccessor;
|
||||
}
|
||||
@ -1186,7 +1182,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static KeyEventAccessor getKeyEventAccessor() {
|
||||
if (keyEventAccessor == null) {
|
||||
unsafe.ensureClassInitialized(KeyEventAccessor.class);
|
||||
ensureClassInitialized(KeyEventAccessor.class);
|
||||
}
|
||||
return keyEventAccessor;
|
||||
}
|
||||
@ -1203,7 +1199,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static ClientPropertyKeyAccessor getClientPropertyKeyAccessor() {
|
||||
if (clientPropertyKeyAccessor == null) {
|
||||
unsafe.ensureClassInitialized(ClientPropertyKeyAccessor.class);
|
||||
ensureClassInitialized(ClientPropertyKeyAccessor.class);
|
||||
}
|
||||
return clientPropertyKeyAccessor;
|
||||
}
|
||||
@ -1220,7 +1216,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static SystemTrayAccessor getSystemTrayAccessor() {
|
||||
if (systemTrayAccessor == null) {
|
||||
unsafe.ensureClassInitialized(SystemTrayAccessor.class);
|
||||
ensureClassInitialized(SystemTrayAccessor.class);
|
||||
}
|
||||
return systemTrayAccessor;
|
||||
}
|
||||
@ -1237,7 +1233,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static TrayIconAccessor getTrayIconAccessor() {
|
||||
if (trayIconAccessor == null) {
|
||||
unsafe.ensureClassInitialized(TrayIconAccessor.class);
|
||||
ensureClassInitialized(TrayIconAccessor.class);
|
||||
}
|
||||
return trayIconAccessor;
|
||||
}
|
||||
@ -1254,7 +1250,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static DefaultKeyboardFocusManagerAccessor getDefaultKeyboardFocusManagerAccessor() {
|
||||
if (defaultKeyboardFocusManagerAccessor == null) {
|
||||
unsafe.ensureClassInitialized(DefaultKeyboardFocusManagerAccessor.class);
|
||||
ensureClassInitialized(DefaultKeyboardFocusManagerAccessor.class);
|
||||
}
|
||||
return defaultKeyboardFocusManagerAccessor;
|
||||
}
|
||||
@ -1271,7 +1267,7 @@ public final class AWTAccessor {
|
||||
public static SequencedEventAccessor getSequencedEventAccessor() {
|
||||
if (sequencedEventAccessor == null) {
|
||||
try {
|
||||
unsafe.ensureClassInitialized(
|
||||
ensureClassInitialized(
|
||||
Class.forName("java.awt.SequencedEvent"));
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
@ -1291,7 +1287,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static ToolkitAccessor getToolkitAccessor() {
|
||||
if (toolkitAccessor == null) {
|
||||
unsafe.ensureClassInitialized(Toolkit.class);
|
||||
ensureClassInitialized(Toolkit.class);
|
||||
}
|
||||
|
||||
return toolkitAccessor;
|
||||
@ -1316,7 +1312,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static SystemColorAccessor getSystemColorAccessor() {
|
||||
if (systemColorAccessor == null) {
|
||||
unsafe.ensureClassInitialized(SystemColor.class);
|
||||
ensureClassInitialized(SystemColor.class);
|
||||
}
|
||||
|
||||
return systemColorAccessor;
|
||||
@ -1334,7 +1330,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static AccessibleContextAccessor getAccessibleContextAccessor() {
|
||||
if (accessibleContextAccessor == null) {
|
||||
unsafe.ensureClassInitialized(AccessibleContext.class);
|
||||
ensureClassInitialized(AccessibleContext.class);
|
||||
}
|
||||
return accessibleContextAccessor;
|
||||
}
|
||||
@ -1351,7 +1347,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static AccessibleBundleAccessor getAccessibleBundleAccessor() {
|
||||
if (accessibleBundleAccessor == null) {
|
||||
unsafe.ensureClassInitialized(AccessibleBundle.class);
|
||||
ensureClassInitialized(AccessibleBundle.class);
|
||||
}
|
||||
return accessibleBundleAccessor;
|
||||
}
|
||||
@ -1368,7 +1364,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static DragSourceContextAccessor getDragSourceContextAccessor() {
|
||||
if (dragSourceContextAccessor == null) {
|
||||
unsafe.ensureClassInitialized(DragSourceContext.class);
|
||||
ensureClassInitialized(DragSourceContext.class);
|
||||
}
|
||||
return dragSourceContextAccessor;
|
||||
}
|
||||
@ -1385,7 +1381,7 @@ public final class AWTAccessor {
|
||||
*/
|
||||
public static DropTargetContextAccessor getDropTargetContextAccessor() {
|
||||
if (dropTargetContextAccessor == null) {
|
||||
unsafe.ensureClassInitialized(DropTargetContext.class);
|
||||
ensureClassInitialized(DropTargetContext.class);
|
||||
}
|
||||
return dropTargetContextAccessor;
|
||||
}
|
||||
@ -1397,4 +1393,9 @@ public final class AWTAccessor {
|
||||
AWTAccessor.dropTargetContextAccessor = accessor;
|
||||
}
|
||||
|
||||
private static void ensureClassInitialized(Class<?> c) {
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(c);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,8 @@
|
||||
|
||||
package sun.swing;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import javax.swing.*;
|
||||
|
||||
import javax.swing.text.JTextComponent;
|
||||
@ -40,8 +39,6 @@ import javax.swing.text.JTextComponent;
|
||||
* for another example.
|
||||
*/
|
||||
public final class SwingAccessor {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
/**
|
||||
* We don't need any objects of this class.
|
||||
* It's rather a collection of static methods
|
||||
@ -142,7 +139,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static JComponentAccessor getJComponentAccessor() {
|
||||
if (jComponentAccessor == null) {
|
||||
unsafe.ensureClassInitialized(JComponent.class);
|
||||
ensureClassInitialized(JComponent.class);
|
||||
}
|
||||
|
||||
return jComponentAccessor;
|
||||
@ -165,7 +162,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static JTextComponentAccessor getJTextComponentAccessor() {
|
||||
if (jtextComponentAccessor == null) {
|
||||
unsafe.ensureClassInitialized(JTextComponent.class);
|
||||
ensureClassInitialized(JTextComponent.class);
|
||||
}
|
||||
|
||||
return jtextComponentAccessor;
|
||||
@ -188,7 +185,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static JLightweightFrameAccessor getJLightweightFrameAccessor() {
|
||||
if (jLightweightFrameAccessor == null) {
|
||||
unsafe.ensureClassInitialized(JLightweightFrame.class);
|
||||
ensureClassInitialized(JLightweightFrame.class);
|
||||
}
|
||||
return jLightweightFrameAccessor;
|
||||
}
|
||||
@ -210,7 +207,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static UIDefaultsAccessor getUIDefaultsAccessor() {
|
||||
if (uiDefaultsAccessor == null) {
|
||||
unsafe.ensureClassInitialized(UIDefaults.class);
|
||||
ensureClassInitialized(UIDefaults.class);
|
||||
}
|
||||
return uiDefaultsAccessor;
|
||||
}
|
||||
@ -232,7 +229,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static RepaintManagerAccessor getRepaintManagerAccessor() {
|
||||
if (repaintManagerAccessor == null) {
|
||||
unsafe.ensureClassInitialized(RepaintManager.class);
|
||||
ensureClassInitialized(RepaintManager.class);
|
||||
}
|
||||
return repaintManagerAccessor;
|
||||
}
|
||||
@ -247,7 +244,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static PopupFactoryAccessor getPopupFactoryAccessor() {
|
||||
if (popupFactoryAccessor == null) {
|
||||
unsafe.ensureClassInitialized(PopupFactory.class);
|
||||
ensureClassInitialized(PopupFactory.class);
|
||||
}
|
||||
return popupFactoryAccessor;
|
||||
}
|
||||
@ -269,7 +266,7 @@ public final class SwingAccessor {
|
||||
*/
|
||||
public static KeyStrokeAccessor getKeyStrokeAccessor() {
|
||||
if (keyStrokeAccessor == null) {
|
||||
unsafe.ensureClassInitialized(KeyStroke.class);
|
||||
ensureClassInitialized(KeyStroke.class);
|
||||
}
|
||||
return keyStrokeAccessor;
|
||||
}
|
||||
@ -280,4 +277,10 @@ public final class SwingAccessor {
|
||||
public static void setKeyStrokeAccessor(KeyStrokeAccessor accessor) {
|
||||
SwingAccessor.keyStrokeAccessor = accessor;
|
||||
}
|
||||
|
||||
private static void ensureClassInitialized(Class<?> c) {
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(c);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package sun.management;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@ -39,7 +40,6 @@ import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.misc.VM.BufferPool;
|
||||
|
||||
@ -63,7 +63,9 @@ public class ManagementFactoryHelper {
|
||||
static {
|
||||
// make sure that the management lib is loaded within
|
||||
// java.lang.management.ManagementFactory
|
||||
jdk.internal.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(ManagementFactory.class);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
|
||||
private static final VMManagement jvm = new VMManagementImpl();
|
||||
|
@ -25,11 +25,10 @@
|
||||
|
||||
package sun.security.krb5;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
public class KerberosSecrets {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static JavaxSecurityAuthKerberosAccess javaxSecurityAuthKerberosAccess;
|
||||
|
||||
public static void setJavaxSecurityAuthKerberosAccess
|
||||
@ -39,8 +38,11 @@ public class KerberosSecrets {
|
||||
|
||||
public static JavaxSecurityAuthKerberosAccess
|
||||
getJavaxSecurityAuthKerberosAccess() {
|
||||
if (javaxSecurityAuthKerberosAccess == null)
|
||||
unsafe.ensureClassInitialized(KeyTab.class);
|
||||
if (javaxSecurityAuthKerberosAccess == null) {
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(KeyTab.class);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
return javaxSecurityAuthKerberosAccess;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import static org.graalvm.compiler.graph.Node.WithAllEdges;
|
||||
import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -133,6 +134,7 @@ public final class NodeClass<T> extends FieldIntrospection<T> {
|
||||
public static <T> NodeClass<T> get(Class<T> clazz) {
|
||||
int numTries = 0;
|
||||
while (true) {
|
||||
@SuppressWarnings("removal")
|
||||
boolean shouldBeInitializedBefore = UNSAFE.shouldBeInitialized(clazz);
|
||||
|
||||
NodeClass<T> result = getUnchecked(clazz);
|
||||
@ -146,13 +148,18 @@ public final class NodeClass<T> extends FieldIntrospection<T> {
|
||||
* information without failing gates.
|
||||
*/
|
||||
numTries++;
|
||||
@SuppressWarnings("removal")
|
||||
boolean shouldBeInitializedAfter = UNSAFE.shouldBeInitialized(clazz);
|
||||
String msg = "GR-9537 Reflective field access of TYPE field returned null. This is probably a bug in HotSpot class initialization. " +
|
||||
" clazz: " + clazz.getTypeName() + ", numTries: " + numTries +
|
||||
", shouldBeInitializedBefore: " + shouldBeInitializedBefore + ", shouldBeInitializedAfter: " + shouldBeInitializedAfter;
|
||||
if (numTries <= 100) {
|
||||
TTY.println(msg);
|
||||
UNSAFE.ensureClassInitialized(clazz);
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(clazz);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
throw GraalError.shouldNotReachHere(msg);
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ import java.util.Objects;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.module.Modules;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.FlightRecorder;
|
||||
@ -73,7 +72,6 @@ import jdk.jfr.internal.consumer.FileAccess;
|
||||
* {@link AccessController#doPrivileged(PrivilegedAction)}
|
||||
*/
|
||||
public final class SecuritySupport {
|
||||
private final static Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private final static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
private final static Module JFR_MODULE = Event.class.getModule();
|
||||
public final static SafePath JFC_DIRECTORY = getPathInProperty("java.home", "lib/jfr");
|
||||
@ -433,7 +431,11 @@ public final class SecuritySupport {
|
||||
}
|
||||
|
||||
static void ensureClassIsInitialized(Class<?> clazz) {
|
||||
unsafe.ensureClassInitialized(clazz);
|
||||
try {
|
||||
MethodHandles.privateLookupIn(clazz, LOOKUP).ensureInitialized(clazz);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
static Class<?> defineClass(Class<?> lookupClass, byte[] bytes) {
|
||||
|
@ -699,8 +699,19 @@ public final class Unsafe {
|
||||
* Detects if the given class may need to be initialized. This is often
|
||||
* needed in conjunction with obtaining the static field base of a
|
||||
* class.
|
||||
*
|
||||
* @deprecated No replacement API for this method. As multiple threads
|
||||
* may be trying to initialize the same class or interface at the same time.
|
||||
* The only reliable result returned by this method is {@code false}
|
||||
* indicating that the given class has been initialized. Instead, simply
|
||||
* call {@link java.lang.invoke.MethodHandles.Lookup#ensureInitialized(Class)}
|
||||
* that does nothing if the given class has already been initialized.
|
||||
* This method is subject to removal in a future version of JDK.
|
||||
*
|
||||
* @return false only if a call to {@code ensureClassInitialized} would have no effect
|
||||
*
|
||||
*/
|
||||
@Deprecated(since = "15", forRemoval = true)
|
||||
@ForceInline
|
||||
public boolean shouldBeInitialized(Class<?> c) {
|
||||
return theInternalUnsafe.shouldBeInitialized(c);
|
||||
@ -710,7 +721,11 @@ public final class Unsafe {
|
||||
* Ensures the given class has been initialized. This is often
|
||||
* needed in conjunction with obtaining the static field base of a
|
||||
* class.
|
||||
*
|
||||
* @deprecated Use the {@link java.lang.invoke.MethodHandles.Lookup#ensureInitialized(Class)}
|
||||
* method instead. This method is subject to removal in a future version of JDK.
|
||||
*/
|
||||
@Deprecated(since = "15", forRemoval = true)
|
||||
@ForceInline
|
||||
public void ensureClassInitialized(Class<?> c) {
|
||||
theInternalUnsafe.ensureClassInitialized(c);
|
||||
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8235521
|
||||
* @summary Tests for Lookup::ensureClassInitialized
|
||||
* @build java.base/* m1/* m2/* Main
|
||||
* @run testng/othervm --add-modules m1 Main
|
||||
*/
|
||||
|
||||
public class Main {
|
||||
// Test access to public java.lang class
|
||||
@Test
|
||||
public void testPublic() throws Exception {
|
||||
assertFalse(Helper.isInitialized(PublicInit.class));
|
||||
MethodHandles.lookup().ensureInitialized(PublicInit.class);
|
||||
assertTrue(Helper.isInitialized(PublicInit.class));
|
||||
// no-op if already initialized
|
||||
MethodHandles.lookup().ensureInitialized(PublicInit.class);
|
||||
}
|
||||
|
||||
// access denied to package-private java.lang class
|
||||
@Test(expectedExceptions = { IllegalAccessException.class })
|
||||
public void testPackagePrivate() throws Exception {
|
||||
Class<?> c = Class.forName("java.lang.DefaultInit", false, null);
|
||||
assertFalse(Helper.isInitialized(c));
|
||||
// access denied
|
||||
MethodHandles.lookup().ensureInitialized(c);
|
||||
}
|
||||
|
||||
// access denied to public class in a non-exported package
|
||||
@Test(expectedExceptions = { IllegalAccessException.class })
|
||||
public void testNonExportedPackage() throws Exception {
|
||||
Class<?> c = Class.forName("jdk.internal.misc.VM", false, null);
|
||||
// access denied
|
||||
MethodHandles.lookup().ensureInitialized(c);
|
||||
}
|
||||
|
||||
// invoke p1.Test::test to test module boundary access
|
||||
@Test
|
||||
public void testModuleAccess() throws Exception {
|
||||
Class<?> c = Class.forName("p1.Test");
|
||||
Method m = c.getMethod("test");
|
||||
m.invoke(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { IllegalArgumentException.class })
|
||||
public void testArrayType() throws Exception {
|
||||
Class<?> arrayType = PublicInit.class.arrayType();
|
||||
MethodHandles.lookup().ensureInitialized(arrayType);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang;
|
||||
|
||||
class DefaultInit {
|
||||
private static boolean initialized;
|
||||
static {
|
||||
initialized = true;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
public class Helper {
|
||||
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
public static boolean isInitialized(Class<?> c) {
|
||||
return !UNSAFE.shouldBeInitialized(c);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang;
|
||||
|
||||
public class PublicInit {
|
||||
private static boolean initialized;
|
||||
static {
|
||||
initialized = true;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m1 {
|
||||
requires m2;
|
||||
exports p1;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
public class A {
|
||||
static final Object lock;
|
||||
static {
|
||||
try {
|
||||
MethodHandles.lookup().ensureInitialized(A.class);
|
||||
lock = new Object();
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
class B {
|
||||
private static final B INSTANCE = new B();
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package p1;
|
||||
|
||||
import p1.internal.*;
|
||||
import static java.lang.invoke.MethodHandles.Lookup.*;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
/*
|
||||
* Test::test is invoked by Main class
|
||||
*/
|
||||
public class Test {
|
||||
public static void test() throws Exception {
|
||||
clinitInvokeEnsureClassInitialized();
|
||||
testModuleAccess();
|
||||
testPackageAccess();
|
||||
testFullPrivilegeAccess();
|
||||
}
|
||||
|
||||
/*
|
||||
* A::<clinit> calls Lookup::ensureClassInitialized(A.class)
|
||||
*/
|
||||
public static void clinitInvokeEnsureClassInitialized() throws Exception {
|
||||
assertFalse(Helper.isInitialized(A.class));
|
||||
|
||||
// same package and public type
|
||||
MethodHandles.lookup().ensureInitialized(A.class);
|
||||
assertTrue(Helper.isInitialized(A.class));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test Lookup with MODULE access to initialize class in this module
|
||||
* and another module it reads.
|
||||
*/
|
||||
public static void testModuleAccess() throws Exception {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup().dropLookupMode(PACKAGE);
|
||||
assertTrue((lookup.lookupModes() & PACKAGE) == 0);
|
||||
|
||||
assertFalse(Helper.isInitialized(p2.T.class));
|
||||
// exported by another module
|
||||
lookup.ensureInitialized(p2.T.class);
|
||||
assertTrue(Helper.isInitialized(p2.T.class));
|
||||
|
||||
// non-exported type in another module
|
||||
Class<?> x = Class.forName(p2.T.class.getModule(), "p2.internal.X");
|
||||
assertFalse(Helper.isInitialized(x));
|
||||
try {
|
||||
lookup.ensureInitialized(x);
|
||||
throw new AssertionError(lookup + " should not have access to " + x);
|
||||
} catch (IllegalAccessException e) {}
|
||||
|
||||
// no access to package-private class in the same module
|
||||
try {
|
||||
lookup.ensureInitialized(E.class);
|
||||
throw new AssertionError(lookup + " should not have access to " + E.class);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test Lookup with PACKAGE access
|
||||
*/
|
||||
public static void testPackageAccess() throws Exception {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup().dropLookupMode(PRIVATE);
|
||||
assertTrue((lookup.lookupModes() & PRIVATE) == 0);
|
||||
// verify these classes are not initialized
|
||||
assertFalse(Helper.isInitialized(B.class));
|
||||
assertFalse(Helper.isInitialized(C.class));
|
||||
assertFalse(Helper.isInitialized(E.class));
|
||||
|
||||
// same package but package-private
|
||||
lookup.ensureInitialized(B.class);
|
||||
assertTrue(Helper.isInitialized(B.class));
|
||||
|
||||
// different package and public type
|
||||
lookup.ensureInitialized(C.class);
|
||||
assertTrue(Helper.isInitialized(C.class));
|
||||
|
||||
// different package and non-public types
|
||||
Class<?> d = Class.forName(Test.class.getModule(), "p1.internal.D");
|
||||
assertFalse(Helper.isInitialized(d));
|
||||
try {
|
||||
lookup.ensureInitialized(d);
|
||||
throw new AssertionError(lookup + " should not have access to " + d);
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test Lookup with full privilege access
|
||||
*/
|
||||
public static void testFullPrivilegeAccess() throws Exception {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
// these classes have been initialized
|
||||
assertTrue(Helper.isInitialized(A.class)); // same package and public type
|
||||
assertTrue(Helper.isInitialized(B.class)); // same package but package-private
|
||||
assertTrue(Helper.isInitialized(C.class)); // different package and public type
|
||||
|
||||
// verify access to these classes
|
||||
lookup.ensureInitialized(A.class);
|
||||
lookup.ensureInitialized(B.class);
|
||||
lookup.ensureInitialized(C.class);
|
||||
|
||||
// different package and non-public types
|
||||
Class<?> d = Class.forName(Test.class.getModule(), "p1.internal.D");
|
||||
try {
|
||||
assertFalse(Helper.isInitialized(d));
|
||||
lookup.ensureInitialized(d);
|
||||
throw new AssertionError(lookup + " should not have access to " + d);
|
||||
} catch (IllegalAccessException e) {}
|
||||
|
||||
// nestmate and same package
|
||||
assertFalse(Helper.isInitialized(E.class));
|
||||
assertTrue(Test.class.isNestmateOf(E.class));
|
||||
lookup.ensureInitialized(E.class);
|
||||
}
|
||||
|
||||
public static void assertTrue(boolean v) {
|
||||
if (!v) {
|
||||
throw new AssertionError("unexpected result");
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertFalse(boolean v) {
|
||||
if (v) {
|
||||
throw new AssertionError("unexpected result");
|
||||
}
|
||||
}
|
||||
|
||||
// nestmate
|
||||
static class E {
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1.internal;
|
||||
|
||||
public class C {
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1.internal;
|
||||
|
||||
class D {
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m2 {
|
||||
exports p2 to m1;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p2;
|
||||
|
||||
public class T {
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p2.internal;
|
||||
|
||||
public class X {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user