8344319: SM cleanup in jdk.dynalink module
Reviewed-by: attila
This commit is contained in:
parent
15ae8d02ee
commit
593a5898f9
@ -27,14 +27,10 @@ package jdk.dynalink;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
|
||||
import static jdk.dynalink.internal.InternalTypeUtilities.canReferenceDirectly;
|
||||
|
||||
@ -201,21 +197,14 @@ final class BiClassValue<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext GET_CLASS_LOADER_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext("getClassLoader");
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static RetentionDirection getRetentionDirection(Class<?> from, Class<?> to) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<RetentionDirection>) () -> {
|
||||
final ClassLoader cl1 = from.getClassLoader();
|
||||
final ClassLoader cl2 = to.getClassLoader();
|
||||
if (canReferenceDirectly(cl1, cl2)) {
|
||||
return RetentionDirection.FORWARD;
|
||||
} else if (canReferenceDirectly(cl2, cl1)) {
|
||||
return RetentionDirection.REVERSE;
|
||||
}
|
||||
return RetentionDirection.NEITHER;
|
||||
}, GET_CLASS_LOADER_CONTEXT);
|
||||
final ClassLoader cl1 = from.getClassLoader();
|
||||
final ClassLoader cl2 = to.getClassLoader();
|
||||
if (canReferenceDirectly(cl1, cl2)) {
|
||||
return RetentionDirection.FORWARD;
|
||||
} else if (canReferenceDirectly(cl2, cl1)) {
|
||||
return RetentionDirection.REVERSE;
|
||||
}
|
||||
return RetentionDirection.NEITHER;
|
||||
}
|
||||
}
|
||||
|
@ -63,9 +63,6 @@ package jdk.dynalink;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.MutableCallSite;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -79,7 +76,6 @@ import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import jdk.dynalink.beans.BeansLinker;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
import jdk.dynalink.linker.GuardedInvocation;
|
||||
import jdk.dynalink.linker.GuardedInvocationTransformer;
|
||||
import jdk.dynalink.linker.GuardingDynamicLinker;
|
||||
@ -108,10 +104,6 @@ import jdk.dynalink.linker.support.TypeUtilities;
|
||||
* @since 9
|
||||
*/
|
||||
public final class DynamicLinkerFactory {
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext GET_CLASS_LOADER_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext("getClassLoader");
|
||||
|
||||
/**
|
||||
* Default value for {@link #setUnstableRelinkThreshold(int) unstable relink
|
||||
* threshold}.
|
||||
@ -430,17 +422,14 @@ public final class DynamicLinkerFactory {
|
||||
|
||||
private List<GuardingDynamicLinker> discoverAutoLoadLinkers() {
|
||||
autoLoadingErrors = new LinkedList<>();
|
||||
final ClassLoader effectiveClassLoader = classLoaderExplicitlySet ? classLoader : getThreadContextClassLoader();
|
||||
final ClassLoader effectiveClassLoader =
|
||||
classLoaderExplicitlySet ? classLoader : Thread.currentThread().getContextClassLoader();
|
||||
final List<GuardingDynamicLinker> discovered = new LinkedList<>();
|
||||
try {
|
||||
@SuppressWarnings("removal")
|
||||
final ServiceLoader<GuardingDynamicLinkerExporter> linkerLoader =
|
||||
AccessController.doPrivileged((PrivilegedAction<ServiceLoader<GuardingDynamicLinkerExporter>>)()-> {
|
||||
if (effectiveClassLoader == null) {
|
||||
return ServiceLoader.loadInstalled(GuardingDynamicLinkerExporter.class);
|
||||
}
|
||||
return ServiceLoader.load(GuardingDynamicLinkerExporter.class, effectiveClassLoader);
|
||||
});
|
||||
(effectiveClassLoader == null)
|
||||
? ServiceLoader.loadInstalled(GuardingDynamicLinkerExporter.class)
|
||||
: ServiceLoader.load(GuardingDynamicLinkerExporter.class, effectiveClassLoader);
|
||||
|
||||
for(final Iterator<GuardingDynamicLinkerExporter> it = linkerLoader.iterator(); it.hasNext();) {
|
||||
try {
|
||||
@ -470,13 +459,6 @@ public final class DynamicLinkerFactory {
|
||||
return discovered;
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static ClassLoader getThreadContextClassLoader() {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader(),
|
||||
GET_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
|
||||
private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
|
||||
final List<? extends GuardingDynamicLinker> linkers) {
|
||||
for(final GuardingDynamicLinker linker: linkers) {
|
||||
|
@ -45,8 +45,6 @@ public class SecureLookupSupplier {
|
||||
*/
|
||||
public static final String GET_LOOKUP_PERMISSION_NAME = "dynalink.getLookup";
|
||||
|
||||
private static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private final MethodHandles.Lookup lookup;
|
||||
|
||||
/**
|
||||
@ -63,11 +61,6 @@ public class SecureLookupSupplier {
|
||||
* @return the lookup secured by this {@code SecureLookupSupplier}.
|
||||
*/
|
||||
public final Lookup getLookup() {
|
||||
@SuppressWarnings("removal")
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && lookup != MethodHandles.publicLookup()) {
|
||||
sm.checkPermission(GET_LOOKUP_PERMISSION);
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -63,8 +63,6 @@ package jdk.dynalink.beans;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -86,20 +84,12 @@ class BeanIntrospector extends FacetIntrospector {
|
||||
|
||||
@Override Collection<Method> getRecordComponentGetters() {
|
||||
if (clazz.isRecord()) {
|
||||
try {
|
||||
// Need to use doPrivileged as getRecordComponents is rather strict.
|
||||
@SuppressWarnings("removal")
|
||||
final RecordComponent[] rcs = AccessController.doPrivileged(
|
||||
(PrivilegedAction<RecordComponent[]>) clazz::getRecordComponents);
|
||||
return Arrays.stream(rcs)
|
||||
.map(RecordComponent::getAccessor)
|
||||
.map(membersLookup::getAccessibleMethod)
|
||||
.filter(Objects::nonNull) // no accessible counterpart
|
||||
.toList();
|
||||
} catch (SecurityException e) {
|
||||
// We couldn't execute getRecordComponents.
|
||||
return List.of();
|
||||
}
|
||||
final RecordComponent[] rcs = clazz.getRecordComponents();
|
||||
return Arrays.stream(rcs)
|
||||
.map(RecordComponent::getAccessor)
|
||||
.map(membersLookup::getAccessibleMethod)
|
||||
.filter(Objects::nonNull) // no accessible counterpart
|
||||
.toList();
|
||||
} else {
|
||||
return List.of();
|
||||
}
|
||||
|
@ -67,12 +67,8 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import jdk.dynalink.CallSiteDescriptor;
|
||||
import jdk.dynalink.SecureLookupSupplier;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
import jdk.dynalink.linker.support.Lookup;
|
||||
|
||||
/**
|
||||
@ -82,10 +78,6 @@ import jdk.dynalink.linker.support.Lookup;
|
||||
* every request.
|
||||
*/
|
||||
class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext GET_LOOKUP_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(
|
||||
SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private final Executable target;
|
||||
private final MethodType type;
|
||||
@ -127,10 +119,7 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
|
||||
@Override
|
||||
MethodHandle getTarget(final CallSiteDescriptor desc) {
|
||||
@SuppressWarnings("removal")
|
||||
final MethodHandles.Lookup lookup = AccessController.doPrivileged(
|
||||
(PrivilegedAction<MethodHandles.Lookup>)desc::getLookup,
|
||||
GET_LOOKUP_CONTEXT);
|
||||
final MethodHandles.Lookup lookup = desc.getLookup();
|
||||
|
||||
if(target instanceof Method) {
|
||||
final MethodHandle mh = unreflect(lookup, (Method)target);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -61,25 +61,17 @@
|
||||
package jdk.dynalink.beans;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
|
||||
/**
|
||||
* A utility class to check whether a given class is in a package with restricted access e.g. "sun.*" etc.
|
||||
*/
|
||||
class CheckRestrictedPackage {
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext NO_PERMISSIONS_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext();
|
||||
|
||||
/**
|
||||
* Returns true if the class is either not public, or it resides in a package with restricted access.
|
||||
* @param clazz the class to test
|
||||
* @return true if the class is either not public, or it resides in a package with restricted access.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
static boolean isRestrictedClass(final Class<?> clazz) {
|
||||
if(!Modifier.isPublic(clazz.getModifiers())) {
|
||||
// Non-public classes are always restricted
|
||||
@ -97,21 +89,6 @@ class CheckRestrictedPackage {
|
||||
// Classes in unexported packages of modules are always restricted
|
||||
return true;
|
||||
}
|
||||
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if(sm == null) {
|
||||
// No further restrictions if we don't have a security manager
|
||||
return false;
|
||||
}
|
||||
// Do a package access check from within an access control context with no permissions
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
sm.checkPackageAccess(pkgName);
|
||||
return null;
|
||||
}, NO_PERMISSIONS_CONTEXT);
|
||||
} catch(final SecurityException e) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -61,13 +61,10 @@
|
||||
package jdk.dynalink.beans;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
|
||||
import jdk.dynalink.internal.InternalTypeUtilities;
|
||||
import jdk.dynalink.linker.LinkerServices;
|
||||
import jdk.dynalink.linker.support.TypeUtilities;
|
||||
@ -78,10 +75,6 @@ import jdk.dynalink.linker.support.TypeUtilities;
|
||||
* JLS.
|
||||
*/
|
||||
final class ClassString {
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext GET_CLASS_LOADER_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext("getClassLoader");
|
||||
|
||||
/**
|
||||
* An anonymous inner class used solely to represent the "type" of null values for method applicability checking.
|
||||
*/
|
||||
@ -128,16 +121,13 @@ final class ClassString {
|
||||
return "ClassString[" + Arrays.toString(classes) + "]";
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
boolean isVisibleFrom(final ClassLoader classLoader) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
|
||||
for(final Class<?> clazz: classes) {
|
||||
if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
|
||||
return false;
|
||||
}
|
||||
for(final Class<?> clazz: classes) {
|
||||
if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, GET_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
List<MethodHandle> getMaximallySpecifics(final List<MethodHandle> methods, final LinkerServices linkerServices, final boolean varArg) {
|
||||
|
@ -62,9 +62,6 @@ package jdk.dynalink.beans;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
@ -73,9 +70,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import jdk.dynalink.CallSiteDescriptor;
|
||||
import jdk.dynalink.SecureLookupSupplier;
|
||||
import jdk.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
import jdk.dynalink.internal.InternalTypeUtilities;
|
||||
import jdk.dynalink.linker.LinkerServices;
|
||||
|
||||
@ -194,16 +189,8 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static final AccessControlContext GET_CALL_SITE_CLASS_LOADER_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(
|
||||
"getClassLoader", SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<ClassLoader>) () -> callSiteDescriptor.getLookup().lookupClass().getClassLoader(),
|
||||
GET_CALL_SITE_CLASS_LOADER_CONTEXT);
|
||||
return callSiteDescriptor.getLookup().lookupClass().getClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.dynalink.internal;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.Permission;
|
||||
import java.security.Permissions;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Utility class for creating permission-restricting {@link AccessControlContext}s.
|
||||
*/
|
||||
public final class AccessControlContextFactory {
|
||||
private AccessControlContextFactory () {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an access control context with no permissions.
|
||||
* @return an access control context with no permissions.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public static AccessControlContext createAccessControlContext() {
|
||||
return createAccessControlContext(new Permission[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an access control context limited to only the specified permissions.
|
||||
* @param permissions the permissions for the newly created access control context.
|
||||
* @return a new access control context limited to only the specified permissions.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public static AccessControlContext createAccessControlContext(final Permission... permissions) {
|
||||
final Permissions perms = new Permissions();
|
||||
for(final Permission permission: permissions) {
|
||||
perms.add(permission);
|
||||
}
|
||||
return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an access control context limited to only the {@link RuntimePermission}s
|
||||
* of the given names.
|
||||
* @param runtimePermissionNames the names of runtime permissions for the
|
||||
* newly created access control context.
|
||||
* @return a new access control context limited to only the runtime
|
||||
* permissions with the specified names.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public static AccessControlContext createAccessControlContext(final String... runtimePermissionNames) {
|
||||
return createAccessControlContext(makeRuntimePermissions(runtimePermissionNames));
|
||||
}
|
||||
|
||||
private static Permission[] makeRuntimePermissions(final String... runtimePermissionNames) {
|
||||
return Stream.of(runtimePermissionNames).map(RuntimePermission::new).toArray(Permission[]::new);
|
||||
}
|
||||
}
|
@ -63,9 +63,6 @@ public class InternalTypeUtilities {
|
||||
* @param referredLoader the referred class loader
|
||||
* @return true if it is safe to strongly reference the class from referred
|
||||
* in referred.
|
||||
* @throws SecurityException if the caller does not have the
|
||||
* {@code RuntimePermission("getClassLoader")} permission and the method
|
||||
* needs to traverse the parent class loader chain.
|
||||
*/
|
||||
public static boolean canReferenceDirectly(final ClassLoader referrerLoader, final ClassLoader referredLoader) {
|
||||
if(referredLoader == null) {
|
||||
|
@ -52,16 +52,9 @@ public abstract class GuardingDynamicLinkerExporter implements Supplier<List<Gua
|
||||
*/
|
||||
public static final String AUTOLOAD_PERMISSION_NAME = "dynalink.exportLinkersAutomatically";
|
||||
|
||||
private static final Permission AUTOLOAD_PERMISSION = new RuntimePermission(AUTOLOAD_PERMISSION_NAME);
|
||||
|
||||
/**
|
||||
* Creates a new linker exporter.
|
||||
*/
|
||||
protected GuardingDynamicLinkerExporter() {
|
||||
@SuppressWarnings("removal")
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(AUTOLOAD_PERMISSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,11 +115,7 @@ public interface GuardingTypeConverterFactory {
|
||||
* it will return the public lookup. A typical case where the lookup might
|
||||
* be needed is when the converter creates a Java adapter class on the fly
|
||||
* (e.g. to convert some object from the dynamic language into a Java
|
||||
* interface for interoperability). Invoking the {@link Supplier#get()}
|
||||
* method on the passed supplier will be subject to the same security checks
|
||||
* as {@link SecureLookupSupplier#getLookup()}. An implementation should avoid
|
||||
* retrieving the lookup if it is not needed so as to avoid the expense of
|
||||
* {@code AccessController.doPrivileged} call.
|
||||
* interface for interoperability).
|
||||
* @return a guarded invocation that can take an object (if it passes guard)
|
||||
* and return another object that is its representation coerced into the
|
||||
* target type. In case the factory is certain it is unable to handle a
|
||||
|
@ -215,10 +215,7 @@ public interface LinkerServices {
|
||||
* operation to the context of some caller class, consider performing it
|
||||
* within an invocation of this method and passing a full-strength lookup
|
||||
* for that class, as it will associate that lookup with the current thread
|
||||
* for the duration of the operation. Note that since you are passing a
|
||||
* {@link SecureLookupSupplier}, any invoked type converter factories will
|
||||
* still need to hold the necessary runtime permission to be able to get the
|
||||
* lookup should they need it.
|
||||
* for the duration of the operation.
|
||||
* @param <T> the type of the return value provided by the passed-in supplier.
|
||||
* @param operation the operation to execute in context of the specified lookup.
|
||||
* @param lookupSupplier secure supplier of the lookup
|
||||
|
Loading…
Reference in New Issue
Block a user