--- old/src/share/classes/java/util/ServiceLoader.java 2013-07-02 11:21:05.966114279 +0100 +++ new/src/share/classes/java/util/ServiceLoader.java 2013-07-02 11:21:05.638114287 +0100 @@ -30,6 +30,9 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; +import java.security.AccessController; +import java.security.AccessControlContext; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; @@ -185,10 +188,13 @@ private static final String PREFIX = "META-INF/services/"; // The class or interface representing the service being loaded - private Class service; + private final Class service; // 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 private LinkedHashMap providers = new LinkedHashMap<>(); @@ -215,6 +221,7 @@ private ServiceLoader(Class svc, ClassLoader cl) { service = Objects.requireNonNull(svc, "Service interface cannot be null"); loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl; + acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null; reload(); } @@ -327,7 +334,7 @@ this.loader = loader; } - public boolean hasNext() { + private boolean hasNextService() { if (nextName != null) { return true; } @@ -352,10 +359,9 @@ return true; } - public S next() { - if (!hasNext()) { + private S nextService() { + if (!hasNextService()) throw new NoSuchElementException(); - } String cn = nextName; nextName = null; Class c = null; @@ -381,6 +387,24 @@ throw new Error(); // This cannot happen } + public boolean hasNext() { + if (acc == null) { + return hasNextService(); + } else { + PrivilegedAction action = () -> hasNextService(); + return AccessController.doPrivileged(action, acc); + } + } + + public S next() { + if (acc == null) { + return nextService(); + } else { + PrivilegedAction action = () -> nextService(); + return AccessController.doPrivileged(action, acc); + } + } + public void remove() { throw new UnsupportedOperationException(); }