8175385: ServiceLoader$LazyClassPathLookupIterator scans boot and platform modules for services
Reviewed-by: alanb, mchung
--- a/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Tue Feb 28 16:44:58 2017 +0800
+++ b/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Tue Feb 28 12:24:29 2017 +0100
@@ -48,6 +48,7 @@
import java.util.stream.StreamSupport;
import jdk.internal.loader.BootLoader;
+import jdk.internal.loader.ClassLoaders;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.JavaLangReflectModuleAccess;
import jdk.internal.misc.SharedSecrets;
@@ -1076,10 +1077,19 @@
if (configs == null) {
try {
String fullName = PREFIX + service.getName();
- if (loader == null)
+ if (loader == null) {
configs = ClassLoader.getSystemResources(fullName);
- else
+ } else if (loader == ClassLoaders.platformClassLoader()) {
+ // The platform classloader doesn't have a class path,
+ // but the boot loader might.
+ if (BootLoader.hasClassPath()) {
+ configs = BootLoader.findResources(fullName);
+ } else {
+ configs = Collections.emptyEnumeration();
+ }
+ } else {
configs = loader.getResources(fullName);
+ }
} catch (IOException x) {
fail(service, "Error locating configuration files", x);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Tue Feb 28 16:44:58 2017 +0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Tue Feb 28 12:24:29 2017 +0100
@@ -188,6 +188,14 @@
}
/**
+ * Returns {@code true} if there is a class path associated with the
+ * BootLoader.
+ */
+ public static boolean hasClassPath() {
+ return ClassLoaders.bootLoader().hasClassPath();
+ }
+
+ /**
* Helper class to define {@code Package} objects for packages in modules
* defined to the boot loader.
*/
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Tue Feb 28 16:44:58 2017 +0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Tue Feb 28 12:24:29 2017 +0100
@@ -425,7 +425,7 @@
* Returns a URL to a resource on the class path.
*/
private URL findResourceOnClassPath(String name) {
- if (ucp != null) {
+ if (hasClassPath()) {
if (System.getSecurityManager() == null) {
return ucp.findResource(name, false);
} else {
@@ -442,7 +442,7 @@
* Returns the URLs of all resources of the given name on the class path.
*/
private Enumeration<URL> findResourcesOnClassPath(String name) {
- if (ucp != null) {
+ if (hasClassPath()) {
if (System.getSecurityManager() == null) {
return ucp.findResources(name, false);
} else {
@@ -481,7 +481,7 @@
} else {
// search class path
- if (ucp != null) {
+ if (hasClassPath()) {
c = findClassOnClassPathOrNull(cn);
}
@@ -514,7 +514,7 @@
}
// search class path
- if (ucp != null) {
+ if (hasClassPath()) {
return findClassOnClassPathOrNull(cn);
}
@@ -569,7 +569,7 @@
}
// check class path
- if (c == null && ucp != null && VM.isModuleSystemInited()) {
+ if (c == null && hasClassPath() && VM.isModuleSystemInited()) {
c = findClassOnClassPathOrNull(cn);
}
}
@@ -870,6 +870,14 @@
}
/**
+ * Returns {@code true} if there is a class path associated with this
+ * class loader.
+ */
+ boolean hasClassPath() {
+ return ucp != null;
+ }
+
+ /**
* Returns {@code true} if the specified package name is sealed according to
* the given manifest.
*/