8344011: Remove usage of security manager from Class and reflective APIs
Reviewed-by: liach, yzheng, rriggs
This commit is contained in:
parent
c977ef7b45
commit
abacece826
@ -30,7 +30,6 @@ import java.lang.constant.ClassDesc;
|
|||||||
import java.lang.constant.ConstantDescs;
|
import java.lang.constant.ConstantDescs;
|
||||||
import java.lang.invoke.TypeDescriptor;
|
import java.lang.invoke.TypeDescriptor;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.module.ModuleReader;
|
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -54,9 +53,7 @@ import java.lang.reflect.Type;
|
|||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.lang.constant.Constable;
|
import java.lang.constant.Constable;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.Permissions;
|
import java.security.Permissions;
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -73,10 +70,8 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import jdk.internal.constant.ConstantUtils;
|
import jdk.internal.constant.ConstantUtils;
|
||||||
import jdk.internal.javac.PreviewFeature;
|
|
||||||
import jdk.internal.loader.BootLoader;
|
import jdk.internal.loader.BootLoader;
|
||||||
import jdk.internal.loader.BuiltinClassLoader;
|
import jdk.internal.loader.BuiltinClassLoader;
|
||||||
import jdk.internal.misc.PreviewFeatures;
|
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
import jdk.internal.module.Resources;
|
import jdk.internal.module.Resources;
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
import jdk.internal.reflect.CallerSensitive;
|
||||||
@ -84,7 +79,6 @@ import jdk.internal.reflect.CallerSensitiveAdapter;
|
|||||||
import jdk.internal.reflect.ConstantPool;
|
import jdk.internal.reflect.ConstantPool;
|
||||||
import jdk.internal.reflect.Reflection;
|
import jdk.internal.reflect.Reflection;
|
||||||
import jdk.internal.reflect.ReflectionFactory;
|
import jdk.internal.reflect.ReflectionFactory;
|
||||||
import jdk.internal.vm.annotation.ForceInline;
|
|
||||||
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||||
import jdk.internal.vm.annotation.Stable;
|
import jdk.internal.vm.annotation.Stable;
|
||||||
|
|
||||||
@ -540,41 +534,10 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 13.1 The Form of a Binary
|
* @jls 13.1 The Form of a Binary
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
|
||||||
public static Class<?> forName(String name, boolean initialize,
|
|
||||||
ClassLoader loader)
|
|
||||||
throws ClassNotFoundException
|
throws ClassNotFoundException
|
||||||
{
|
{
|
||||||
Class<?> caller = null;
|
return forName0(name, initialize, loader, null);
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
// Reflective call to get caller class is only needed if a security manager
|
|
||||||
// is present. Avoid the overhead of making this call otherwise.
|
|
||||||
caller = Reflection.getCallerClass();
|
|
||||||
}
|
|
||||||
return forName(name, initialize, loader, caller);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caller-sensitive adapter method for reflective invocation
|
|
||||||
@CallerSensitiveAdapter
|
|
||||||
private static Class<?> forName(String name, boolean initialize, ClassLoader loader, Class<?> caller)
|
|
||||||
throws ClassNotFoundException
|
|
||||||
{
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
// Reflective call to get caller class is only needed if a security manager
|
|
||||||
// is present. Avoid the overhead of making this call otherwise.
|
|
||||||
if (loader == null) {
|
|
||||||
ClassLoader ccl = ClassLoader.getClassLoader(caller);
|
|
||||||
if (ccl != null) {
|
|
||||||
sm.checkPermission(
|
|
||||||
SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return forName0(name, initialize, loader, caller);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called after security check for system loader access checks have been made. */
|
/** Called after security check for system loader access checks have been made. */
|
||||||
@ -620,38 +583,11 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 12.3 Linking of Classes and Interfaces
|
* @jls 12.3 Linking of Classes and Interfaces
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@CallerSensitive
|
|
||||||
public static Class<?> forName(Module module, String name) {
|
public static Class<?> forName(Module module, String name) {
|
||||||
Class<?> caller = null;
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
caller = Reflection.getCallerClass();
|
|
||||||
}
|
|
||||||
return forName(module, name, caller);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caller-sensitive adapter method for reflective invocation
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@CallerSensitiveAdapter
|
|
||||||
private static Class<?> forName(Module module, String name, Class<?> caller) {
|
|
||||||
Objects.requireNonNull(module);
|
Objects.requireNonNull(module);
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
|
|
||||||
ClassLoader cl;
|
ClassLoader cl = module.getClassLoader();
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
if (caller != null && caller.getModule() != module) {
|
|
||||||
// if caller is null, Class.forName is the last java frame on the stack.
|
|
||||||
// java.base has all permissions
|
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
|
|
||||||
cl = AccessController.doPrivileged(pa);
|
|
||||||
} else {
|
|
||||||
cl = module.getClassLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cl != null) {
|
if (cl != null) {
|
||||||
return cl.loadClass(module, name);
|
return cl.loadClass(module, name);
|
||||||
} else {
|
} else {
|
||||||
@ -740,17 +676,11 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @throws ExceptionInInitializerError if the initialization
|
* @throws ExceptionInInitializerError if the initialization
|
||||||
* provoked by this method fails.
|
* provoked by this method fails.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
@Deprecated(since="9")
|
@Deprecated(since="9")
|
||||||
public T newInstance()
|
public T newInstance()
|
||||||
throws InstantiationException, IllegalAccessException
|
throws InstantiationException, IllegalAccessException
|
||||||
{
|
{
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructor lookup
|
// Constructor lookup
|
||||||
Constructor<T> tmpConstructor = cachedConstructor;
|
Constructor<T> tmpConstructor = cachedConstructor;
|
||||||
if (tmpConstructor == null) {
|
if (tmpConstructor == null) {
|
||||||
@ -765,13 +695,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
getConstructor0(empty, Member.DECLARED));
|
getConstructor0(empty, Member.DECLARED));
|
||||||
// Disable accessibility checks on the constructor
|
// Disable accessibility checks on the constructor
|
||||||
// access check is done with the true caller
|
// access check is done with the true caller
|
||||||
java.security.AccessController.doPrivileged(
|
c.setAccessible(true);
|
||||||
new java.security.PrivilegedAction<>() {
|
|
||||||
public Void run() {
|
|
||||||
c.setAccessible(true);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cachedConstructor = tmpConstructor = c;
|
cachedConstructor = tmpConstructor = c;
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw (InstantiationException)
|
throw (InstantiationException)
|
||||||
@ -1035,18 +959,8 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* represented by this {@code Class} object.
|
* represented by this {@code Class} object.
|
||||||
* @see java.lang.ClassLoader
|
* @see java.lang.ClassLoader
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
@ForceInline // to ensure Reflection.getCallerClass optimization
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
ClassLoader cl = classLoader;
|
return classLoader;
|
||||||
if (cl == null)
|
|
||||||
return null;
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
|
|
||||||
}
|
|
||||||
return cl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package-private to allow ClassLoader access
|
// Package-private to allow ClassLoader access
|
||||||
@ -1511,7 +1425,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Method getEnclosingMethod() {
|
public Method getEnclosingMethod() {
|
||||||
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
|
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
|
||||||
|
|
||||||
@ -1533,14 +1446,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
for(int i = 0; i < parameterClasses.length; i++)
|
for(int i = 0; i < parameterClasses.length; i++)
|
||||||
parameterClasses[i] = toClass(parameterTypes[i]);
|
parameterClasses[i] = toClass(parameterTypes[i]);
|
||||||
|
|
||||||
// Perform access check
|
|
||||||
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
|
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
|
|
||||||
Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false);
|
Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1648,7 +1554,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Constructor<?> getEnclosingConstructor() {
|
public Constructor<?> getEnclosingConstructor() {
|
||||||
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
|
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
|
||||||
|
|
||||||
@ -1666,18 +1571,11 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
// Convert Types to Classes; returned types *should*
|
// Convert Types to Classes; returned types *should*
|
||||||
// be class objects since the methodDescriptor's used
|
// be class objects since the methodDescriptor's used
|
||||||
// don't have generics information
|
// don't have generics information
|
||||||
for(int i = 0; i < parameterClasses.length; i++)
|
for (int i = 0; i < parameterClasses.length; i++)
|
||||||
parameterClasses[i] = toClass(parameterTypes[i]);
|
parameterClasses[i] = toClass(parameterTypes[i]);
|
||||||
|
|
||||||
// Perform access check
|
|
||||||
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
|
|
||||||
Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
|
||||||
Constructor<?>[] candidates = enclosingCandidate
|
Constructor<?>[] candidates = enclosingCandidate
|
||||||
.privateGetDeclaredConstructors(false);
|
.privateGetDeclaredConstructors(false);
|
||||||
/*
|
/*
|
||||||
@ -1708,19 +1606,8 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @return the declaring class for this class
|
* @return the declaring class for this class
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Class<?> getDeclaringClass() {
|
public Class<?> getDeclaringClass() {
|
||||||
final Class<?> candidate = getDeclaringClass0();
|
return getDeclaringClass0();
|
||||||
|
|
||||||
if (candidate != null) {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
candidate.checkPackageAccess(sm,
|
|
||||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return candidate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private native Class<?> getDeclaringClass0();
|
private native Class<?> getDeclaringClass0();
|
||||||
@ -1733,7 +1620,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @return the immediately enclosing class of the underlying class
|
* @return the immediately enclosing class of the underlying class
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Class<?> getEnclosingClass() {
|
public Class<?> getEnclosingClass() {
|
||||||
// There are five kinds of classes (or interfaces):
|
// There are five kinds of classes (or interfaces):
|
||||||
// a) Top level classes
|
// a) Top level classes
|
||||||
@ -1760,15 +1646,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
else
|
else
|
||||||
enclosingCandidate = enclosingClass;
|
enclosingCandidate = enclosingClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enclosingCandidate != null) {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
enclosingCandidate.checkPackageAccess(sm,
|
|
||||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return enclosingCandidate;
|
return enclosingCandidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1991,36 +1868,18 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* members of this class
|
* members of this class
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@CallerSensitive
|
|
||||||
public Class<?>[] getClasses() {
|
public Class<?>[] getClasses() {
|
||||||
SecurityManager sm = System.getSecurityManager();
|
List<Class<?>> list = new ArrayList<>();
|
||||||
if (sm != null) {
|
Class<?> currentClass = Class.this;
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
|
while (currentClass != null) {
|
||||||
}
|
for (Class<?> m : currentClass.getDeclaredClasses()) {
|
||||||
|
if (Modifier.isPublic(m.getModifiers())) {
|
||||||
// Privileged so this implementation can look at DECLARED classes,
|
list.add(m);
|
||||||
// something the caller might not have privilege to do. The code here
|
|
||||||
// is allowed to look at DECLARED classes because (1) it does not hand
|
|
||||||
// out anything other than public members and (2) public member access
|
|
||||||
// has already been ok'd by the SecurityManager.
|
|
||||||
|
|
||||||
return java.security.AccessController.doPrivileged(
|
|
||||||
new java.security.PrivilegedAction<>() {
|
|
||||||
public Class<?>[] run() {
|
|
||||||
List<Class<?>> list = new ArrayList<>();
|
|
||||||
Class<?> currentClass = Class.this;
|
|
||||||
while (currentClass != null) {
|
|
||||||
for (Class<?> m : currentClass.getDeclaredClasses()) {
|
|
||||||
if (Modifier.isPublic(m.getModifiers())) {
|
|
||||||
list.add(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentClass = currentClass.getSuperclass();
|
|
||||||
}
|
|
||||||
return list.toArray(new Class<?>[0]);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
|
}
|
||||||
|
return list.toArray(new Class<?>[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2054,13 +1913,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.2 Class Members
|
* @jls 8.2 Class Members
|
||||||
* @jls 8.3 Field Declarations
|
* @jls 8.3 Field Declarations
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Field[] getFields() {
|
public Field[] getFields() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return copyFields(privateGetPublicFields());
|
return copyFields(privateGetPublicFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2138,13 +1991,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.4 Method Declarations
|
* @jls 8.4 Method Declarations
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Method[] getMethods() {
|
public Method[] getMethods() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return copyMethods(privateGetPublicMethods());
|
return copyMethods(privateGetPublicMethods());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2173,13 +2020,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @see #getDeclaredConstructors()
|
* @see #getDeclaredConstructors()
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Constructor<?>[] getConstructors() {
|
public Constructor<?>[] getConstructors() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return copyConstructors(privateGetDeclaredConstructors(true));
|
return copyConstructors(privateGetDeclaredConstructors(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2219,14 +2060,8 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.2 Class Members
|
* @jls 8.2 Class Members
|
||||||
* @jls 8.3 Field Declarations
|
* @jls 8.3 Field Declarations
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Field getField(String name) throws NoSuchFieldException {
|
public Field getField(String name) throws NoSuchFieldException {
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
Field field = getField0(name);
|
Field field = getField0(name);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new NoSuchFieldException(name);
|
throw new NoSuchFieldException(name);
|
||||||
@ -2322,15 +2157,9 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.4 Method Declarations
|
* @jls 8.4 Method Declarations
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Method getMethod(String name, Class<?>... parameterTypes)
|
public Method getMethod(String name, Class<?>... parameterTypes)
|
||||||
throws NoSuchMethodException {
|
throws NoSuchMethodException {
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
Method method = getMethod0(name, parameterTypes);
|
Method method = getMethod0(name, parameterTypes);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException(methodToString(name, parameterTypes));
|
throw new NoSuchMethodException(methodToString(name, parameterTypes));
|
||||||
@ -2363,14 +2192,8 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @see #getDeclaredConstructor(Class[])
|
* @see #getDeclaredConstructor(Class[])
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Constructor<T> getConstructor(Class<?>... parameterTypes)
|
public Constructor<T> getConstructor(Class<?>... parameterTypes)
|
||||||
throws NoSuchMethodException {
|
throws NoSuchMethodException {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return getReflectionFactory().copyConstructor(
|
return getReflectionFactory().copyConstructor(
|
||||||
getConstructor0(parameterTypes, Member.PUBLIC));
|
getConstructor0(parameterTypes, Member.PUBLIC));
|
||||||
}
|
}
|
||||||
@ -2392,13 +2215,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @since 1.1
|
* @since 1.1
|
||||||
* @jls 8.5 Member Class and Interface Declarations
|
* @jls 8.5 Member Class and Interface Declarations
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Class<?>[] getDeclaredClasses() {
|
public Class<?>[] getDeclaredClasses() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), false);
|
|
||||||
}
|
|
||||||
return getDeclaredClasses0();
|
return getDeclaredClasses0();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2425,13 +2242,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.2 Class Members
|
* @jls 8.2 Class Members
|
||||||
* @jls 8.3 Field Declarations
|
* @jls 8.3 Field Declarations
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Field[] getDeclaredFields() {
|
public Field[] getDeclaredFields() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return copyFields(privateGetDeclaredFields(false));
|
return copyFields(privateGetDeclaredFields(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2467,13 +2278,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.10 Record Classes
|
* @jls 8.10 Record Classes
|
||||||
* @since 16
|
* @since 16
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public RecordComponent[] getRecordComponents() {
|
public RecordComponent[] getRecordComponents() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
if (!isRecord()) {
|
if (!isRecord()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -2519,13 +2324,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* programming language and JVM modeling in core reflection</a>
|
* programming language and JVM modeling in core reflection</a>
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Method[] getDeclaredMethods() {
|
public Method[] getDeclaredMethods() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return copyMethods(privateGetDeclaredMethods(false));
|
return copyMethods(privateGetDeclaredMethods(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2550,13 +2349,7 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @see #getConstructors()
|
* @see #getConstructors()
|
||||||
* @jls 8.8 Constructor Declarations
|
* @jls 8.8 Constructor Declarations
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Constructor<?>[] getDeclaredConstructors() {
|
public Constructor<?>[] getDeclaredConstructors() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
return copyConstructors(privateGetDeclaredConstructors(false));
|
return copyConstructors(privateGetDeclaredConstructors(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2581,14 +2374,8 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.2 Class Members
|
* @jls 8.2 Class Members
|
||||||
* @jls 8.3 Field Declarations
|
* @jls 8.3 Field Declarations
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Field getDeclaredField(String name) throws NoSuchFieldException {
|
public Field getDeclaredField(String name) throws NoSuchFieldException {
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
Field field = searchFields(privateGetDeclaredFields(false), name);
|
Field field = searchFields(privateGetDeclaredFields(false), name);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new NoSuchFieldException(name);
|
throw new NoSuchFieldException(name);
|
||||||
@ -2626,15 +2413,9 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 8.4 Method Declarations
|
* @jls 8.4 Method Declarations
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
|
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
|
||||||
throws NoSuchMethodException {
|
throws NoSuchMethodException {
|
||||||
Objects.requireNonNull(name);
|
Objects.requireNonNull(name);
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
|
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException(methodToString(name, parameterTypes));
|
throw new NoSuchMethodException(methodToString(name, parameterTypes));
|
||||||
@ -2703,15 +2484,8 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @see #getConstructor(Class[])
|
* @see #getConstructor(Class[])
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
|
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
|
||||||
throws NoSuchMethodException {
|
throws NoSuchMethodException {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getReflectionFactory().copyConstructor(
|
return getReflectionFactory().copyConstructor(
|
||||||
getConstructor0(parameterTypes, Member.DECLARED));
|
getConstructor0(parameterTypes, Member.DECLARED));
|
||||||
}
|
}
|
||||||
@ -2933,11 +2707,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public ProtectionDomain getProtectionDomain() {
|
public ProtectionDomain getProtectionDomain() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
|
|
||||||
}
|
|
||||||
return protectionDomain();
|
return protectionDomain();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2972,91 +2741,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
*/
|
*/
|
||||||
static native <T> Class<T> getPrimitiveClass(String name);
|
static native <T> Class<T> getPrimitiveClass(String name);
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if client is allowed to access members. If access is denied,
|
|
||||||
* throw a SecurityException.
|
|
||||||
*
|
|
||||||
* This method also enforces package access.
|
|
||||||
*
|
|
||||||
* <p> Default policy: allow all clients access with normal Java access
|
|
||||||
* control.
|
|
||||||
*
|
|
||||||
* <p> NOTE: should only be called if a SecurityManager is installed
|
|
||||||
*/
|
|
||||||
private void checkMemberAccess(@SuppressWarnings("removal") SecurityManager sm, int which,
|
|
||||||
Class<?> caller, boolean checkProxyInterfaces) {
|
|
||||||
/* Default policy allows access to all {@link Member#PUBLIC} members,
|
|
||||||
* as well as access to classes that have the same class loader as the caller.
|
|
||||||
* In all other cases, it requires RuntimePermission("accessDeclaredMembers")
|
|
||||||
* permission.
|
|
||||||
*/
|
|
||||||
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
|
|
||||||
if (which != Member.PUBLIC) {
|
|
||||||
final ClassLoader cl = classLoader;
|
|
||||||
if (ccl != cl) {
|
|
||||||
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.checkPackageAccess(sm, ccl, checkProxyInterfaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks if a client loaded in ClassLoader ccl is allowed to access this
|
|
||||||
* class under the current package access policy. If access is denied,
|
|
||||||
* throw a SecurityException.
|
|
||||||
*
|
|
||||||
* NOTE: this method should only be called if a SecurityManager is active
|
|
||||||
*/
|
|
||||||
private void checkPackageAccess(@SuppressWarnings("removal") SecurityManager sm, final ClassLoader ccl,
|
|
||||||
boolean checkProxyInterfaces) {
|
|
||||||
final ClassLoader cl = classLoader;
|
|
||||||
|
|
||||||
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
|
|
||||||
String pkg = this.getPackageName();
|
|
||||||
if (!pkg.isEmpty()) {
|
|
||||||
// skip the package access check on a proxy class in default proxy package
|
|
||||||
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
|
|
||||||
sm.checkPackageAccess(pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check package access on the proxy interfaces
|
|
||||||
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
|
|
||||||
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces(/* cloneArray */ false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks if a client loaded in ClassLoader ccl is allowed to access the provided
|
|
||||||
* classes under the current package access policy. If access is denied,
|
|
||||||
* throw a SecurityException.
|
|
||||||
*
|
|
||||||
* NOTE: this method should only be called if a SecurityManager is active
|
|
||||||
* classes must be non-empty
|
|
||||||
* all classes provided must be loaded by the same ClassLoader
|
|
||||||
* NOTE: this method does not support Proxy classes
|
|
||||||
*/
|
|
||||||
private static void checkPackageAccessForPermittedSubclasses(@SuppressWarnings("removal") SecurityManager sm,
|
|
||||||
final ClassLoader ccl, Class<?>[] subClasses) {
|
|
||||||
final ClassLoader cl = subClasses[0].classLoader;
|
|
||||||
|
|
||||||
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
|
|
||||||
Set<String> packages = new HashSet<>();
|
|
||||||
|
|
||||||
for (Class<?> c : subClasses) {
|
|
||||||
if (Proxy.isProxyClass(c))
|
|
||||||
throw new InternalError("a permitted subclass should not be a proxy class: " + c);
|
|
||||||
String pkg = c.getPackageName();
|
|
||||||
if (!pkg.isEmpty()) {
|
|
||||||
packages.add(pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String pkg : packages) {
|
|
||||||
sm.checkPackageAccess(pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a package name prefix if the name is not absolute. Remove leading "/"
|
* Add a package name prefix if the name is not absolute. Remove leading "/"
|
||||||
* if name is absolute
|
* if name is absolute
|
||||||
@ -3732,15 +3416,12 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the factory for reflective objects
|
// Fetches the factory for reflective objects
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static ReflectionFactory getReflectionFactory() {
|
private static ReflectionFactory getReflectionFactory() {
|
||||||
var factory = reflectionFactory;
|
var factory = reflectionFactory;
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
return reflectionFactory =
|
return reflectionFactory = ReflectionFactory.getReflectionFactory();
|
||||||
java.security.AccessController.doPrivileged
|
|
||||||
(new ReflectionFactory.GetReflectionFactoryAction());
|
|
||||||
}
|
}
|
||||||
private static ReflectionFactory reflectionFactory;
|
private static ReflectionFactory reflectionFactory;
|
||||||
|
|
||||||
@ -3766,20 +3447,13 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* identical to getEnumConstants except that the result is
|
* identical to getEnumConstants except that the result is
|
||||||
* uncloned, cached, and shared by all callers.
|
* uncloned, cached, and shared by all callers.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
T[] getEnumConstantsShared() {
|
T[] getEnumConstantsShared() {
|
||||||
T[] constants = enumConstants;
|
T[] constants = enumConstants;
|
||||||
if (constants == null) {
|
if (constants == null) {
|
||||||
if (!isEnum()) return null;
|
if (!isEnum()) return null;
|
||||||
try {
|
try {
|
||||||
final Method values = getMethod("values");
|
final Method values = getMethod("values");
|
||||||
java.security.AccessController.doPrivileged(
|
values.setAccessible(true);
|
||||||
new java.security.PrivilegedAction<>() {
|
|
||||||
public Void run() {
|
|
||||||
values.setAccessible(true);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T[] temporaryConstants = (T[])values.invoke(null);
|
T[] temporaryConstants = (T[])values.invoke(null);
|
||||||
enumConstants = constants = temporaryConstants;
|
enumConstants = constants = temporaryConstants;
|
||||||
@ -4160,24 +3834,11 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jvms 4.7.29 The {@code NestMembers} Attribute
|
* @jvms 4.7.29 The {@code NestMembers} Attribute
|
||||||
* @jvms 5.4.4 Access Control
|
* @jvms 5.4.4 Access Control
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Class<?> getNestHost() {
|
public Class<?> getNestHost() {
|
||||||
if (isPrimitive() || isArray()) {
|
if (isPrimitive() || isArray()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
return getNestHost0();
|
||||||
Class<?> host = getNestHost0();
|
|
||||||
if (host == this) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
// returning a different class requires a security check
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkPackageAccess(sm,
|
|
||||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
|
||||||
}
|
|
||||||
return host;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4244,7 +3905,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jvms 4.7.28 The {@code NestHost} Attribute
|
* @jvms 4.7.28 The {@code NestHost} Attribute
|
||||||
* @jvms 4.7.29 The {@code NestMembers} Attribute
|
* @jvms 4.7.29 The {@code NestMembers} Attribute
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Class<?>[] getNestMembers() {
|
public Class<?>[] getNestMembers() {
|
||||||
if (isPrimitive() || isArray()) {
|
if (isPrimitive() || isArray()) {
|
||||||
return new Class<?>[] { this };
|
return new Class<?>[] { this };
|
||||||
@ -4252,17 +3912,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
Class<?>[] members = getNestMembers0();
|
Class<?>[] members = getNestMembers0();
|
||||||
// Can't actually enable this due to bootstrapping issues
|
// Can't actually enable this due to bootstrapping issues
|
||||||
// assert(members.length != 1 || members[0] == this); // expected invariant from VM
|
// assert(members.length != 1 || members[0] == this); // expected invariant from VM
|
||||||
|
|
||||||
if (members.length > 1) {
|
|
||||||
// If we return anything other than the current class we need
|
|
||||||
// a security check
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkPackageAccess(sm,
|
|
||||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4432,7 +4081,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
* @jls 9.1 Interface Declarations
|
* @jls 9.1 Interface Declarations
|
||||||
* @since 17
|
* @since 17
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public Class<?>[] getPermittedSubclasses() {
|
public Class<?>[] getPermittedSubclasses() {
|
||||||
Class<?>[] subClasses;
|
Class<?>[] subClasses;
|
||||||
if (isArray() || isPrimitive() || (subClasses = getPermittedSubclasses0()) == null) {
|
if (isArray() || isPrimitive() || (subClasses = getPermittedSubclasses0()) == null) {
|
||||||
@ -4445,16 +4093,6 @@ public final class Class<T> implements java.io.Serializable,
|
|||||||
.toArray(s -> new Class<?>[s]);
|
.toArray(s -> new Class<?>[s]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subClasses.length > 0) {
|
|
||||||
// If we return some classes we need a security check:
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
checkPackageAccessForPermittedSubclasses(sm,
|
|
||||||
ClassLoader.getClassLoader(Reflection.getCallerClass()),
|
|
||||||
subClasses);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return subClasses;
|
return subClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@ import java.lang.reflect.AccessFlag;
|
|||||||
import java.lang.reflect.AnnotatedElement;
|
import java.lang.reflect.AnnotatedElement;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -64,14 +62,12 @@ import jdk.internal.misc.CDS;
|
|||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.module.ModuleBootstrap;
|
import jdk.internal.module.ModuleBootstrap;
|
||||||
import jdk.internal.module.ModuleBootstrap.IllegalNativeAccess;
|
|
||||||
import jdk.internal.module.ModuleLoaderMap;
|
import jdk.internal.module.ModuleLoaderMap;
|
||||||
import jdk.internal.module.ServicesCatalog;
|
import jdk.internal.module.ServicesCatalog;
|
||||||
import jdk.internal.module.Resources;
|
import jdk.internal.module.Resources;
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
import jdk.internal.reflect.CallerSensitive;
|
||||||
import jdk.internal.reflect.Reflection;
|
import jdk.internal.reflect.Reflection;
|
||||||
import jdk.internal.vm.annotation.Stable;
|
import jdk.internal.vm.annotation.Stable;
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a run-time module, either {@link #isNamed() named} or unnamed.
|
* Represents a run-time module, either {@link #isNamed() named} or unnamed.
|
||||||
@ -198,11 +194,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
* @return The class loader for this module
|
* @return The class loader for this module
|
||||||
*/
|
*/
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1556,7 +1547,6 @@ public final class Module implements AnnotatedElement {
|
|||||||
// cached class file with annotations
|
// cached class file with annotations
|
||||||
private volatile Class<?> moduleInfoClass;
|
private volatile Class<?> moduleInfoClass;
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private Class<?> moduleInfoClass() {
|
private Class<?> moduleInfoClass() {
|
||||||
Class<?> clazz = this.moduleInfoClass;
|
Class<?> clazz = this.moduleInfoClass;
|
||||||
if (clazz != null)
|
if (clazz != null)
|
||||||
@ -1566,8 +1556,7 @@ public final class Module implements AnnotatedElement {
|
|||||||
clazz = this.moduleInfoClass;
|
clazz = this.moduleInfoClass;
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
if (isNamed()) {
|
if (isNamed()) {
|
||||||
PrivilegedAction<Class<?>> pa = this::loadModuleInfoClass;
|
clazz = loadModuleInfoClass();
|
||||||
clazz = AccessController.doPrivileged(pa);
|
|
||||||
}
|
}
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
class DummyModuleInfo { }
|
class DummyModuleInfo { }
|
||||||
|
@ -44,7 +44,6 @@ import java.util.function.Function;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import jdk.internal.javac.PreviewFeature;
|
|
||||||
import jdk.internal.javac.Restricted;
|
import jdk.internal.javac.Restricted;
|
||||||
import jdk.internal.loader.ClassLoaderValue;
|
import jdk.internal.loader.ClassLoaderValue;
|
||||||
import jdk.internal.loader.Loader;
|
import jdk.internal.loader.Loader;
|
||||||
@ -54,7 +53,6 @@ import jdk.internal.misc.CDS;
|
|||||||
import jdk.internal.reflect.CallerSensitive;
|
import jdk.internal.reflect.CallerSensitive;
|
||||||
import jdk.internal.reflect.Reflection;
|
import jdk.internal.reflect.Reflection;
|
||||||
import jdk.internal.vm.annotation.Stable;
|
import jdk.internal.vm.annotation.Stable;
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A layer of modules in the Java virtual machine.
|
* A layer of modules in the Java virtual machine.
|
||||||
@ -505,9 +503,6 @@ public final class ModuleLayer {
|
|||||||
List<ModuleLayer> parents = List.copyOf(parentLayers);
|
List<ModuleLayer> parents = List.copyOf(parentLayers);
|
||||||
checkConfiguration(cf, parents);
|
checkConfiguration(cf, parents);
|
||||||
|
|
||||||
checkCreateClassLoaderPermission();
|
|
||||||
checkGetClassLoaderPermission();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Loader loader = new Loader(cf.modules(), parentLoader);
|
Loader loader = new Loader(cf.modules(), parentLoader);
|
||||||
loader.initRemotePackageMap(cf, parents);
|
loader.initRemotePackageMap(cf, parents);
|
||||||
@ -572,9 +567,6 @@ public final class ModuleLayer {
|
|||||||
List<ModuleLayer> parents = List.copyOf(parentLayers);
|
List<ModuleLayer> parents = List.copyOf(parentLayers);
|
||||||
checkConfiguration(cf, parents);
|
checkConfiguration(cf, parents);
|
||||||
|
|
||||||
checkCreateClassLoaderPermission();
|
|
||||||
checkGetClassLoaderPermission();
|
|
||||||
|
|
||||||
LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
|
LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
|
||||||
try {
|
try {
|
||||||
ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
|
ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
|
||||||
@ -654,8 +646,6 @@ public final class ModuleLayer {
|
|||||||
checkConfiguration(cf, parents);
|
checkConfiguration(cf, parents);
|
||||||
Objects.requireNonNull(clf);
|
Objects.requireNonNull(clf);
|
||||||
|
|
||||||
checkGetClassLoaderPermission();
|
|
||||||
|
|
||||||
// The boot layer is checked during module system initialization
|
// The boot layer is checked during module system initialization
|
||||||
if (boot() != null) {
|
if (boot() != null) {
|
||||||
checkForDuplicatePkgs(cf, clf);
|
checkForDuplicatePkgs(cf, clf);
|
||||||
@ -693,20 +683,6 @@ public final class ModuleLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkCreateClassLoaderPermission() {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkGetClassLoaderPermission() {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks a configuration and the module-to-loader mapping to ensure that
|
* Checks a configuration and the module-to-loader mapping to ensure that
|
||||||
* no two modules mapped to the same class loader have the same package.
|
* no two modules mapped to the same class loader have the same package.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,8 +30,6 @@ import java.lang.reflect.AnnotatedElement;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import jdk.internal.loader.BootLoader;
|
import jdk.internal.loader.BootLoader;
|
||||||
@ -417,9 +415,7 @@ public class Package extends NamedPackage implements java.lang.reflect.Annotated
|
|||||||
// find package-info.class defined by loader
|
// find package-info.class defined by loader
|
||||||
String cn = packageName() + ".package-info";
|
String cn = packageName() + ".package-info";
|
||||||
Module module = module();
|
Module module = module();
|
||||||
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
|
ClassLoader loader = module.getClassLoader();
|
||||||
@SuppressWarnings("removal")
|
|
||||||
ClassLoader loader = AccessController.doPrivileged(pa);
|
|
||||||
Class<?> c;
|
Class<?> c;
|
||||||
if (loader != null) {
|
if (loader != null) {
|
||||||
c = loader.loadClass(module, cn);
|
c = loader.loadClass(module, cn);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,7 +28,6 @@ import jdk.internal.reflect.ReflectionFactory;
|
|||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -88,10 +87,7 @@ final class PublicMethods {
|
|||||||
* Method (name, parameter types) tuple.
|
* Method (name, parameter types) tuple.
|
||||||
*/
|
*/
|
||||||
private static final class Key {
|
private static final class Key {
|
||||||
@SuppressWarnings("removal")
|
private static final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
|
||||||
private static final ReflectionFactory reflectionFactory =
|
|
||||||
AccessController.doPrivileged(
|
|
||||||
new ReflectionFactory.GetReflectionFactoryAction());
|
|
||||||
|
|
||||||
private final String name; // must be interned (as from Method.getName())
|
private final String name; // must be interned (as from Method.getName())
|
||||||
private final Class<?>[] ptypes;
|
private final Class<?>[] ptypes;
|
||||||
|
@ -107,9 +107,6 @@ import static sun.invoke.util.Wrapper.isWrapperType;
|
|||||||
* implemented by invoking the implementation method
|
* implemented by invoking the implementation method
|
||||||
* @throws LambdaConversionException If any of the meta-factory protocol
|
* @throws LambdaConversionException If any of the meta-factory protocol
|
||||||
* invariants are violated
|
* invariants are violated
|
||||||
* @throws SecurityException If a security manager is present, and it
|
|
||||||
* <a href="MethodHandles.Lookup.html#secmgr">denies access</a>
|
|
||||||
* from {@code caller} to the package of {@code implementation}.
|
|
||||||
*/
|
*/
|
||||||
AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller,
|
AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller,
|
||||||
MethodType factoryType,
|
MethodType factoryType,
|
||||||
@ -138,7 +135,7 @@ import static sun.invoke.util.Wrapper.isWrapperType;
|
|||||||
this.implementation = implementation;
|
this.implementation = implementation;
|
||||||
this.implMethodType = implementation.type();
|
this.implMethodType = implementation.type();
|
||||||
try {
|
try {
|
||||||
this.implInfo = caller.revealDirect(implementation); // may throw SecurityException
|
this.implInfo = caller.revealDirect(implementation);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new LambdaConversionException(implementation + " is not direct or cannot be cracked");
|
throw new LambdaConversionException(implementation + " is not direct or cannot be cracked");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package java.lang.invoke;
|
package java.lang.invoke;
|
||||||
|
|
||||||
import java.security.*;
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.lang.invoke.MethodHandles.Lookup;
|
import java.lang.invoke.MethodHandles.Lookup;
|
||||||
|
|
||||||
@ -85,16 +84,13 @@ final class InfoFromMemberName implements MethodHandleInfo {
|
|||||||
// For more information see comments on {@link MethodHandleNatives#linkMethod}.
|
// For more information see comments on {@link MethodHandleNatives#linkMethod}.
|
||||||
throw new IllegalArgumentException("cannot reflect signature polymorphic method");
|
throw new IllegalArgumentException("cannot reflect signature polymorphic method");
|
||||||
}
|
}
|
||||||
@SuppressWarnings("removal")
|
|
||||||
Member mem = AccessController.doPrivileged(new PrivilegedAction<>() {
|
Member mem;
|
||||||
public Member run() {
|
try {
|
||||||
try {
|
mem = reflectUnchecked();
|
||||||
return reflectUnchecked();
|
} catch (ReflectiveOperationException ex) {
|
||||||
} catch (ReflectiveOperationException ex) {
|
throw new IllegalArgumentException(ex);
|
||||||
throw new IllegalArgumentException(ex);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
try {
|
||||||
Class<?> defc = getDeclaringClass();
|
Class<?> defc = getDeclaringClass();
|
||||||
byte refKind = (byte) getReferenceKind();
|
byte refKind = (byte) getReferenceKind();
|
||||||
|
@ -29,7 +29,6 @@ import jdk.internal.constant.ClassOrInterfaceDescImpl;
|
|||||||
import jdk.internal.misc.CDS;
|
import jdk.internal.misc.CDS;
|
||||||
import jdk.internal.util.ClassFileDumper;
|
import jdk.internal.util.ClassFileDumper;
|
||||||
import sun.invoke.util.VerifyAccess;
|
import sun.invoke.util.VerifyAccess;
|
||||||
import sun.security.action.GetBooleanAction;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.classfile.ClassBuilder;
|
import java.lang.classfile.ClassBuilder;
|
||||||
@ -83,7 +82,7 @@ import sun.invoke.util.Wrapper;
|
|||||||
lambdaProxyClassFileDumper = ClassFileDumper.getInstance(dumpProxyClassesKey, "DUMP_LAMBDA_PROXY_CLASS_FILES");
|
lambdaProxyClassFileDumper = ClassFileDumper.getInstance(dumpProxyClassesKey, "DUMP_LAMBDA_PROXY_CLASS_FILES");
|
||||||
|
|
||||||
final String disableEagerInitializationKey = "jdk.internal.lambda.disableEagerInitialization";
|
final String disableEagerInitializationKey = "jdk.internal.lambda.disableEagerInitialization";
|
||||||
disableEagerInitialization = GetBooleanAction.privilegedGetProperty(disableEagerInitializationKey);
|
disableEagerInitialization = Boolean.getBoolean(disableEagerInitializationKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See context values in AbstractValidatingLambdaMetafactory
|
// See context values in AbstractValidatingLambdaMetafactory
|
||||||
@ -134,9 +133,6 @@ import sun.invoke.util.Wrapper;
|
|||||||
* implemented by invoking the implementation method
|
* implemented by invoking the implementation method
|
||||||
* @throws LambdaConversionException If any of the meta-factory protocol
|
* @throws LambdaConversionException If any of the meta-factory protocol
|
||||||
* invariants are violated
|
* invariants are violated
|
||||||
* @throws SecurityException If a security manager is present, and it
|
|
||||||
* <a href="MethodHandles.Lookup.html#secmgr">denies access</a>
|
|
||||||
* from {@code caller} to the package of {@code implementation}.
|
|
||||||
*/
|
*/
|
||||||
public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
|
public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
|
||||||
MethodType factoryType,
|
MethodType factoryType,
|
||||||
|
@ -1208,11 +1208,7 @@ abstract class MethodHandleImpl {
|
|||||||
|
|
||||||
private static boolean checkInjectedInvoker(Class<?> hostClass, Class<?> invokerClass) {
|
private static boolean checkInjectedInvoker(Class<?> hostClass, Class<?> invokerClass) {
|
||||||
assert (hostClass.getClassLoader() == invokerClass.getClassLoader()) : hostClass.getName()+" (CL)";
|
assert (hostClass.getClassLoader() == invokerClass.getClassLoader()) : hostClass.getName()+" (CL)";
|
||||||
try {
|
assert (hostClass.getProtectionDomain() == invokerClass.getProtectionDomain()) : hostClass.getName()+" (PD)";
|
||||||
assert (hostClass.getProtectionDomain() == invokerClass.getProtectionDomain()) : hostClass.getName()+" (PD)";
|
|
||||||
} catch (SecurityException ex) {
|
|
||||||
// Self-check was blocked by security manager. This is OK.
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
// Test the invoker to ensure that it really injects into the right place.
|
// Test the invoker to ensure that it really injects into the right place.
|
||||||
MethodHandle invoker = IMPL_LOOKUP.findStatic(invokerClass, "invoke_V", INVOKER_MT);
|
MethodHandle invoker = IMPL_LOOKUP.findStatic(invokerClass, "invoke_V", INVOKER_MT);
|
||||||
|
@ -33,8 +33,6 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -56,10 +54,7 @@ import java.lang.classfile.TypeKind;
|
|||||||
import jdk.internal.constant.ConstantUtils;
|
import jdk.internal.constant.ConstantUtils;
|
||||||
import jdk.internal.loader.ClassLoaders;
|
import jdk.internal.loader.ClassLoaders;
|
||||||
import jdk.internal.module.Modules;
|
import jdk.internal.module.Modules;
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
|
||||||
import jdk.internal.reflect.Reflection;
|
|
||||||
import jdk.internal.util.ClassFileDumper;
|
import jdk.internal.util.ClassFileDumper;
|
||||||
import sun.reflect.misc.ReflectUtil;
|
|
||||||
|
|
||||||
import static java.lang.constant.ConstantDescs.*;
|
import static java.lang.constant.ConstantDescs.*;
|
||||||
import static java.lang.invoke.MethodHandleStatics.*;
|
import static java.lang.invoke.MethodHandleStatics.*;
|
||||||
@ -159,7 +154,6 @@ public class MethodHandleProxies {
|
|||||||
* be converted to the type required by the requested interface
|
* be converted to the type required by the requested interface
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("doclint:reference") // cross-module links
|
@SuppressWarnings("doclint:reference") // cross-module links
|
||||||
@CallerSensitive
|
|
||||||
public static <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
|
public static <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
|
||||||
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
|
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
|
||||||
throw newIllegalArgumentException("not a public interface", intfc.getName());
|
throw newIllegalArgumentException("not a public interface", intfc.getName());
|
||||||
@ -168,17 +162,7 @@ public class MethodHandleProxies {
|
|||||||
if (intfc.isHidden())
|
if (intfc.isHidden())
|
||||||
throw newIllegalArgumentException("a hidden interface", intfc.getName());
|
throw newIllegalArgumentException("a hidden interface", intfc.getName());
|
||||||
Objects.requireNonNull(target);
|
Objects.requireNonNull(target);
|
||||||
final MethodHandle mh;
|
final MethodHandle mh = target;
|
||||||
@SuppressWarnings("removal")
|
|
||||||
var sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
final Class<?> caller = Reflection.getCallerClass();
|
|
||||||
final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
|
|
||||||
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
|
|
||||||
mh = ccl != null ? bindCaller(target, caller) : target;
|
|
||||||
} else {
|
|
||||||
mh = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define one hidden class for each interface. Create an instance of
|
// Define one hidden class for each interface. Create an instance of
|
||||||
// the hidden class for a given target method handle which will be
|
// the hidden class for a given target method handle which will be
|
||||||
@ -283,17 +267,7 @@ public class MethodHandleProxies {
|
|||||||
// define the dynamic module to the class loader of the interface
|
// define the dynamic module to the class loader of the interface
|
||||||
var definer = new Lookup(intfc).makeHiddenClassDefiner(className, template, DUMPER);
|
var definer = new Lookup(intfc).makeHiddenClassDefiner(className, template, DUMPER);
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
Lookup lookup = definer.defineClassAsLookup(true);
|
||||||
var sm = System.getSecurityManager();
|
|
||||||
Lookup lookup;
|
|
||||||
if (sm != null) {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
var l = AccessController.doPrivileged((PrivilegedAction<Lookup>) () ->
|
|
||||||
definer.defineClassAsLookup(true));
|
|
||||||
lookup = l;
|
|
||||||
} else {
|
|
||||||
lookup = definer.defineClassAsLookup(true);
|
|
||||||
}
|
|
||||||
// cache the wrapper type
|
// cache the wrapper type
|
||||||
var ret = lookup.lookupClass();
|
var ret = lookup.lookupClass();
|
||||||
WRAPPER_TYPES.add(ret);
|
WRAPPER_TYPES.add(ret);
|
||||||
|
@ -28,7 +28,6 @@ package java.lang.invoke;
|
|||||||
import jdk.internal.misc.CDS;
|
import jdk.internal.misc.CDS;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
import jdk.internal.util.ClassFileDumper;
|
import jdk.internal.util.ClassFileDumper;
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
|
|
||||||
import java.lang.reflect.ClassFileFormatVersion;
|
import java.lang.reflect.ClassFileFormatVersion;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@ -66,7 +65,7 @@ class MethodHandleStatics {
|
|||||||
static final ClassFileDumper DUMP_CLASS_FILES;
|
static final ClassFileDumper DUMP_CLASS_FILES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Properties props = GetPropertyAction.privilegedGetProperties();
|
Properties props = System.getProperties();
|
||||||
DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
|
DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
|
||||||
props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));
|
props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));
|
||||||
|
|
||||||
|
@ -36,8 +36,6 @@ import jdk.internal.vm.annotation.ForceInline;
|
|||||||
import sun.invoke.util.ValueConversions;
|
import sun.invoke.util.ValueConversions;
|
||||||
import sun.invoke.util.VerifyAccess;
|
import sun.invoke.util.VerifyAccess;
|
||||||
import sun.invoke.util.Wrapper;
|
import sun.invoke.util.Wrapper;
|
||||||
import sun.reflect.misc.ReflectUtil;
|
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
import java.lang.classfile.ClassFile;
|
import java.lang.classfile.ClassFile;
|
||||||
import java.lang.classfile.ClassModel;
|
import java.lang.classfile.ClassModel;
|
||||||
@ -243,9 +241,6 @@ public class MethodHandles {
|
|||||||
return new Lookup(targetClass);
|
return new Lookup(targetClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) sm.checkPermission(SecurityConstants.ACCESS_PERMISSION);
|
|
||||||
if (targetClass.isPrimitive())
|
if (targetClass.isPrimitive())
|
||||||
throw new IllegalArgumentException(targetClass + " is a primitive class");
|
throw new IllegalArgumentException(targetClass + " is a primitive class");
|
||||||
if (targetClass.isArray())
|
if (targetClass.isArray())
|
||||||
@ -463,9 +458,6 @@ public class MethodHandles {
|
|||||||
* @since 1.8
|
* @since 1.8
|
||||||
*/
|
*/
|
||||||
public static <T extends Member> T reflectAs(Class<T> expected, MethodHandle target) {
|
public static <T extends Member> T reflectAs(Class<T> expected, MethodHandle target) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager smgr = System.getSecurityManager();
|
|
||||||
if (smgr != null) smgr.checkPermission(SecurityConstants.ACCESS_PERMISSION);
|
|
||||||
Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
|
Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
|
||||||
return lookup.revealDirect(target).reflectAs(expected, lookup);
|
return lookup.revealDirect(target).reflectAs(expected, lookup);
|
||||||
}
|
}
|
||||||
@ -741,8 +733,6 @@ public class MethodHandles {
|
|||||||
* <ul style="font-size:smaller;">
|
* <ul style="font-size:smaller;">
|
||||||
* <li>access private fields, methods, and constructors of the lookup class and its nestmates
|
* <li>access private fields, methods, and constructors of the lookup class and its nestmates
|
||||||
* <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
|
* <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
|
||||||
* <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
|
|
||||||
* for classes accessible to the lookup class
|
|
||||||
* <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
|
* <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
|
||||||
* within the same package member
|
* within the same package member
|
||||||
* </ul>
|
* </ul>
|
||||||
@ -1759,23 +1749,11 @@ public class MethodHandles {
|
|||||||
* @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
|
* @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
|
||||||
*/
|
*/
|
||||||
public Class<?> defineClass(byte[] bytes) throws IllegalAccessException {
|
public Class<?> defineClass(byte[] bytes) throws IllegalAccessException {
|
||||||
ensureDefineClassPermission();
|
|
||||||
if ((lookupModes() & PACKAGE) == 0)
|
if ((lookupModes() & PACKAGE) == 0)
|
||||||
throw new IllegalAccessException("Lookup does not have PACKAGE access");
|
throw new IllegalAccessException("Lookup does not have PACKAGE access");
|
||||||
return makeClassDefiner(bytes.clone()).defineClass(false);
|
return makeClassDefiner(bytes.clone()).defineClass(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureDefineClassPermission() {
|
|
||||||
if (allowedModes == TRUSTED) return;
|
|
||||||
|
|
||||||
if (!hasFullPrivilegeAccess()) {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkPermission(new RuntimePermission("defineClass"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of class options that specify whether a hidden class created by
|
* The set of class options that specify whether a hidden class created by
|
||||||
* {@link Lookup#defineHiddenClass(byte[], boolean, ClassOption...)
|
* {@link Lookup#defineHiddenClass(byte[], boolean, ClassOption...)
|
||||||
@ -2042,7 +2020,6 @@ public class MethodHandles {
|
|||||||
{
|
{
|
||||||
Objects.requireNonNull(bytes);
|
Objects.requireNonNull(bytes);
|
||||||
int flags = ClassOption.optionsToFlag(options);
|
int flags = ClassOption.optionsToFlag(options);
|
||||||
ensureDefineClassPermission();
|
|
||||||
if (!hasFullPrivilegeAccess()) {
|
if (!hasFullPrivilegeAccess()) {
|
||||||
throw new IllegalAccessException(this + " does not have full privilege access");
|
throw new IllegalAccessException(this + " does not have full privilege access");
|
||||||
}
|
}
|
||||||
@ -2128,7 +2105,6 @@ public class MethodHandles {
|
|||||||
|
|
||||||
int flags = ClassOption.optionsToFlag(options);
|
int flags = ClassOption.optionsToFlag(options);
|
||||||
|
|
||||||
ensureDefineClassPermission();
|
|
||||||
if (!hasFullPrivilegeAccess()) {
|
if (!hasFullPrivilegeAccess()) {
|
||||||
throw new IllegalAccessException(this + " does not have full privilege access");
|
throw new IllegalAccessException(this + " does not have full privilege access");
|
||||||
}
|
}
|
||||||
@ -2768,7 +2744,6 @@ assertEquals("[x, y, z]", pb.command().toString());
|
|||||||
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
|
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
|
||||||
throw makeAccessException(targetClass);
|
throw makeAccessException(targetClass);
|
||||||
}
|
}
|
||||||
checkSecurityManager(targetClass);
|
|
||||||
|
|
||||||
// ensure class initialization
|
// ensure class initialization
|
||||||
Unsafe.getUnsafe().ensureClassInitialized(targetClass);
|
Unsafe.getUnsafe().ensureClassInitialized(targetClass);
|
||||||
@ -2872,7 +2847,6 @@ assertEquals("[x, y, z]", pb.command().toString());
|
|||||||
if (!isClassAccessible(targetClass)) {
|
if (!isClassAccessible(targetClass)) {
|
||||||
throw makeAccessException(targetClass);
|
throw makeAccessException(targetClass);
|
||||||
}
|
}
|
||||||
checkSecurityManager(targetClass);
|
|
||||||
return targetClass;
|
return targetClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3292,7 +3266,7 @@ return mh1;
|
|||||||
assert(method.isMethod());
|
assert(method.isMethod());
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
|
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
|
||||||
return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerLookup(method));
|
return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerLookup(method));
|
||||||
}
|
}
|
||||||
private MethodHandle unreflectForMH(Method m) {
|
private MethodHandle unreflectForMH(Method m) {
|
||||||
// these names require special lookups because they throw UnsupportedOperationException
|
// these names require special lookups because they throw UnsupportedOperationException
|
||||||
@ -3343,7 +3317,7 @@ return mh1;
|
|||||||
MemberName method = new MemberName(m, true);
|
MemberName method = new MemberName(m, true);
|
||||||
assert(method.isMethod());
|
assert(method.isMethod());
|
||||||
// ignore m.isAccessible: this is a new kind of access
|
// ignore m.isAccessible: this is a new kind of access
|
||||||
return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerLookup(method));
|
return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerLookup(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3375,12 +3349,12 @@ return mh1;
|
|||||||
assert(ctor.isConstructor());
|
assert(ctor.isConstructor());
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
|
Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
|
||||||
return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
|
return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Produces a method handle that is capable of creating instances of the given class
|
* Produces a method handle that is capable of creating instances of the given class
|
||||||
* and instantiated by the given constructor. No security manager check.
|
* and instantiated by the given constructor.
|
||||||
*
|
*
|
||||||
* This method should only be used by ReflectionFactory::newConstructorForSerialization.
|
* This method should only be used by ReflectionFactory::newConstructorForSerialization.
|
||||||
*/
|
*/
|
||||||
@ -3473,7 +3447,7 @@ return mh1;
|
|||||||
: MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
|
: MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
|
Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
|
||||||
return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
|
return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3550,8 +3524,8 @@ return mh1;
|
|||||||
public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
|
public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
|
||||||
MemberName getField = new MemberName(f, false);
|
MemberName getField = new MemberName(f, false);
|
||||||
MemberName putField = new MemberName(f, true);
|
MemberName putField = new MemberName(f, true);
|
||||||
return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(),
|
return getFieldVarHandle(getField.getReferenceKind(), putField.getReferenceKind(),
|
||||||
f.getDeclaringClass(), getField, putField);
|
f.getDeclaringClass(), getField, putField);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3586,10 +3560,9 @@ return mh1;
|
|||||||
if (refKind == REF_invokeVirtual && defc.isInterface())
|
if (refKind == REF_invokeVirtual && defc.isInterface())
|
||||||
// Symbolic reference is through interface but resolves to Object method (toString, etc.)
|
// Symbolic reference is through interface but resolves to Object method (toString, etc.)
|
||||||
refKind = REF_invokeInterface;
|
refKind = REF_invokeInterface;
|
||||||
// Check SM permissions and member access before cracking.
|
// Check member access before cracking.
|
||||||
try {
|
try {
|
||||||
checkAccess(refKind, defc, member);
|
checkAccess(refKind, defc, member);
|
||||||
checkSecurityManager(defc, member);
|
|
||||||
} catch (IllegalAccessException ex) {
|
} catch (IllegalAccessException ex) {
|
||||||
throw new IllegalArgumentException(ex);
|
throw new IllegalArgumentException(ex);
|
||||||
}
|
}
|
||||||
@ -3716,69 +3689,6 @@ return mh1;
|
|||||||
return (allowedModes & (PRIVATE|MODULE)) == (PRIVATE|MODULE);
|
return (allowedModes & (PRIVATE|MODULE)) == (PRIVATE|MODULE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform steps 1 and 2b <a href="MethodHandles.Lookup.html#secmgr">access checks</a>
|
|
||||||
* for ensureInitialized, findClass or accessClass.
|
|
||||||
*/
|
|
||||||
void checkSecurityManager(Class<?> refc) {
|
|
||||||
if (allowedModes == TRUSTED) return;
|
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager smgr = System.getSecurityManager();
|
|
||||||
if (smgr == null) return;
|
|
||||||
|
|
||||||
// Step 1:
|
|
||||||
boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
|
|
||||||
if (!fullPrivilegeLookup ||
|
|
||||||
!VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
|
|
||||||
ReflectUtil.checkPackageAccess(refc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2b:
|
|
||||||
if (!fullPrivilegeLookup) {
|
|
||||||
smgr.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform steps 1, 2a and 3 <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
|
|
||||||
* Determines a trustable caller class to compare with refc, the symbolic reference class.
|
|
||||||
* If this lookup object has full privilege access except original access,
|
|
||||||
* then the caller class is the lookupClass.
|
|
||||||
*
|
|
||||||
* Lookup object created by {@link MethodHandles#privateLookupIn(Class, Lookup)}
|
|
||||||
* from the same module skips the security permission check.
|
|
||||||
*/
|
|
||||||
void checkSecurityManager(Class<?> refc, MemberName m) {
|
|
||||||
Objects.requireNonNull(refc);
|
|
||||||
Objects.requireNonNull(m);
|
|
||||||
|
|
||||||
if (allowedModes == TRUSTED) return;
|
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager smgr = System.getSecurityManager();
|
|
||||||
if (smgr == null) return;
|
|
||||||
|
|
||||||
// Step 1:
|
|
||||||
boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
|
|
||||||
if (!fullPrivilegeLookup ||
|
|
||||||
!VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
|
|
||||||
ReflectUtil.checkPackageAccess(refc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2a:
|
|
||||||
if (m.isPublic()) return;
|
|
||||||
if (!fullPrivilegeLookup) {
|
|
||||||
smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3:
|
|
||||||
Class<?> defc = m.getDeclaringClass();
|
|
||||||
if (!fullPrivilegeLookup && defc != refc) {
|
|
||||||
ReflectUtil.checkPackageAccess(defc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
|
void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
|
||||||
boolean wantStatic = (refKind == REF_invokeStatic);
|
boolean wantStatic = (refKind == REF_invokeStatic);
|
||||||
String message;
|
String message;
|
||||||
@ -3918,30 +3828,18 @@ return mh1;
|
|||||||
/** Check access and get the requested method. */
|
/** Check access and get the requested method. */
|
||||||
private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
|
private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
|
||||||
final boolean doRestrict = true;
|
final boolean doRestrict = true;
|
||||||
final boolean checkSecurity = true;
|
return getDirectMethodCommon(refKind, refc, method, doRestrict, callerLookup);
|
||||||
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
|
|
||||||
}
|
}
|
||||||
/** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
|
/** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
|
||||||
private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
|
private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
|
||||||
final boolean doRestrict = false;
|
final boolean doRestrict = false;
|
||||||
final boolean checkSecurity = true;
|
return getDirectMethodCommon(REF_invokeSpecial, refc, method, doRestrict, callerLookup);
|
||||||
return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
|
|
||||||
}
|
|
||||||
/** Check access and get the requested method, eliding security manager checks. */
|
|
||||||
private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
|
|
||||||
final boolean doRestrict = true;
|
|
||||||
final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
|
|
||||||
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
|
|
||||||
}
|
}
|
||||||
/** Common code for all methods; do not call directly except from immediately above. */
|
/** Common code for all methods; do not call directly except from immediately above. */
|
||||||
private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
|
private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
|
||||||
boolean checkSecurity,
|
|
||||||
boolean doRestrict,
|
boolean doRestrict,
|
||||||
Lookup boundCaller) throws IllegalAccessException {
|
Lookup boundCaller) throws IllegalAccessException {
|
||||||
checkMethod(refKind, refc, method);
|
checkMethod(refKind, refc, method);
|
||||||
// Optionally check with the security manager; this isn't needed for unreflect* calls.
|
|
||||||
if (checkSecurity)
|
|
||||||
checkSecurityManager(refc, method);
|
|
||||||
assert(!method.isMethodHandleInvoke());
|
assert(!method.isMethodHandleInvoke());
|
||||||
|
|
||||||
if (refKind == REF_invokeSpecial &&
|
if (refKind == REF_invokeSpecial &&
|
||||||
@ -4010,21 +3908,11 @@ return mh1;
|
|||||||
|
|
||||||
/** Check access and get the requested field. */
|
/** Check access and get the requested field. */
|
||||||
private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
|
private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
|
||||||
final boolean checkSecurity = true;
|
return getDirectFieldCommon(refKind, refc, field);
|
||||||
return getDirectFieldCommon(refKind, refc, field, checkSecurity);
|
|
||||||
}
|
|
||||||
/** Check access and get the requested field, eliding security manager checks. */
|
|
||||||
private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
|
|
||||||
final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
|
|
||||||
return getDirectFieldCommon(refKind, refc, field, checkSecurity);
|
|
||||||
}
|
}
|
||||||
/** Common code for all fields; do not call directly except from immediately above. */
|
/** Common code for all fields; do not call directly except from immediately above. */
|
||||||
private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field,
|
private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
|
||||||
boolean checkSecurity) throws IllegalAccessException {
|
|
||||||
checkField(refKind, refc, field);
|
checkField(refKind, refc, field);
|
||||||
// Optionally check with the security manager; this isn't needed for unreflect* calls.
|
|
||||||
if (checkSecurity)
|
|
||||||
checkSecurityManager(refc, field);
|
|
||||||
DirectMethodHandle dmh = DirectMethodHandle.make(refc, field);
|
DirectMethodHandle dmh = DirectMethodHandle.make(refc, field);
|
||||||
boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
|
boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
|
||||||
restrictProtectedReceiver(field));
|
restrictProtectedReceiver(field));
|
||||||
@ -4035,26 +3923,17 @@ return mh1;
|
|||||||
private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind,
|
private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind,
|
||||||
Class<?> refc, MemberName getField, MemberName putField)
|
Class<?> refc, MemberName getField, MemberName putField)
|
||||||
throws IllegalAccessException {
|
throws IllegalAccessException {
|
||||||
final boolean checkSecurity = true;
|
return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField);
|
||||||
return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
|
|
||||||
}
|
|
||||||
private VarHandle getFieldVarHandleNoSecurityManager(byte getRefKind, byte putRefKind,
|
|
||||||
Class<?> refc, MemberName getField, MemberName putField)
|
|
||||||
throws IllegalAccessException {
|
|
||||||
final boolean checkSecurity = false;
|
|
||||||
return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
|
|
||||||
}
|
}
|
||||||
private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind,
|
private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind,
|
||||||
Class<?> refc, MemberName getField, MemberName putField,
|
Class<?> refc, MemberName getField,
|
||||||
boolean checkSecurity) throws IllegalAccessException {
|
MemberName putField) throws IllegalAccessException {
|
||||||
assert getField.isStatic() == putField.isStatic();
|
assert getField.isStatic() == putField.isStatic();
|
||||||
assert getField.isGetter() && putField.isSetter();
|
assert getField.isGetter() && putField.isSetter();
|
||||||
assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind);
|
assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind);
|
||||||
assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind);
|
assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind);
|
||||||
|
|
||||||
checkField(getRefKind, refc, getField);
|
checkField(getRefKind, refc, getField);
|
||||||
if (checkSecurity)
|
|
||||||
checkSecurityManager(refc, getField);
|
|
||||||
|
|
||||||
if (!putField.isFinal()) {
|
if (!putField.isFinal()) {
|
||||||
// A VarHandle does not support updates to final fields, any
|
// A VarHandle does not support updates to final fields, any
|
||||||
@ -4062,8 +3941,6 @@ return mh1;
|
|||||||
// therefore the following write-based accessibility checks are
|
// therefore the following write-based accessibility checks are
|
||||||
// only required for non-final fields
|
// only required for non-final fields
|
||||||
checkField(putRefKind, refc, putField);
|
checkField(putRefKind, refc, putField);
|
||||||
if (checkSecurity)
|
|
||||||
checkSecurityManager(refc, putField);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
|
boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
|
||||||
@ -4081,22 +3958,12 @@ return mh1;
|
|||||||
}
|
}
|
||||||
/** Check access and get the requested constructor. */
|
/** Check access and get the requested constructor. */
|
||||||
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
|
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
|
||||||
final boolean checkSecurity = true;
|
return getDirectConstructorCommon(refc, ctor);
|
||||||
return getDirectConstructorCommon(refc, ctor, checkSecurity);
|
|
||||||
}
|
|
||||||
/** Check access and get the requested constructor, eliding security manager checks. */
|
|
||||||
private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
|
|
||||||
final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
|
|
||||||
return getDirectConstructorCommon(refc, ctor, checkSecurity);
|
|
||||||
}
|
}
|
||||||
/** Common code for all constructors; do not call directly except from immediately above. */
|
/** Common code for all constructors; do not call directly except from immediately above. */
|
||||||
private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
|
private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor) throws IllegalAccessException {
|
||||||
boolean checkSecurity) throws IllegalAccessException {
|
|
||||||
assert(ctor.isConstructor());
|
assert(ctor.isConstructor());
|
||||||
checkAccess(REF_newInvokeSpecial, refc, ctor);
|
checkAccess(REF_newInvokeSpecial, refc, ctor);
|
||||||
// Optionally check with the security manager; this isn't needed for unreflect* calls.
|
|
||||||
if (checkSecurity)
|
|
||||||
checkSecurityManager(refc, ctor);
|
|
||||||
assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
|
assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
|
||||||
return DirectMethodHandle.make(ctor).setVarargs(ctor);
|
return DirectMethodHandle.make(ctor).setVarargs(ctor);
|
||||||
}
|
}
|
||||||
@ -4163,14 +4030,9 @@ return mh1;
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
MemberName resolved2 = publicLookup().resolveOrNull(refKind,
|
||||||
MemberName resolved2 = publicLookup().resolveOrNull(refKind,
|
|
||||||
new MemberName(refKind, defc, member.getName(), member.getType()));
|
new MemberName(refKind, defc, member.getName(), member.getType()));
|
||||||
if (resolved2 == null) {
|
if (resolved2 == null) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
checkSecurityManager(defc, resolved2);
|
|
||||||
} catch (SecurityException ex) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -4178,11 +4040,11 @@ return mh1;
|
|||||||
private MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
|
private MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
|
||||||
throws ReflectiveOperationException {
|
throws ReflectiveOperationException {
|
||||||
if (MethodHandleNatives.refKindIsField(refKind)) {
|
if (MethodHandleNatives.refKindIsField(refKind)) {
|
||||||
return getDirectFieldNoSecurityManager(refKind, defc, member);
|
return getDirectField(refKind, defc, member);
|
||||||
} else if (MethodHandleNatives.refKindIsMethod(refKind)) {
|
} else if (MethodHandleNatives.refKindIsMethod(refKind)) {
|
||||||
return getDirectMethodNoSecurityManager(refKind, defc, member, findBoundCallerLookup(member));
|
return getDirectMethod(refKind, defc, member, findBoundCallerLookup(member));
|
||||||
} else if (refKind == REF_newInvokeSpecial) {
|
} else if (refKind == REF_newInvokeSpecial) {
|
||||||
return getDirectConstructorNoSecurityManager(defc, member);
|
return getDirectConstructor(defc, member);
|
||||||
}
|
}
|
||||||
// oops
|
// oops
|
||||||
throw newIllegalArgumentException("bad MethodHandle constant #"+member);
|
throw newIllegalArgumentException("bad MethodHandle constant #"+member);
|
||||||
|
@ -28,21 +28,15 @@ package java.lang.invoke;
|
|||||||
import java.lang.constant.ClassDesc;
|
import java.lang.constant.ClassDesc;
|
||||||
import java.lang.constant.Constable;
|
import java.lang.constant.Constable;
|
||||||
import java.lang.constant.MethodTypeDesc;
|
import java.lang.constant.MethodTypeDesc;
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.lang.ref.ReferenceQueue;
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import jdk.internal.util.ReferencedKeySet;
|
import jdk.internal.util.ReferencedKeySet;
|
||||||
import jdk.internal.util.ReferenceKey;
|
import jdk.internal.util.ReferenceKey;
|
||||||
@ -50,7 +44,6 @@ import jdk.internal.vm.annotation.Stable;
|
|||||||
import sun.invoke.util.BytecodeDescriptor;
|
import sun.invoke.util.BytecodeDescriptor;
|
||||||
import sun.invoke.util.VerifyType;
|
import sun.invoke.util.VerifyType;
|
||||||
import sun.invoke.util.Wrapper;
|
import sun.invoke.util.Wrapper;
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
|
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
|
||||||
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
|
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
|
||||||
@ -1183,13 +1176,6 @@ class MethodType
|
|||||||
public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
|
public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
|
||||||
throws IllegalArgumentException, TypeNotPresentException
|
throws IllegalArgumentException, TypeNotPresentException
|
||||||
{
|
{
|
||||||
if (loader == null) {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fromDescriptor(descriptor,
|
return fromDescriptor(descriptor,
|
||||||
(loader == null) ? ClassLoader.getSystemClassLoader() : loader);
|
(loader == null) ? ClassLoader.getSystemClassLoader() : loader);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,9 +28,6 @@ import java.io.Serializable;
|
|||||||
import java.io.InvalidObjectException;
|
import java.io.InvalidObjectException;
|
||||||
import java.io.ObjectStreamException;
|
import java.io.ObjectStreamException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedActionException;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,25 +262,11 @@ public final class SerializedLambda implements Serializable {
|
|||||||
@java.io.Serial
|
@java.io.Serial
|
||||||
private Object readResolve() throws ObjectStreamException {
|
private Object readResolve() throws ObjectStreamException {
|
||||||
try {
|
try {
|
||||||
@SuppressWarnings("removal")
|
Method deserialize = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
|
||||||
Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
|
deserialize.setAccessible(true);
|
||||||
@Override
|
|
||||||
public Method run() throws Exception {
|
|
||||||
Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
|
|
||||||
m.setAccessible(true);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return deserialize.invoke(null, this);
|
return deserialize.invoke(null, this);
|
||||||
} catch (ReflectiveOperationException roe) {
|
} catch (ReflectiveOperationException roe) {
|
||||||
throw new InvalidObjectException("ReflectiveOperationException during deserialization", roe);
|
throw new InvalidObjectException("ReflectiveOperationException during deserialization", roe);
|
||||||
} catch (PrivilegedActionException e) {
|
|
||||||
Exception cause = e.getException();
|
|
||||||
if (cause instanceof RuntimeException re)
|
|
||||||
throw re;
|
|
||||||
else
|
|
||||||
throw new RuntimeException("Exception in SerializedLambda.readResolve", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,15 +28,12 @@ package java.lang.reflect;
|
|||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.security.AccessController;
|
|
||||||
|
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
import jdk.internal.reflect.CallerSensitive;
|
||||||
import jdk.internal.reflect.Reflection;
|
import jdk.internal.reflect.Reflection;
|
||||||
import jdk.internal.reflect.ReflectionFactory;
|
import jdk.internal.reflect.ReflectionFactory;
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code AccessibleObject} class is the base class for {@code Field},
|
* The {@code AccessibleObject} class is the base class for {@code Field},
|
||||||
@ -81,17 +78,6 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
SharedSecrets.setJavaLangReflectAccess(new ReflectAccess());
|
SharedSecrets.setJavaLangReflectAccess(new ReflectAccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkPermission() {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
// SecurityConstants.ACCESS_PERMISSION is used to check
|
|
||||||
// whether a client has sufficient privilege to defeat Java
|
|
||||||
// language access control checks.
|
|
||||||
sm.checkPermission(SecurityConstants.ACCESS_PERMISSION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to set the {@code accessible} flag for an
|
* Convenience method to set the {@code accessible} flag for an
|
||||||
* array of reflected objects.
|
* array of reflected objects.
|
||||||
@ -114,7 +100,6 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
*/
|
*/
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
public static void setAccessible(AccessibleObject[] array, boolean flag) {
|
public static void setAccessible(AccessibleObject[] array, boolean flag) {
|
||||||
checkPermission();
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
Class<?> caller = Reflection.getCallerClass();
|
Class<?> caller = Reflection.getCallerClass();
|
||||||
array = array.clone();
|
array = array.clone();
|
||||||
@ -196,7 +181,6 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
*/
|
*/
|
||||||
@CallerSensitive // overrides in Method/Field/Constructor are @CS
|
@CallerSensitive // overrides in Method/Field/Constructor are @CS
|
||||||
public void setAccessible(boolean flag) {
|
public void setAccessible(boolean flag) {
|
||||||
AccessibleObject.checkPermission();
|
|
||||||
setAccessible0(flag);
|
setAccessible0(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,8 +241,6 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
*/
|
*/
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
public final boolean trySetAccessible() {
|
public final boolean trySetAccessible() {
|
||||||
AccessibleObject.checkPermission();
|
|
||||||
|
|
||||||
if (override == true) return true;
|
if (override == true) return true;
|
||||||
|
|
||||||
// if it's not a Constructor, Method, Field then no access check
|
// if it's not a Constructor, Method, Field then no access check
|
||||||
@ -502,10 +484,7 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
// Reflection factory used by subclasses for creating field,
|
// Reflection factory used by subclasses for creating field,
|
||||||
// method, and constructor accessors. Note that this is called
|
// method, and constructor accessors. Note that this is called
|
||||||
// very early in the bootstrapping process.
|
// very early in the bootstrapping process.
|
||||||
@SuppressWarnings("removal")
|
static final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
|
||||||
static final ReflectionFactory reflectionFactory =
|
|
||||||
AccessController.doPrivileged(
|
|
||||||
new ReflectionFactory.GetReflectionFactoryAction());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@ -623,8 +602,7 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
// For non-public members or members in package-private classes,
|
// For non-public members or members in package-private classes,
|
||||||
// it is necessary to perform somewhat expensive access checks.
|
// it is necessary to perform somewhat expensive access checks.
|
||||||
// If the access check succeeds for a given class, it will
|
// If the access check succeeds for a given class, it will
|
||||||
// always succeed (it is not affected by the granting or revoking
|
// always succeed; we speed up the check in the common case by
|
||||||
// of permissions); we speed up the check in the common case by
|
|
||||||
// remembering the last Class for which the check succeeded.
|
// remembering the last Class for which the check succeeded.
|
||||||
//
|
//
|
||||||
// The simple access check for Constructor is to see if
|
// The simple access check for Constructor is to see if
|
||||||
@ -756,8 +734,7 @@ public class AccessibleObject implements AnnotatedElement {
|
|||||||
*/
|
*/
|
||||||
private static boolean printStackTraceWhenAccessFails() {
|
private static boolean printStackTraceWhenAccessFails() {
|
||||||
if (!printStackPropertiesSet && VM.initLevel() >= 1) {
|
if (!printStackPropertiesSet && VM.initLevel() >= 1) {
|
||||||
String s = GetPropertyAction.privilegedGetProperty(
|
String s = System.getProperty("sun.reflect.debugModuleAccessChecks");
|
||||||
"sun.reflect.debugModuleAccessChecks");
|
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
printStackWhenAccessFails = !s.equalsIgnoreCase("false");
|
printStackWhenAccessFails = !s.equalsIgnoreCase("false");
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,6 @@ public final class Constructor<T> extends Executable {
|
|||||||
@Override
|
@Override
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
public void setAccessible(boolean flag) {
|
public void setAccessible(boolean flag) {
|
||||||
AccessibleObject.checkPermission();
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
checkCanSetAccessible(Reflection.getCallerClass());
|
checkCanSetAccessible(Reflection.getCallerClass());
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,6 @@ class Field extends AccessibleObject implements Member {
|
|||||||
@Override
|
@Override
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
public void setAccessible(boolean flag) {
|
public void setAccessible(boolean flag) {
|
||||||
AccessibleObject.checkPermission();
|
|
||||||
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
|
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
|
||||||
setAccessible0(flag);
|
setAccessible0(flag);
|
||||||
}
|
}
|
||||||
@ -1155,7 +1154,6 @@ class Field extends AccessibleObject implements Member {
|
|||||||
modifiers);
|
modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// security check is done before calling this method
|
|
||||||
private FieldAccessor getFieldAccessor() {
|
private FieldAccessor getFieldAccessor() {
|
||||||
FieldAccessor a = fieldAccessor;
|
FieldAccessor a = fieldAccessor;
|
||||||
return (a != null) ? a : acquireFieldAccessor();
|
return (a != null) ? a : acquireFieldAccessor();
|
||||||
|
@ -173,7 +173,6 @@ public final class Method extends Executable {
|
|||||||
@Override
|
@Override
|
||||||
@CallerSensitive
|
@CallerSensitive
|
||||||
public void setAccessible(boolean flag) {
|
public void setAccessible(boolean flag) {
|
||||||
AccessibleObject.checkPermission();
|
|
||||||
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
|
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
|
||||||
setAccessible0(flag);
|
setAccessible0(flag);
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,6 @@ import java.lang.invoke.MethodHandles;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.invoke.WrongMethodTypeException;
|
import java.lang.invoke.WrongMethodTypeException;
|
||||||
import java.lang.module.ModuleDescriptor;
|
import java.lang.module.ModuleDescriptor;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -52,13 +50,9 @@ import jdk.internal.access.JavaLangAccess;
|
|||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.module.Modules;
|
import jdk.internal.module.Modules;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
|
||||||
import jdk.internal.reflect.Reflection;
|
|
||||||
import jdk.internal.loader.ClassLoaderValue;
|
import jdk.internal.loader.ClassLoaderValue;
|
||||||
import jdk.internal.vm.annotation.Stable;
|
import jdk.internal.vm.annotation.Stable;
|
||||||
import sun.reflect.misc.ReflectUtil;
|
import sun.reflect.misc.ReflectUtil;
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
import static java.lang.invoke.MethodType.methodType;
|
import static java.lang.invoke.MethodType.methodType;
|
||||||
import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
|
import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
|
||||||
@ -366,17 +360,11 @@ public class Proxy implements java.io.Serializable {
|
|||||||
* @see <a href="#membership">Package and Module Membership of Proxy Class</a>
|
* @see <a href="#membership">Package and Module Membership of Proxy Class</a>
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@CallerSensitive
|
|
||||||
public static Class<?> getProxyClass(ClassLoader loader,
|
public static Class<?> getProxyClass(ClassLoader loader,
|
||||||
Class<?>... interfaces)
|
Class<?>... interfaces)
|
||||||
throws IllegalArgumentException
|
throws IllegalArgumentException
|
||||||
{
|
{
|
||||||
@SuppressWarnings("removal")
|
return getProxyConstructor(loader, interfaces)
|
||||||
Class<?> caller = System.getSecurityManager() == null
|
|
||||||
? null
|
|
||||||
: Reflection.getCallerClass();
|
|
||||||
|
|
||||||
return getProxyConstructor(caller, loader, interfaces)
|
|
||||||
.getDeclaringClass();
|
.getDeclaringClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,25 +374,18 @@ public class Proxy implements java.io.Serializable {
|
|||||||
* and an array of interfaces. The returned constructor will have the
|
* and an array of interfaces. The returned constructor will have the
|
||||||
* {@link Constructor#setAccessible(boolean) accessible} flag already set.
|
* {@link Constructor#setAccessible(boolean) accessible} flag already set.
|
||||||
*
|
*
|
||||||
* @param caller passed from a public-facing @CallerSensitive method if
|
|
||||||
* SecurityManager is set or {@code null} if there's no
|
|
||||||
* SecurityManager
|
|
||||||
* @param loader the class loader to define the proxy class
|
* @param loader the class loader to define the proxy class
|
||||||
* @param interfaces the list of interfaces for the proxy class
|
* @param interfaces the list of interfaces for the proxy class
|
||||||
* to implement
|
* to implement
|
||||||
* @return a Constructor of the proxy class taking single
|
* @return a Constructor of the proxy class taking single
|
||||||
* {@code InvocationHandler} parameter
|
* {@code InvocationHandler} parameter
|
||||||
*/
|
*/
|
||||||
private static Constructor<?> getProxyConstructor(Class<?> caller,
|
private static Constructor<?> getProxyConstructor(ClassLoader loader,
|
||||||
ClassLoader loader,
|
|
||||||
Class<?>... interfaces)
|
Class<?>... interfaces)
|
||||||
{
|
{
|
||||||
// optimization for single interface
|
// optimization for single interface
|
||||||
if (interfaces.length == 1) {
|
if (interfaces.length == 1) {
|
||||||
Class<?> intf = interfaces[0];
|
Class<?> intf = interfaces[0];
|
||||||
if (caller != null) {
|
|
||||||
checkProxyAccess(caller, loader, intf);
|
|
||||||
}
|
|
||||||
return proxyCache.sub(intf).computeIfAbsent(
|
return proxyCache.sub(intf).computeIfAbsent(
|
||||||
loader,
|
loader,
|
||||||
(ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
|
(ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
|
||||||
@ -412,9 +393,6 @@ public class Proxy implements java.io.Serializable {
|
|||||||
} else {
|
} else {
|
||||||
// interfaces cloned
|
// interfaces cloned
|
||||||
final Class<?>[] intfsArray = interfaces.clone();
|
final Class<?>[] intfsArray = interfaces.clone();
|
||||||
if (caller != null) {
|
|
||||||
checkProxyAccess(caller, loader, intfsArray);
|
|
||||||
}
|
|
||||||
final List<Class<?>> intfs = Arrays.asList(intfsArray);
|
final List<Class<?>> intfs = Arrays.asList(intfsArray);
|
||||||
return proxyCache.sub(intfs).computeIfAbsent(
|
return proxyCache.sub(intfs).computeIfAbsent(
|
||||||
loader,
|
loader,
|
||||||
@ -423,39 +401,6 @@ public class Proxy implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check permissions required to create a Proxy class.
|
|
||||||
*
|
|
||||||
* To define a proxy class, it performs the access checks as in
|
|
||||||
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
|
|
||||||
* 1. "getClassLoader" permission check if loader == null
|
|
||||||
* 2. checkPackageAccess on the interfaces it implements
|
|
||||||
*
|
|
||||||
* To get a constructor and new instance of a proxy class, it performs
|
|
||||||
* the package access check on the interfaces it implements
|
|
||||||
* as in Class.getConstructor.
|
|
||||||
*
|
|
||||||
* If an interface is non-public, the proxy class must be defined by
|
|
||||||
* the defining loader of the interface. If the caller's class loader
|
|
||||||
* is not the same as the defining loader of the interface, the VM
|
|
||||||
* will throw IllegalAccessError when the generated proxy class is
|
|
||||||
* being defined.
|
|
||||||
*/
|
|
||||||
private static void checkProxyAccess(Class<?> caller,
|
|
||||||
ClassLoader loader,
|
|
||||||
Class<?> ... interfaces)
|
|
||||||
{
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
ClassLoader ccl = caller.getClassLoader();
|
|
||||||
if (loader == null && ccl != null) {
|
|
||||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
|
||||||
}
|
|
||||||
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder for a proxy class.
|
* Builder for a proxy class.
|
||||||
*
|
*
|
||||||
@ -516,7 +461,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
? proxyClassNamePrefix + num
|
? proxyClassNamePrefix + num
|
||||||
: context.packageName() + "." + proxyClassNamePrefix + num;
|
: context.packageName() + "." + proxyClassNamePrefix + num;
|
||||||
|
|
||||||
ClassLoader loader = getLoader(context.module());
|
ClassLoader loader = context.module().getClassLoader();
|
||||||
trace(proxyName, context.module(), loader, interfaces);
|
trace(proxyName, context.module(), loader, interfaces);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -586,8 +531,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String DEBUG =
|
private static final String DEBUG = System.getProperty("jdk.proxy.debug", "");
|
||||||
GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
|
|
||||||
|
|
||||||
private static boolean isDebug() {
|
private static boolean isDebug() {
|
||||||
return !DEBUG.isEmpty();
|
return !DEBUG.isEmpty();
|
||||||
@ -618,7 +562,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
|
|
||||||
this.interfaces = interfaces;
|
this.interfaces = interfaces;
|
||||||
this.context = proxyClassContext(loader, interfaces, refTypes);
|
this.context = proxyClassContext(loader, interfaces, refTypes);
|
||||||
assert getLoader(context.module()) == loader;
|
assert context.module().getClassLoader() == loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyBuilder(ClassLoader loader, Class<?> intf) {
|
ProxyBuilder(ClassLoader loader, Class<?> intf) {
|
||||||
@ -630,11 +574,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
* accessible flag already set. If the target module does not have access
|
* accessible flag already set. If the target module does not have access
|
||||||
* to any interface types, IllegalAccessError will be thrown by the VM
|
* to any interface types, IllegalAccessError will be thrown by the VM
|
||||||
* at defineClass time.
|
* at defineClass time.
|
||||||
*
|
|
||||||
* Must call the checkProxyAccess method to perform permission checks
|
|
||||||
* before calling this.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
Constructor<?> build() {
|
Constructor<?> build() {
|
||||||
Class<?> proxyClass = defineProxyClass(context, interfaces);
|
Class<?> proxyClass = defineProxyClass(context, interfaces);
|
||||||
|
|
||||||
@ -644,12 +584,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw new InternalError(e.toString(), e);
|
throw new InternalError(e.toString(), e);
|
||||||
}
|
}
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
cons.setAccessible(true);
|
||||||
public Void run() {
|
|
||||||
cons.setAccessible(true);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return cons;
|
return cons;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,7 +723,7 @@ public class Proxy implements java.io.Serializable {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"cannot have non-public interfaces in different packages");
|
"cannot have non-public interfaces in different packages");
|
||||||
}
|
}
|
||||||
if (getLoader(m) != loader) {
|
if (m.getClassLoader() != loader) {
|
||||||
// the specified loader is not the same class loader
|
// the specified loader is not the same class loader
|
||||||
// of the non-public interface
|
// of the non-public interface
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@ -979,36 +914,24 @@ public class Proxy implements java.io.Serializable {
|
|||||||
*
|
*
|
||||||
* @see <a href="#membership">Package and Module Membership of Proxy Class</a>
|
* @see <a href="#membership">Package and Module Membership of Proxy Class</a>
|
||||||
*/
|
*/
|
||||||
@CallerSensitive
|
|
||||||
public static Object newProxyInstance(ClassLoader loader,
|
public static Object newProxyInstance(ClassLoader loader,
|
||||||
Class<?>[] interfaces,
|
Class<?>[] interfaces,
|
||||||
InvocationHandler h) {
|
InvocationHandler h) {
|
||||||
Objects.requireNonNull(h);
|
Objects.requireNonNull(h);
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
final Class<?> caller = System.getSecurityManager() == null
|
|
||||||
? null
|
|
||||||
: Reflection.getCallerClass();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up or generate the designated proxy class and its constructor.
|
* Look up or generate the designated proxy class and its constructor.
|
||||||
*/
|
*/
|
||||||
Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
|
Constructor<?> cons = getProxyConstructor(loader, interfaces);
|
||||||
|
|
||||||
return newProxyInstance(caller, cons, h);
|
return newProxyInstance(cons, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager
|
private static Object newProxyInstance(Constructor<?> cons, InvocationHandler h) {
|
||||||
Constructor<?> cons,
|
|
||||||
InvocationHandler h) {
|
|
||||||
/*
|
/*
|
||||||
* Invoke its constructor with the designated invocation handler.
|
* Invoke its constructor with the designated invocation handler.
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
if (caller != null) {
|
|
||||||
checkNewProxyPermission(caller, cons.getDeclaringClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
return cons.newInstance(new Object[]{h});
|
return cons.newInstance(new Object[]{h});
|
||||||
} catch (IllegalAccessException | InstantiationException e) {
|
} catch (IllegalAccessException | InstantiationException e) {
|
||||||
throw new InternalError(e.toString(), e);
|
throw new InternalError(e.toString(), e);
|
||||||
@ -1022,35 +945,6 @@ public class Proxy implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
|
|
||||||
ClassLoader ccl = caller.getClassLoader();
|
|
||||||
ClassLoader pcl = proxyClass.getClassLoader();
|
|
||||||
|
|
||||||
// do permission check if the caller is in a different runtime package
|
|
||||||
// of the proxy class
|
|
||||||
String pkg = proxyClass.getPackageName();
|
|
||||||
String callerPkg = caller.getPackageName();
|
|
||||||
|
|
||||||
if (pcl != ccl || !pkg.equals(callerPkg)) {
|
|
||||||
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the class loader for the given module.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static ClassLoader getLoader(Module m) {
|
|
||||||
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
|
|
||||||
return AccessController.doPrivileged(pa);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given class is a proxy class.
|
* Returns true if the given class is a proxy class.
|
||||||
*
|
*
|
||||||
@ -1075,8 +969,6 @@ public class Proxy implements java.io.Serializable {
|
|||||||
* @throws IllegalArgumentException if the argument is not a
|
* @throws IllegalArgumentException if the argument is not a
|
||||||
* proxy instance
|
* proxy instance
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@CallerSensitive
|
|
||||||
public static InvocationHandler getInvocationHandler(Object proxy)
|
public static InvocationHandler getInvocationHandler(Object proxy)
|
||||||
throws IllegalArgumentException
|
throws IllegalArgumentException
|
||||||
{
|
{
|
||||||
@ -1089,16 +981,6 @@ public class Proxy implements java.io.Serializable {
|
|||||||
|
|
||||||
final Proxy p = (Proxy) proxy;
|
final Proxy p = (Proxy) proxy;
|
||||||
final InvocationHandler ih = p.h;
|
final InvocationHandler ih = p.h;
|
||||||
if (System.getSecurityManager() != null) {
|
|
||||||
Class<?> ihClass = ih.getClass();
|
|
||||||
Class<?> caller = Reflection.getCallerClass();
|
|
||||||
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
|
|
||||||
ihClass.getClassLoader()))
|
|
||||||
{
|
|
||||||
ReflectUtil.checkPackageAccess(ihClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ih;
|
return ih;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1249,20 +1131,14 @@ public class Proxy implements java.io.Serializable {
|
|||||||
*
|
*
|
||||||
* @return a lookup for proxy class of this proxy instance
|
* @return a lookup for proxy class of this proxy instance
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static MethodHandles.Lookup proxyClassLookup(MethodHandles.Lookup caller, Class<?> proxyClass) {
|
private static MethodHandles.Lookup proxyClassLookup(MethodHandles.Lookup caller, Class<?> proxyClass) {
|
||||||
return AccessController.doPrivileged(new PrivilegedAction<>() {
|
try {
|
||||||
@Override
|
Method m = proxyClass.getDeclaredMethod("proxyClassLookup", MethodHandles.Lookup.class);
|
||||||
public MethodHandles.Lookup run() {
|
m.setAccessible(true);
|
||||||
try {
|
return (MethodHandles.Lookup) m.invoke(null, caller);
|
||||||
Method m = proxyClass.getDeclaredMethod("proxyClassLookup", MethodHandles.Lookup.class);
|
} catch (ReflectiveOperationException e) {
|
||||||
m.setAccessible(true);
|
throw new InternalError(e);
|
||||||
return (MethodHandles.Lookup) m.invoke(null, caller);
|
}
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
throw new InternalError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,7 +43,6 @@ import java.util.Objects;
|
|||||||
import jdk.internal.constant.ClassOrInterfaceDescImpl;
|
import jdk.internal.constant.ClassOrInterfaceDescImpl;
|
||||||
import jdk.internal.constant.ConstantUtils;
|
import jdk.internal.constant.ConstantUtils;
|
||||||
import jdk.internal.constant.MethodTypeDescImpl;
|
import jdk.internal.constant.MethodTypeDescImpl;
|
||||||
import sun.security.action.GetBooleanAction;
|
|
||||||
|
|
||||||
import static java.lang.classfile.ClassFile.*;
|
import static java.lang.classfile.ClassFile.*;
|
||||||
import java.lang.classfile.attribute.StackMapFrameInfo;
|
import java.lang.classfile.attribute.StackMapFrameInfo;
|
||||||
@ -106,9 +105,8 @@ final class ProxyGenerator {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
private static final boolean SAVE_GENERATED_FILES =
|
private static final boolean SAVE_GENERATED_FILES =
|
||||||
java.security.AccessController.doPrivileged(
|
Boolean.getBoolean("jdk.proxy.ProxyGenerator.saveGeneratedFiles");
|
||||||
new GetBooleanAction(
|
|
||||||
"jdk.proxy.ProxyGenerator.saveGeneratedFiles"));
|
|
||||||
|
|
||||||
/* Preloaded ProxyMethod objects for methods in java.lang.Object */
|
/* Preloaded ProxyMethod objects for methods in java.lang.Object */
|
||||||
private static final Method OBJECT_HASH_CODE_METHOD;
|
private static final Method OBJECT_HASH_CODE_METHOD;
|
||||||
@ -215,27 +213,21 @@ final class ProxyGenerator {
|
|||||||
final byte[] classFile = gen.generateClassFile();
|
final byte[] classFile = gen.generateClassFile();
|
||||||
|
|
||||||
if (SAVE_GENERATED_FILES) {
|
if (SAVE_GENERATED_FILES) {
|
||||||
java.security.AccessController.doPrivileged(
|
try {
|
||||||
new java.security.PrivilegedAction<Void>() {
|
int i = name.lastIndexOf('.');
|
||||||
public Void run() {
|
Path path;
|
||||||
try {
|
if (i > 0) {
|
||||||
int i = name.lastIndexOf('.');
|
Path dir = Path.of(name.substring(0, i).replace('.', '/'));
|
||||||
Path path;
|
Files.createDirectories(dir);
|
||||||
if (i > 0) {
|
path = dir.resolve(name.substring(i + 1) + ".class");
|
||||||
Path dir = Path.of(name.substring(0, i).replace('.', '/'));
|
} else {
|
||||||
Files.createDirectories(dir);
|
path = Path.of(name + ".class");
|
||||||
path = dir.resolve(name.substring(i + 1) + ".class");
|
}
|
||||||
} else {
|
Files.write(path, classFile);
|
||||||
path = Path.of(name + ".class");
|
return null;
|
||||||
}
|
} catch (IOException e) {
|
||||||
Files.write(path, classFile);
|
throw new InternalError("I/O exception saving generated file: " + e);
|
||||||
return null;
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new InternalError(
|
|
||||||
"I/O exception saving generated file: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return classFile;
|
return classFile;
|
||||||
@ -565,11 +557,6 @@ final class ProxyGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the class initializer.
|
* Generate the class initializer.
|
||||||
* Discussion: Currently, for Proxy to work with SecurityManager,
|
|
||||||
* we rely on the parameter classes of the methods to be computed
|
|
||||||
* from Proxy instead of via user code paths like bootstrap method
|
|
||||||
* lazy evaluation. That might change if we can pass in the live
|
|
||||||
* Method objects directly..
|
|
||||||
*/
|
*/
|
||||||
private void generateStaticInitializer(ClassBuilder clb) {
|
private void generateStaticInitializer(ClassBuilder clb) {
|
||||||
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
|
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
|
||||||
@ -786,9 +773,6 @@ final class ProxyGenerator {
|
|||||||
* Generate code for initializing the static field that stores
|
* Generate code for initializing the static field that stores
|
||||||
* the Method object for this proxy method. A class loader is
|
* the Method object for this proxy method. A class loader is
|
||||||
* anticipated at local variable index 0.
|
* anticipated at local variable index 0.
|
||||||
* The generated code must be run in an AccessController.doPrivileged
|
|
||||||
* block if a SecurityManager is present, as otherwise the code
|
|
||||||
* cannot pass {@code null} ClassLoader to forName.
|
|
||||||
*/
|
*/
|
||||||
private void codeFieldInitialization(CodeBuilder cob) {
|
private void codeFieldInitialization(CodeBuilder cob) {
|
||||||
var cp = cob.constantPool();
|
var cp = cob.constantPool();
|
||||||
|
@ -35,11 +35,6 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.security.AccessControlContext;
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.security.PrivilegedActionException;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -396,10 +391,6 @@ public final class ServiceLoader<S>
|
|||||||
// null when locating provider using a module layer
|
// null when locating provider using a module layer
|
||||||
private final ClassLoader loader;
|
private final ClassLoader loader;
|
||||||
|
|
||||||
// The access control context taken when the ServiceLoader is created
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private final AccessControlContext acc;
|
|
||||||
|
|
||||||
// The lazy-lookup iterator for iterator operations
|
// The lazy-lookup iterator for iterator operations
|
||||||
private Iterator<Provider<S>> lookupIterator1;
|
private Iterator<Provider<S>> lookupIterator1;
|
||||||
private final List<S> instantiatedProviders = new ArrayList<>();
|
private final List<S> instantiatedProviders = new ArrayList<>();
|
||||||
@ -462,7 +453,6 @@ public final class ServiceLoader<S>
|
|||||||
* If {@code svc} is not accessible to {@code caller} or the caller
|
* If {@code svc} is not accessible to {@code caller} or the caller
|
||||||
* module does not use the service type.
|
* module does not use the service type.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) {
|
private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) {
|
||||||
Objects.requireNonNull(caller);
|
Objects.requireNonNull(caller);
|
||||||
Objects.requireNonNull(layer);
|
Objects.requireNonNull(layer);
|
||||||
@ -473,9 +463,6 @@ public final class ServiceLoader<S>
|
|||||||
this.serviceName = svc.getName();
|
this.serviceName = svc.getName();
|
||||||
this.layer = layer;
|
this.layer = layer;
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
this.acc = (System.getSecurityManager() != null)
|
|
||||||
? AccessController.getContext()
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -486,7 +473,6 @@ public final class ServiceLoader<S>
|
|||||||
* If {@code svc} is not accessible to {@code caller} or the caller
|
* If {@code svc} is not accessible to {@code caller} or the caller
|
||||||
* module does not use the service type.
|
* module does not use the service type.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
|
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
|
||||||
Objects.requireNonNull(svc);
|
Objects.requireNonNull(svc);
|
||||||
|
|
||||||
@ -515,9 +501,6 @@ public final class ServiceLoader<S>
|
|||||||
this.serviceName = svc.getName();
|
this.serviceName = svc.getName();
|
||||||
this.layer = null;
|
this.layer = null;
|
||||||
this.loader = cl;
|
this.loader = cl;
|
||||||
this.acc = (System.getSecurityManager() != null)
|
|
||||||
? AccessController.getContext()
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -529,7 +512,6 @@ public final class ServiceLoader<S>
|
|||||||
* @throws ServiceConfigurationError
|
* @throws ServiceConfigurationError
|
||||||
* If the caller module does not use the service type.
|
* If the caller module does not use the service type.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) {
|
private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) {
|
||||||
if (!callerModule.canUse(svc)) {
|
if (!callerModule.canUse(svc)) {
|
||||||
fail(svc, callerModule + " does not declare `uses`");
|
fail(svc, callerModule + " does not declare `uses`");
|
||||||
@ -539,9 +521,6 @@ public final class ServiceLoader<S>
|
|||||||
this.serviceName = svc.getName();
|
this.serviceName = svc.getName();
|
||||||
this.layer = null;
|
this.layer = null;
|
||||||
this.loader = cl;
|
this.loader = cl;
|
||||||
this.acc = (System.getSecurityManager() != null)
|
|
||||||
? AccessController.getContext()
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -601,7 +580,6 @@ public final class ServiceLoader<S>
|
|||||||
* provider method or there is more than one public static
|
* provider method or there is more than one public static
|
||||||
* provider method
|
* provider method
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private Method findStaticProviderMethod(Class<?> clazz) {
|
private Method findStaticProviderMethod(Class<?> clazz) {
|
||||||
List<Method> methods = null;
|
List<Method> methods = null;
|
||||||
try {
|
try {
|
||||||
@ -628,12 +606,7 @@ public final class ServiceLoader<S>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
Method m = result;
|
result.setAccessible(true);
|
||||||
PrivilegedAction<Void> pa = () -> {
|
|
||||||
m.setAccessible(true);
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
AccessController.doPrivileged(pa);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -644,27 +617,16 @@ public final class ServiceLoader<S>
|
|||||||
* @throws ServiceConfigurationError if the class does not have
|
* @throws ServiceConfigurationError if the class does not have
|
||||||
* public no-arg constructor
|
* public no-arg constructor
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private Constructor<?> getConstructor(Class<?> clazz) {
|
private Constructor<?> getConstructor(Class<?> clazz) {
|
||||||
PrivilegedExceptionAction<Constructor<?>> pa
|
|
||||||
= new PrivilegedExceptionAction<>() {
|
|
||||||
@Override
|
|
||||||
public Constructor<?> run() throws Exception {
|
|
||||||
Constructor<?> ctor = clazz.getConstructor();
|
|
||||||
if (inExplicitModule(clazz))
|
|
||||||
ctor.setAccessible(true);
|
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Constructor<?> ctor = null;
|
Constructor<?> ctor = null;
|
||||||
try {
|
try {
|
||||||
ctor = AccessController.doPrivileged(pa);
|
ctor = clazz.getConstructor();
|
||||||
} catch (Throwable x) {
|
} catch (NoSuchMethodException ex) {
|
||||||
if (x instanceof PrivilegedActionException)
|
|
||||||
x = x.getCause();
|
|
||||||
String cn = clazz.getName();
|
String cn = clazz.getName();
|
||||||
fail(service, cn + " Unable to get public no-arg constructor", x);
|
fail(service, cn + " Unable to get public no-arg constructor", ex);
|
||||||
}
|
}
|
||||||
|
if (inExplicitModule(clazz))
|
||||||
|
ctor.setAccessible(true);
|
||||||
return ctor;
|
return ctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,29 +640,23 @@ public final class ServiceLoader<S>
|
|||||||
final Class<? extends S> type;
|
final Class<? extends S> type;
|
||||||
final Method factoryMethod; // factory method or null
|
final Method factoryMethod; // factory method or null
|
||||||
final Constructor<? extends S> ctor; // public no-args constructor or null
|
final Constructor<? extends S> ctor; // public no-args constructor or null
|
||||||
@SuppressWarnings("removal")
|
|
||||||
final AccessControlContext acc;
|
|
||||||
|
|
||||||
ProviderImpl(Class<S> service,
|
ProviderImpl(Class<S> service,
|
||||||
Class<? extends S> type,
|
Class<? extends S> type,
|
||||||
Method factoryMethod,
|
Method factoryMethod) {
|
||||||
@SuppressWarnings("removal") AccessControlContext acc) {
|
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.factoryMethod = factoryMethod;
|
this.factoryMethod = factoryMethod;
|
||||||
this.ctor = null;
|
this.ctor = null;
|
||||||
this.acc = acc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProviderImpl(Class<S> service,
|
ProviderImpl(Class<S> service,
|
||||||
Class<? extends S> type,
|
Class<? extends S> type,
|
||||||
Constructor<? extends S> ctor,
|
Constructor<? extends S> ctor) {
|
||||||
@SuppressWarnings("removal") AccessControlContext acc) {
|
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.factoryMethod = null;
|
this.factoryMethod = null;
|
||||||
this.ctor = ctor;
|
this.ctor = ctor;
|
||||||
this.acc = acc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -723,36 +679,14 @@ public final class ServiceLoader<S>
|
|||||||
* permissions that are restricted by the security context of whatever
|
* permissions that are restricted by the security context of whatever
|
||||||
* created this loader.
|
* created this loader.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private S invokeFactoryMethod() {
|
private S invokeFactoryMethod() {
|
||||||
Object result = null;
|
Object result = null;
|
||||||
Throwable exc = null;
|
try {
|
||||||
if (acc == null) {
|
result = factoryMethod.invoke(null);
|
||||||
try {
|
} catch (Throwable ex) {
|
||||||
result = factoryMethod.invoke(null);
|
if (ex instanceof InvocationTargetException)
|
||||||
} catch (Throwable x) {
|
ex = ex.getCause();
|
||||||
exc = x;
|
fail(service, factoryMethod + " failed", ex);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrivilegedExceptionAction<?> pa = new PrivilegedExceptionAction<>() {
|
|
||||||
@Override
|
|
||||||
public Object run() throws Exception {
|
|
||||||
return factoryMethod.invoke(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// invoke factory method with permissions restricted by acc
|
|
||||||
try {
|
|
||||||
result = AccessController.doPrivileged(pa, acc);
|
|
||||||
} catch (Throwable x) {
|
|
||||||
if (x instanceof PrivilegedActionException)
|
|
||||||
x = x.getCause();
|
|
||||||
exc = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exc != null) {
|
|
||||||
if (exc instanceof InvocationTargetException)
|
|
||||||
exc = exc.getCause();
|
|
||||||
fail(service, factoryMethod + " failed", exc);
|
|
||||||
}
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
fail(service, factoryMethod + " returned null");
|
fail(service, factoryMethod + " returned null");
|
||||||
@ -767,38 +701,16 @@ public final class ServiceLoader<S>
|
|||||||
* with a security manager then the constructor runs with permissions that
|
* with a security manager then the constructor runs with permissions that
|
||||||
* are restricted by the security context of whatever created this loader.
|
* are restricted by the security context of whatever created this loader.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private S newInstance() {
|
private S newInstance() {
|
||||||
S p = null;
|
S p = null;
|
||||||
Throwable exc = null;
|
try {
|
||||||
if (acc == null) {
|
p = ctor.newInstance();
|
||||||
try {
|
} catch (Throwable ex) {
|
||||||
p = ctor.newInstance();
|
if (ex instanceof InvocationTargetException)
|
||||||
} catch (Throwable x) {
|
ex = ex.getCause();
|
||||||
exc = x;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrivilegedExceptionAction<S> pa = new PrivilegedExceptionAction<>() {
|
|
||||||
@Override
|
|
||||||
public S run() throws Exception {
|
|
||||||
return ctor.newInstance();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// invoke constructor with permissions restricted by acc
|
|
||||||
try {
|
|
||||||
p = AccessController.doPrivileged(pa, acc);
|
|
||||||
} catch (Throwable x) {
|
|
||||||
if (x instanceof PrivilegedActionException)
|
|
||||||
x = x.getCause();
|
|
||||||
exc = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exc != null) {
|
|
||||||
if (exc instanceof InvocationTargetException)
|
|
||||||
exc = exc.getCause();
|
|
||||||
String cn = ctor.getDeclaringClass().getName();
|
String cn = ctor.getDeclaringClass().getName();
|
||||||
fail(service,
|
fail(service,
|
||||||
"Provider " + cn + " could not be instantiated", exc);
|
"Provider " + cn + " could not be instantiated", ex);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -809,15 +721,14 @@ public final class ServiceLoader<S>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(service, type, acc);
|
return Objects.hash(service, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object ob) {
|
public boolean equals(Object ob) {
|
||||||
return ob instanceof @SuppressWarnings("unchecked")ProviderImpl<?> that
|
return ob instanceof @SuppressWarnings("unchecked")ProviderImpl<?> that
|
||||||
&& this.service == that.service
|
&& this.service == that.service
|
||||||
&& this.type == that.type
|
&& this.type == that.type;
|
||||||
&& Objects.equals(this.acc, that.acc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,7 +742,6 @@ public final class ServiceLoader<S>
|
|||||||
* isn't the expected sub-type (or doesn't define a provider
|
* isn't the expected sub-type (or doesn't define a provider
|
||||||
* factory method that returns the expected type)
|
* factory method that returns the expected type)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private Provider<S> loadProvider(ServiceProvider provider) {
|
private Provider<S> loadProvider(ServiceProvider provider) {
|
||||||
Module module = provider.module();
|
Module module = provider.module();
|
||||||
if (!module.canRead(service.getModule())) {
|
if (!module.canRead(service.getModule())) {
|
||||||
@ -841,22 +751,10 @@ public final class ServiceLoader<S>
|
|||||||
|
|
||||||
String cn = provider.providerName();
|
String cn = provider.providerName();
|
||||||
Class<?> clazz = null;
|
Class<?> clazz = null;
|
||||||
if (acc == null) {
|
try {
|
||||||
try {
|
clazz = Class.forName(module, cn);
|
||||||
clazz = Class.forName(module, cn);
|
} catch (LinkageError e) {
|
||||||
} catch (LinkageError e) {
|
fail(service, "Unable to load " + cn, e);
|
||||||
fail(service, "Unable to load " + cn, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrivilegedExceptionAction<Class<?>> pa = () -> Class.forName(module, cn);
|
|
||||||
try {
|
|
||||||
clazz = AccessController.doPrivileged(pa);
|
|
||||||
} catch (Throwable x) {
|
|
||||||
if (x instanceof PrivilegedActionException)
|
|
||||||
x = x.getCause();
|
|
||||||
fail(service, "Unable to load " + cn, x);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
fail(service, "Provider " + cn + " not found");
|
fail(service, "Provider " + cn + " not found");
|
||||||
@ -878,7 +776,7 @@ public final class ServiceLoader<S>
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends S> type = (Class<? extends S>) returnType;
|
Class<? extends S> type = (Class<? extends S>) returnType;
|
||||||
return new ProviderImpl<S>(service, type, factoryMethod, acc);
|
return new ProviderImpl<S>(service, type, factoryMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -891,7 +789,7 @@ public final class ServiceLoader<S>
|
|||||||
Class<? extends S> type = (Class<? extends S>) clazz;
|
Class<? extends S> type = (Class<? extends S>) clazz;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Constructor<? extends S> ctor = (Constructor<? extends S> ) getConstructor(clazz);
|
Constructor<? extends S> ctor = (Constructor<? extends S> ) getConstructor(clazz);
|
||||||
return new ProviderImpl<S>(service, type, ctor, acc);
|
return new ProviderImpl<S>(service, type, ctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -997,20 +895,6 @@ public final class ServiceLoader<S>
|
|||||||
return catalog.findServices(serviceName);
|
return catalog.findServices(serviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the class loader that a module is defined to
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ClassLoader loaderFor(Module module) {
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm == null) {
|
|
||||||
return module.getClassLoader();
|
|
||||||
} else {
|
|
||||||
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
|
|
||||||
return AccessController.doPrivileged(pa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an iterator to iterate over the implementations of {@code
|
* Returns an iterator to iterate over the implementations of {@code
|
||||||
* service} in modules defined to the given class loader or in custom
|
* service} in modules defined to the given class loader or in custom
|
||||||
@ -1041,7 +925,7 @@ public final class ServiceLoader<S>
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
ModuleLayer layer = iterator.next();
|
ModuleLayer layer = iterator.next();
|
||||||
for (ServiceProvider sp : providers(layer)) {
|
for (ServiceProvider sp : providers(layer)) {
|
||||||
ClassLoader l = loaderFor(sp.module());
|
ClassLoader l = sp.module().getClassLoader();
|
||||||
if (l != null && l != platformClassLoader) {
|
if (l != null && l != platformClassLoader) {
|
||||||
allProviders.add(sp);
|
allProviders.add(sp);
|
||||||
}
|
}
|
||||||
@ -1225,7 +1109,7 @@ public final class ServiceLoader<S>
|
|||||||
Class<? extends S> type = (Class<? extends S>) clazz;
|
Class<? extends S> type = (Class<? extends S>) clazz;
|
||||||
Constructor<? extends S> ctor
|
Constructor<? extends S> ctor
|
||||||
= (Constructor<? extends S>)getConstructor(clazz);
|
= (Constructor<? extends S>)getConstructor(clazz);
|
||||||
ProviderImpl<S> p = new ProviderImpl<S>(service, type, ctor, acc);
|
ProviderImpl<S> p = new ProviderImpl<S>(service, type, ctor);
|
||||||
nextProvider = (ProviderImpl<T>) p;
|
nextProvider = (ProviderImpl<T>) p;
|
||||||
} else {
|
} else {
|
||||||
fail(service, clazz.getName() + " not a subtype");
|
fail(service, clazz.getName() + " not a subtype");
|
||||||
@ -1253,30 +1137,14 @@ public final class ServiceLoader<S>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
if (acc == null) {
|
return hasNextService();
|
||||||
return hasNextService();
|
|
||||||
} else {
|
|
||||||
PrivilegedAction<Boolean> action = new PrivilegedAction<>() {
|
|
||||||
public Boolean run() { return hasNextService(); }
|
|
||||||
};
|
|
||||||
return AccessController.doPrivileged(action, acc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@Override
|
@Override
|
||||||
public Provider<T> next() {
|
public Provider<T> next() {
|
||||||
if (acc == null) {
|
return nextService();
|
||||||
return nextService();
|
|
||||||
} else {
|
|
||||||
PrivilegedAction<Provider<T>> action = new PrivilegedAction<>() {
|
|
||||||
public Provider<T> run() { return nextService(); }
|
|
||||||
};
|
|
||||||
return AccessController.doPrivileged(action, acc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +32,6 @@ import java.lang.constant.ConstantDescs;
|
|||||||
import java.lang.constant.MethodTypeDesc;
|
import java.lang.constant.MethodTypeDesc;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -320,15 +318,8 @@ public final class MethodTypeDescImpl implements MethodTypeDesc {
|
|||||||
public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
|
public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
|
||||||
MethodType mtype;
|
MethodType mtype;
|
||||||
try {
|
try {
|
||||||
@SuppressWarnings("removal")
|
mtype = MethodType.fromMethodDescriptorString(descriptorString(),
|
||||||
MethodType mt = AccessController.doPrivileged(new PrivilegedAction<>() {
|
lookup.lookupClass().getClassLoader());
|
||||||
@Override
|
|
||||||
public MethodType run() {
|
|
||||||
return MethodType.fromMethodDescriptorString(descriptorString(),
|
|
||||||
lookup.lookupClass().getClassLoader());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mtype = mt;
|
|
||||||
} catch (TypeNotPresentException ex) {
|
} catch (TypeNotPresentException ex) {
|
||||||
throw (ClassNotFoundException) ex.getCause();
|
throw (ClassNotFoundException) ex.getCause();
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,10 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.Properties;
|
|
||||||
import jdk.internal.access.JavaLangReflectAccess;
|
import jdk.internal.access.JavaLangReflectAccess;
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.vm.annotation.Stable;
|
import jdk.internal.vm.annotation.Stable;
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
/** <P> The master factory for all reflective objects, both those in
|
/** <P> The master factory for all reflective objects, both those in
|
||||||
java.lang.reflect (Fields, Methods, Constructors) as well as their
|
java.lang.reflect (Fields, Methods, Constructors) as well as their
|
||||||
@ -93,27 +90,12 @@ public class ReflectionFactory {
|
|||||||
* Provides the caller with the capability to instantiate reflective
|
* Provides the caller with the capability to instantiate reflective
|
||||||
* objects.
|
* objects.
|
||||||
*
|
*
|
||||||
* <p> First, if there is a security manager, its
|
|
||||||
* <code>checkPermission</code> method is called with a {@link
|
|
||||||
* java.lang.RuntimePermission} with target
|
|
||||||
* <code>"reflectionFactoryAccess"</code>. This may result in a
|
|
||||||
* security exception.
|
|
||||||
*
|
|
||||||
* <p> The returned <code>ReflectionFactory</code> object should be
|
* <p> The returned <code>ReflectionFactory</code> object should be
|
||||||
* carefully guarded by the caller, since it can be used to read and
|
* carefully guarded by the caller, since it can be used to read and
|
||||||
* write private data and invoke private methods, as well as to load
|
* write private data and invoke private methods, as well as to load
|
||||||
* unverified bytecodes. It must never be passed to untrusted code.
|
* unverified bytecodes. It must never be passed to untrusted code.
|
||||||
*
|
*/
|
||||||
* @exception SecurityException if a security manager exists and its
|
|
||||||
* <code>checkPermission</code> method doesn't allow
|
|
||||||
* access to the RuntimePermission "reflectionFactoryAccess". */
|
|
||||||
public static ReflectionFactory getReflectionFactory() {
|
public static ReflectionFactory getReflectionFactory() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager security = System.getSecurityManager();
|
|
||||||
if (security != null) {
|
|
||||||
security.checkPermission(
|
|
||||||
SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION);
|
|
||||||
}
|
|
||||||
return soleInstance;
|
return soleInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,11 +531,10 @@ public class ReflectionFactory {
|
|||||||
private static Config loadConfig() {
|
private static Config loadConfig() {
|
||||||
assert VM.isModuleSystemInited();
|
assert VM.isModuleSystemInited();
|
||||||
|
|
||||||
Properties props = GetPropertyAction.privilegedGetProperties();
|
|
||||||
boolean useNativeAccessorOnly =
|
boolean useNativeAccessorOnly =
|
||||||
"true".equals(props.getProperty("jdk.reflect.useNativeAccessorOnly"));
|
"true".equals(System.getProperty("jdk.reflect.useNativeAccessorOnly"));
|
||||||
boolean disableSerialConstructorChecks =
|
boolean disableSerialConstructorChecks =
|
||||||
"true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
|
"true".equals(System.getProperty("jdk.disableSerialConstructorChecks"));
|
||||||
|
|
||||||
return new Config(useNativeAccessorOnly, disableSerialConstructorChecks);
|
return new Config(useNativeAccessorOnly, disableSerialConstructorChecks);
|
||||||
}
|
}
|
||||||
|
@ -311,8 +311,6 @@ public class VerifyAccess {
|
|||||||
// will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
|
// will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
|
||||||
// will record the first successful result. Unsuccessful results are not stored.
|
// will record the first successful result. Unsuccessful results are not stored.
|
||||||
//
|
//
|
||||||
// We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
|
|
||||||
// class loader about the binding of the proposed name (type.getName()).
|
|
||||||
// The looked up type ("res") is compared for equality against the proposed
|
// The looked up type ("res") is compared for equality against the proposed
|
||||||
// type ("type") and then is discarded. Thus, the worst that can happen to
|
// type ("type") and then is discarded. Thus, the worst that can happen to
|
||||||
// the "child" class loader is that it is bothered to load and report a class
|
// the "child" class loader is that it is bothered to load and report a class
|
||||||
@ -320,17 +318,12 @@ public class VerifyAccess {
|
|||||||
// memoization. And the caller never gets to look at the alternate type binding
|
// memoization. And the caller never gets to look at the alternate type binding
|
||||||
// ("res"), whether it exists or not.
|
// ("res"), whether it exists or not.
|
||||||
final String name = type.getName();
|
final String name = type.getName();
|
||||||
@SuppressWarnings("removal")
|
Class<?> res = null;
|
||||||
Class<?> res = java.security.AccessController.doPrivileged(
|
try {
|
||||||
new java.security.PrivilegedAction<>() {
|
res = Class.forName(name, false, refcLoader);
|
||||||
public Class<?> run() {
|
} catch (ClassNotFoundException | LinkageError e) {
|
||||||
try {
|
// Assume the class is not found
|
||||||
return Class.forName(name, false, refcLoader);
|
}
|
||||||
} catch (ClassNotFoundException | LinkageError e) {
|
|
||||||
return null; // Assume the class is not found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return (type == res);
|
return (type == res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,7 +23,6 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package sun.reflect.misc;
|
package sun.reflect.misc;
|
||||||
|
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
@ -31,16 +30,13 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import jdk.internal.reflect.Reflection;
|
import jdk.internal.reflect.Reflection;
|
||||||
import sun.security.util.SecurityConstants;
|
|
||||||
|
|
||||||
public final class ReflectUtil {
|
public final class ReflectUtil {
|
||||||
|
|
||||||
private ReflectUtil() {
|
private ReflectUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> forName(String name)
|
public static Class<?> forName(String name) throws ClassNotFoundException {
|
||||||
throws ClassNotFoundException {
|
|
||||||
checkPackageAccess(name);
|
|
||||||
return Class.forName(name);
|
return Class.forName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,182 +69,48 @@ public final class ReflectUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a conservative approximation of member access check. Use this if
|
* Does nothing.
|
||||||
* you don't have an actual 'userland' caller Class/ClassLoader available.
|
|
||||||
* This might be more restrictive than a precise member access check where
|
|
||||||
* you have a caller, but should never allow a member access that is
|
|
||||||
* forbidden.
|
|
||||||
*
|
|
||||||
* @param m the {@code Member} about to be accessed
|
|
||||||
*/
|
*/
|
||||||
public static void conservativeCheckMemberAccess(Member m) throws SecurityException{
|
public static void conservativeCheckMemberAccess(Member m) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
final SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check for package access on the declaring class.
|
|
||||||
//
|
|
||||||
// In addition, unless the member and the declaring class are both
|
|
||||||
// public check for access declared member permissions.
|
|
||||||
//
|
|
||||||
// This is done regardless of ClassLoader relations between the {@code
|
|
||||||
// Member m} and any potential caller.
|
|
||||||
|
|
||||||
final Class<?> declaringClass = m.getDeclaringClass();
|
|
||||||
|
|
||||||
privateCheckPackageAccess(sm, declaringClass);
|
|
||||||
|
|
||||||
if (Modifier.isPublic(m.getModifiers()) &&
|
|
||||||
Modifier.isPublic(declaringClass.getModifiers()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check for declared member access.
|
|
||||||
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks package access on the given class.
|
* Does nothing.
|
||||||
*
|
|
||||||
* If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements
|
|
||||||
* a non-public interface (i.e. may be in a non-restricted package),
|
|
||||||
* also check the package access on the proxy interfaces.
|
|
||||||
*/
|
*/
|
||||||
public static void checkPackageAccess(Class<?> clazz) {
|
public static void checkPackageAccess(Class<?> clazz) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager s = System.getSecurityManager();
|
|
||||||
if (s != null) {
|
|
||||||
privateCheckPackageAccess(s, clazz);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: should only be called if a SecurityManager is installed
|
* Does nothing
|
||||||
*/
|
|
||||||
private static void privateCheckPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
|
|
||||||
String pkg = clazz.getPackageName();
|
|
||||||
if (!pkg.isEmpty()) {
|
|
||||||
s.checkPackageAccess(pkg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNonPublicProxyClass(clazz)) {
|
|
||||||
privateCheckProxyPackageAccess(s, clazz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks package access on the given classname.
|
|
||||||
* This method is typically called when the Class instance is not
|
|
||||||
* available and the caller attempts to load a class on behalf
|
|
||||||
* the true caller (application).
|
|
||||||
*/
|
*/
|
||||||
public static void checkPackageAccess(String name) {
|
public static void checkPackageAccess(String name) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager s = System.getSecurityManager();
|
|
||||||
if (s != null) {
|
|
||||||
String cname = name.replace('/', '.');
|
|
||||||
if (cname.startsWith("[")) {
|
|
||||||
int b = cname.lastIndexOf('[') + 2;
|
|
||||||
if (b > 1 && b < cname.length()) {
|
|
||||||
cname = cname.substring(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int i = cname.lastIndexOf('.');
|
|
||||||
if (i != -1) {
|
|
||||||
s.checkPackageAccess(cname.substring(0, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true.
|
||||||
|
*/
|
||||||
public static boolean isPackageAccessible(Class<?> clazz) {
|
public static boolean isPackageAccessible(Class<?> clazz) {
|
||||||
try {
|
|
||||||
checkPackageAccess(clazz);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if p is an ancestor of cl i.e. class loader 'p' can
|
/**
|
||||||
// be found in the cl's delegation chain
|
* Returns false.
|
||||||
private static boolean isAncestor(ClassLoader p, ClassLoader cl) {
|
*/
|
||||||
ClassLoader acl = cl;
|
public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) {
|
||||||
do {
|
|
||||||
acl = acl.getParent();
|
|
||||||
if (p == acl) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} while (acl != null);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if package access check is needed for reflective
|
* Does nothing
|
||||||
* access from a class loader 'from' to classes or members in
|
|
||||||
* a class defined by class loader 'to'. This method returns true
|
|
||||||
* if 'from' is not the same as or an ancestor of 'to'. All code
|
|
||||||
* in a system domain are granted with all permission and so this
|
|
||||||
* method returns false if 'from' class loader is a class loader
|
|
||||||
* loading system classes. On the other hand, if a class loader
|
|
||||||
* attempts to access system domain classes, it requires package
|
|
||||||
* access check and this method will return true.
|
|
||||||
*/
|
|
||||||
public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) {
|
|
||||||
if (from == null || from == to)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (to == null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return !isAncestor(from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check package access on the proxy interfaces that the given proxy class
|
|
||||||
* implements.
|
|
||||||
*
|
|
||||||
* @param clazz Proxy class object
|
|
||||||
*/
|
*/
|
||||||
public static void checkProxyPackageAccess(Class<?> clazz) {
|
public static void checkProxyPackageAccess(Class<?> clazz) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager s = System.getSecurityManager();
|
|
||||||
if (s != null) {
|
|
||||||
privateCheckProxyPackageAccess(s, clazz);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: should only be called if a SecurityManager is installed
|
* Does nothing.
|
||||||
*/
|
|
||||||
private static void privateCheckProxyPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
|
|
||||||
// check proxy interfaces if the given class is a proxy class
|
|
||||||
if (Proxy.isProxyClass(clazz)) {
|
|
||||||
for (Class<?> intf : clazz.getInterfaces()) {
|
|
||||||
privateCheckPackageAccess(s, intf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Access check on the interfaces that a proxy class implements and throw
|
|
||||||
* {@code SecurityException} if it accesses a restricted package from
|
|
||||||
* the caller's class loader.
|
|
||||||
*
|
|
||||||
* @param ccl the caller's class loader
|
|
||||||
* @param interfaces the list of interfaces that a proxy class implements
|
|
||||||
*/
|
*/
|
||||||
public static void checkProxyPackageAccess(ClassLoader ccl,
|
public static void checkProxyPackageAccess(ClassLoader ccl,
|
||||||
Class<?>... interfaces)
|
Class<?>... interfaces) {
|
||||||
{
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
for (Class<?> intf : interfaces) {
|
|
||||||
ClassLoader cl = intf.getClassLoader();
|
|
||||||
if (needsPackageAccessCheck(ccl, cl)) {
|
|
||||||
privateCheckPackageAccess(sm, intf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that bytecode instrumentation tools may exclude 'sun.*'
|
// Note that bytecode instrumentation tools may exclude 'sun.*'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -53,7 +53,7 @@ public class StaticArchiveWithLambda {
|
|||||||
"-Xlog:class+load,cds")
|
"-Xlog:class+load,cds")
|
||||||
.setArchiveName(archiveName);
|
.setArchiveName(archiveName);
|
||||||
CDSTestUtils.createArchiveAndCheck(opts)
|
CDSTestUtils.createArchiveAndCheck(opts)
|
||||||
.shouldContain("Skipping java/lang/invoke/BoundMethodHandle$Species_LLLL because it is dynamically generated");
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
// run with archive
|
// run with archive
|
||||||
CDSOptions runOpts = (new CDSOptions())
|
CDSOptions runOpts = (new CDSOptions())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user