8235521: Replacement API for Unsafe::ensureClassInitialized

Reviewed-by: alanb, chegar, psandoz
This commit is contained in:
Mandy Chung 2020-06-08 16:55:45 -07:00
parent 6fc6476da8
commit 71d646a160
22 changed files with 708 additions and 83 deletions

View File

@ -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.

View File

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

View File

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

View File

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

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);
}

View File

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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

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