From 64e526d079a7218f984eeaba6ff2feeaadeeaffb Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 6 Apr 2010 16:36:51 -0700 Subject: Actually use ServiceLoader in places where we had a hard-coded equivalent. I've also removed a file that was causing us to use this code unnecessarily at run-time to explicitly specify the built-in default PreferencesFactory. I haven't touched Charset, but should come back and fix that too at some point. Change-Id: I3a2145041d048078bdb55ae7b8fa4ec9d8726922 --- luni/src/main/java/java/util/ServiceLoader.java | 45 ++++++++++++++++++------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'luni/src') diff --git a/luni/src/main/java/java/util/ServiceLoader.java b/luni/src/main/java/java/util/ServiceLoader.java index 2f28dff..335a1db 100644 --- a/luni/src/main/java/java/util/ServiceLoader.java +++ b/luni/src/main/java/java/util/ServiceLoader.java @@ -62,6 +62,8 @@ import java.net.URL; * *

Note that each iteration creates new instances of the various service implementations, so * any heavily-used code will likely want to cache the known implementations itself and reuse them. + * Note also that the candidate classes are instantiated lazily as you call {@code next} on the + * iterator: construction of the iterator itself does not instantiate any of the providers. * * @param the service class or interface * @since 1.6 @@ -106,13 +108,17 @@ public final class ServiceLoader implements Iterable { } /** - * Constructs a service loader. + * Constructs a service loader. If {@code classLoader} is null, the system class loader + * is used. * * @param service the service class or interface - * @param loader the class loader + * @param classLoader the class loader * @return a new ServiceLoader */ public static ServiceLoader load(Class service, ClassLoader classLoader) { + if (classLoader == null) { + classLoader = ClassLoader.getSystemClassLoader(); + } return new ServiceLoader(service, classLoader); } @@ -120,16 +126,12 @@ public final class ServiceLoader implements Iterable { services.clear(); try { String name = "META-INF/services/" + service.getName(); - services.addAll(Collections.list(classLoader().getResources(name))); + services.addAll(Collections.list(classLoader.getResources(name))); } catch (IOException e) { return; } } - private ClassLoader classLoader() { - return (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); - } - /** * Constructs a service loader, using the current thread's context class loader. * @@ -156,6 +158,29 @@ public final class ServiceLoader implements Iterable { return ServiceLoader.load(service, cl); } + /** + * Internal API to support built-in SPIs that check a system property first. + * Returns an instance specified by a property with the class' binary name, or null if + * no such property is set. + * @hide + */ + public static S loadFromSystemProperty(final Class service) { + return AccessController.doPrivileged(new PrivilegedAction() { + public S run() { + try { + final String className = System.getProperty(service.getName()); + if (className != null) { + Class c = ClassLoader.getSystemClassLoader().loadClass(className); + return (S) c.newInstance(); + } + return null; + } catch (Exception e) { + throw new Error(e); + } + } + }); + } + @Override public String toString() { return "ServiceLoader for " + service.getName(); @@ -190,11 +215,7 @@ public final class ServiceLoader implements Iterable { } String className = queue.remove(); try { - if (classLoader == null) { - return service.cast(Class.forName(className).newInstance()); - } else { - return service.cast(classLoader.loadClass(className).newInstance()); - } + return service.cast(classLoader.loadClass(className).newInstance()); } catch (Exception e) { throw new ServiceConfigurationError("Couldn't instantiate class " + className, e); } -- cgit v1.1