提交 b0983556 编写于 作者: A alanb

8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts

Reviewed-by: mchung, ahgross, forax, psandoz
上级 1bc949f6
...@@ -30,6 +30,9 @@ import java.io.IOException; ...@@ -30,6 +30,9 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
...@@ -185,10 +188,13 @@ public final class ServiceLoader<S> ...@@ -185,10 +188,13 @@ public final class ServiceLoader<S>
private static final String PREFIX = "META-INF/services/"; private static final String PREFIX = "META-INF/services/";
// The class or interface representing the service being loaded // The class or interface representing the service being loaded
private Class<S> service; private final Class<S> service;
// The class loader used to locate, load, and instantiate providers // The class loader used to locate, load, and instantiate providers
private ClassLoader loader; private final ClassLoader loader;
// The access control context taken when the ServiceLoader is created
private final AccessControlContext acc;
// Cached providers, in instantiation order // Cached providers, in instantiation order
private LinkedHashMap<String,S> providers = new LinkedHashMap<>(); private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
...@@ -215,6 +221,7 @@ public final class ServiceLoader<S> ...@@ -215,6 +221,7 @@ public final class ServiceLoader<S>
private ServiceLoader(Class<S> svc, ClassLoader cl) { private ServiceLoader(Class<S> svc, ClassLoader cl) {
service = Objects.requireNonNull(svc, "Service interface cannot be null"); service = Objects.requireNonNull(svc, "Service interface cannot be null");
loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl; loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
reload(); reload();
} }
...@@ -327,7 +334,7 @@ public final class ServiceLoader<S> ...@@ -327,7 +334,7 @@ public final class ServiceLoader<S>
this.loader = loader; this.loader = loader;
} }
public boolean hasNext() { private boolean hasNextService() {
if (nextName != null) { if (nextName != null) {
return true; return true;
} }
...@@ -352,10 +359,9 @@ public final class ServiceLoader<S> ...@@ -352,10 +359,9 @@ public final class ServiceLoader<S>
return true; return true;
} }
public S next() { private S nextService() {
if (!hasNext()) { if (!hasNextService())
throw new NoSuchElementException(); throw new NoSuchElementException();
}
String cn = nextName; String cn = nextName;
nextName = null; nextName = null;
Class<?> c = null; Class<?> c = null;
...@@ -381,6 +387,28 @@ public final class ServiceLoader<S> ...@@ -381,6 +387,28 @@ public final class ServiceLoader<S>
throw new Error(); // This cannot happen throw new Error(); // This cannot happen
} }
public boolean hasNext() {
if (acc == null) {
return hasNextService();
} else {
PrivilegedAction<Boolean> action = new PrivilegedAction<Boolean>() {
public Boolean run() { return hasNextService(); }
};
return AccessController.doPrivileged(action, acc);
}
}
public S next() {
if (acc == null) {
return nextService();
} else {
PrivilegedAction<S> action = new PrivilegedAction<S>() {
public S run() { return nextService(); }
};
return AccessController.doPrivileged(action, acc);
}
}
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册