diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2007-01-01 20:27:36 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2007-01-01 20:27:36 +0000 |
commit | dcba527c112e564771f554731f71c3d7c1c11533 (patch) | |
tree | 7eea75af633d8bb76f2ac4c3c8d0f0ecd80fd6fc /gnu/classpath | |
parent | eeecdc6f3fd6990889b204abe0d60f6061ca8bfb (diff) | |
download | classpath-dcba527c112e564771f554731f71c3d7c1c11533.tar.gz |
2007-01-01 Andrew John Hughes <gnu_andrew@member.fsf.org>
* ChangeLog-2006: New file.
* gnu/classpath/ServiceFactory.java:
Add option of throwing a ServiceConfigurationError.
(lookupProviders(Class,ClassLoader,boolean)): Implemented.
* java/util/ServiceConfigurationError.java: New file.
* java/util/ServiceLoader.java: Likewise.
Diffstat (limited to 'gnu/classpath')
-rw-r--r-- | gnu/classpath/ServiceFactory.java | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/gnu/classpath/ServiceFactory.java b/gnu/classpath/ServiceFactory.java index 122a79c96..daf996c23 100644 --- a/gnu/classpath/ServiceFactory.java +++ b/gnu/classpath/ServiceFactory.java @@ -49,6 +49,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.ServiceConfigurationError; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; @@ -176,7 +177,6 @@ public final class ServiceFactory */ private static final Logger LOGGER = Logger.getLogger("gnu.classpath"); - /** * Declared private in order to prevent constructing instances of * this utility class. @@ -225,6 +225,51 @@ public final class ServiceFactory public static Iterator lookupProviders(Class spi, ClassLoader loader) { + return lookupProviders(spi, loader, false); + } + + /** + * Finds service providers that are implementing the specified + * Service Provider Interface. + * + * <p><b>On-demand loading:</b> Loading and initializing service + * providers is delayed as much as possible. The rationale is that + * typical clients will iterate through the set of installed service + * providers until one is found that matches some criteria (like + * supported formats, or quality of service). In such scenarios, it + * might make sense to install only the frequently needed service + * providers on the local machine. More exotic providers can be put + * onto a server; the server will only be contacted when no suitable + * service could be found locally. + * + * <p><b>Security considerations:</b> Any loaded service providers + * are loaded through the specified ClassLoader, or the system + * ClassLoader if <code>classLoader</code> is + * <code>null</code>. When <code>lookupProviders</code> is called, + * the current {@link AccessControlContext} gets recorded. This + * captured security context will determine the permissions when + * services get loaded via the <code>next()</code> method of the + * returned <code>Iterator</code>. + * + * @param spi the service provider interface which must be + * implemented by any loaded service providers. + * + * @param loader the class loader that will be used to load the + * service providers, or <code>null</code> for the system class + * loader. For using the context class loader, see {@link + * #lookupProviders(Class)}. + * @param error true if a {@link ServiceConfigurationError} + * should be thrown when an error occurs, rather + * than it merely being logged. + * @return an iterator over instances of <code>spi</code>. + * + * @throws IllegalArgumentException if <code>spi</code> is + * <code>null</code>. + */ + public static Iterator lookupProviders(Class spi, + ClassLoader loader, + boolean error) + { String resourceName; Enumeration urls; @@ -246,10 +291,14 @@ public final class ServiceFactory * does not return anything (no providers installed). */ log(Level.WARNING, "cannot access {0}", resourceName, ioex); - return Collections.EMPTY_LIST.iterator(); + if (error) + throw new ServiceConfigurationError("Failed to access + " + + resourceName, ioex); + else + return Collections.EMPTY_LIST.iterator(); } - return new ServiceIterator(spi, urls, loader, + return new ServiceIterator(spi, urls, loader, error, AccessController.getContext()); } @@ -342,6 +391,11 @@ public final class ServiceFactory */ private Object nextProvider; + /** + * True if a {@link ServiceConfigurationError} should be thrown + * when an error occurs, instead of it merely being logged. + */ + private boolean error; /** * Constructs an Iterator that loads and initializes services on @@ -359,16 +413,21 @@ public final class ServiceFactory * @param loader the ClassLoader that gets used for loading * service providers. * + * @param error true if a {@link ServiceConfigurationError} + * should be thrown when an error occurs, rather + * than it merely being logged. + * * @param securityContext the security context to use when loading * and initializing service providers. */ ServiceIterator(Class spi, Enumeration urls, ClassLoader loader, - AccessControlContext securityContext) + boolean error, AccessControlContext securityContext) { this.spi = spi; this.urls = urls; this.loader = loader; this.securityContext = securityContext; + this.error = error; this.nextProvider = loadNextServiceProvider(); } @@ -426,6 +485,9 @@ public final class ServiceFactory log(Level.WARNING, "IOException upon reading {0}", currentURL, readProblem); line = null; + if (error) + throw new ServiceConfigurationError("Error reading " + + currentURL, readProblem); } /* When we are at the end of one list of services, @@ -477,6 +539,13 @@ public final class ServiceFactory log(Level.WARNING, msg, new Object[] { line, spi.getName(), currentURL }, ex); + if (error) + throw new ServiceConfigurationError("Cannot load service "+ + "provider class " + + line + " specified by "+ + "\"META-INF/services/"+ + spi.getName() + "\" in "+ + currentURL, ex); continue; } } @@ -497,6 +566,9 @@ public final class ServiceFactory catch (Exception ex) { log(Level.WARNING, "cannot close {0}", currentURL, ex); + if (error) + throw new ServiceConfigurationError("Cannot close " + + currentURL, ex); } reader = null; currentURL = null; @@ -515,6 +587,9 @@ public final class ServiceFactory catch (Exception ex) { log(Level.WARNING, "cannot open {0}", currentURL, ex); + if (error) + throw new ServiceConfigurationError("Cannot open " + + currentURL, ex); } } while (reader == null); |