8344011: Remove usage of security manager from Class and reflective APIs

Reviewed-by: liach, yzheng, rriggs
This commit is contained in:
Alan Bateman 2024-11-14 07:39:28 +00:00
parent c977ef7b45
commit abacece826
26 changed files with 163 additions and 1251 deletions

View file

@ -35,11 +35,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
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.Supplier;
import java.util.stream.Stream;
@ -396,10 +391,6 @@ public final class ServiceLoader<S>
// null when locating provider using a module layer
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
private Iterator<Provider<S>> lookupIterator1;
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
* module does not use the service type.
*/
@SuppressWarnings("removal")
private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) {
Objects.requireNonNull(caller);
Objects.requireNonNull(layer);
@ -473,9 +463,6 @@ public final class ServiceLoader<S>
this.serviceName = svc.getName();
this.layer = layer;
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
* module does not use the service type.
*/
@SuppressWarnings("removal")
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
Objects.requireNonNull(svc);
@ -515,9 +501,6 @@ public final class ServiceLoader<S>
this.serviceName = svc.getName();
this.layer = null;
this.loader = cl;
this.acc = (System.getSecurityManager() != null)
? AccessController.getContext()
: null;
}
/**
@ -529,7 +512,6 @@ public final class ServiceLoader<S>
* @throws ServiceConfigurationError
* If the caller module does not use the service type.
*/
@SuppressWarnings("removal")
private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) {
if (!callerModule.canUse(svc)) {
fail(svc, callerModule + " does not declare `uses`");
@ -539,9 +521,6 @@ public final class ServiceLoader<S>
this.serviceName = svc.getName();
this.layer = null;
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
*/
@SuppressWarnings("removal")
private Method findStaticProviderMethod(Class<?> clazz) {
List<Method> methods = null;
try {
@ -628,12 +606,7 @@ public final class ServiceLoader<S>
}
}
if (result != null) {
Method m = result;
PrivilegedAction<Void> pa = () -> {
m.setAccessible(true);
return null;
};
AccessController.doPrivileged(pa);
result.setAccessible(true);
}
return result;
}
@ -644,27 +617,16 @@ public final class ServiceLoader<S>
* @throws ServiceConfigurationError if the class does not have
* public no-arg constructor
*/
@SuppressWarnings("removal")
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;
try {
ctor = AccessController.doPrivileged(pa);
} catch (Throwable x) {
if (x instanceof PrivilegedActionException)
x = x.getCause();
ctor = clazz.getConstructor();
} catch (NoSuchMethodException ex) {
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;
}
@ -678,29 +640,23 @@ public final class ServiceLoader<S>
final Class<? extends S> type;
final Method factoryMethod; // factory method or null
final Constructor<? extends S> ctor; // public no-args constructor or null
@SuppressWarnings("removal")
final AccessControlContext acc;
ProviderImpl(Class<S> service,
Class<? extends S> type,
Method factoryMethod,
@SuppressWarnings("removal") AccessControlContext acc) {
Method factoryMethod) {
this.service = service;
this.type = type;
this.factoryMethod = factoryMethod;
this.ctor = null;
this.acc = acc;
}
ProviderImpl(Class<S> service,
Class<? extends S> type,
Constructor<? extends S> ctor,
@SuppressWarnings("removal") AccessControlContext acc) {
Constructor<? extends S> ctor) {
this.service = service;
this.type = type;
this.factoryMethod = null;
this.ctor = ctor;
this.acc = acc;
}
@Override
@ -723,36 +679,14 @@ public final class ServiceLoader<S>
* permissions that are restricted by the security context of whatever
* created this loader.
*/
@SuppressWarnings("removal")
private S invokeFactoryMethod() {
Object result = null;
Throwable exc = null;
if (acc == null) {
try {
result = factoryMethod.invoke(null);
} catch (Throwable x) {
exc = x;
}
} 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);
try {
result = factoryMethod.invoke(null);
} catch (Throwable ex) {
if (ex instanceof InvocationTargetException)
ex = ex.getCause();
fail(service, factoryMethod + " failed", ex);
}
if (result == 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
* are restricted by the security context of whatever created this loader.
*/
@SuppressWarnings("removal")
private S newInstance() {
S p = null;
Throwable exc = null;
if (acc == null) {
try {
p = ctor.newInstance();
} catch (Throwable x) {
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();
try {
p = ctor.newInstance();
} catch (Throwable ex) {
if (ex instanceof InvocationTargetException)
ex = ex.getCause();
String cn = ctor.getDeclaringClass().getName();
fail(service,
"Provider " + cn + " could not be instantiated", exc);
"Provider " + cn + " could not be instantiated", ex);
}
return p;
}
@ -809,15 +721,14 @@ public final class ServiceLoader<S>
@Override
public int hashCode() {
return Objects.hash(service, type, acc);
return Objects.hash(service, type);
}
@Override
public boolean equals(Object ob) {
return ob instanceof @SuppressWarnings("unchecked")ProviderImpl<?> that
&& this.service == that.service
&& this.type == that.type
&& Objects.equals(this.acc, that.acc);
&& this.type == that.type;
}
}
@ -831,7 +742,6 @@ public final class ServiceLoader<S>
* isn't the expected sub-type (or doesn't define a provider
* factory method that returns the expected type)
*/
@SuppressWarnings("removal")
private Provider<S> loadProvider(ServiceProvider provider) {
Module module = provider.module();
if (!module.canRead(service.getModule())) {
@ -841,22 +751,10 @@ public final class ServiceLoader<S>
String cn = provider.providerName();
Class<?> clazz = null;
if (acc == null) {
try {
clazz = Class.forName(module, cn);
} catch (LinkageError 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;
}
try {
clazz = Class.forName(module, cn);
} catch (LinkageError e) {
fail(service, "Unable to load " + cn, e);
}
if (clazz == null) {
fail(service, "Provider " + cn + " not found");
@ -878,7 +776,7 @@ public final class ServiceLoader<S>
@SuppressWarnings("unchecked")
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;
@SuppressWarnings("unchecked")
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);
}
/**
* 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
* service} in modules defined to the given class loader or in custom
@ -1041,7 +925,7 @@ public final class ServiceLoader<S>
while (iterator.hasNext()) {
ModuleLayer layer = iterator.next();
for (ServiceProvider sp : providers(layer)) {
ClassLoader l = loaderFor(sp.module());
ClassLoader l = sp.module().getClassLoader();
if (l != null && l != platformClassLoader) {
allProviders.add(sp);
}
@ -1225,7 +1109,7 @@ public final class ServiceLoader<S>
Class<? extends S> type = (Class<? extends S>) clazz;
Constructor<? extends S> ctor
= (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;
} else {
fail(service, clazz.getName() + " not a subtype");
@ -1253,30 +1137,14 @@ public final class ServiceLoader<S>
}
}
@SuppressWarnings("removal")
@Override
public boolean hasNext() {
if (acc == null) {
return hasNextService();
} else {
PrivilegedAction<Boolean> action = new PrivilegedAction<>() {
public Boolean run() { return hasNextService(); }
};
return AccessController.doPrivileged(action, acc);
}
return hasNextService();
}
@SuppressWarnings("removal")
@Override
public Provider<T> next() {
if (acc == null) {
return nextService();
} else {
PrivilegedAction<Provider<T>> action = new PrivilegedAction<>() {
public Provider<T> run() { return nextService(); }
};
return AccessController.doPrivileged(action, acc);
}
return nextService();
}
}