src/share/classes/java/util/ServiceLoader.java

Print this page



 201      * reloaded.
 202      *
 203      * <p> After invoking this method, subsequent invocations of the {@link
 204      * #iterator() iterator} method will lazily look up and instantiate
 205      * providers from scratch, just as is done by a newly-created loader.
 206      *
 207      * <p> This method is intended for use in situations in which new providers
 208      * can be installed into a running Java virtual machine.
 209      */
 210     public void reload() {
 211         providers.clear();
 212         lookupIterator = new LazyIterator(service, loader);
 213     }
 214 
 215     private ServiceLoader(Class<S> svc, ClassLoader cl) {
 216         service = svc;
 217         loader = cl;
 218         reload();
 219     }
 220 
 221     private static void fail(Class service, String msg, Throwable cause)
 222         throws ServiceConfigurationError
 223     {
 224         throw new ServiceConfigurationError(service.getName() + ": " + msg,
 225                                             cause);
 226     }
 227 
 228     private static void fail(Class service, String msg)
 229         throws ServiceConfigurationError
 230     {
 231         throw new ServiceConfigurationError(service.getName() + ": " + msg);
 232     }
 233 
 234     private static void fail(Class service, URL u, int line, String msg)
 235         throws ServiceConfigurationError
 236     {
 237         fail(service, u + ":" + line + ": " + msg);
 238     }
 239 
 240     // Parse a single line from the given configuration file, adding the name
 241     // on the line to the names list.
 242     //
 243     private int parseLine(Class service, URL u, BufferedReader r, int lc,
 244                           List<String> names)
 245         throws IOException, ServiceConfigurationError
 246     {
 247         String ln = r.readLine();
 248         if (ln == null) {
 249             return -1;
 250         }
 251         int ci = ln.indexOf('#');
 252         if (ci >= 0) ln = ln.substring(0, ci);
 253         ln = ln.trim();
 254         int n = ln.length();
 255         if (n != 0) {
 256             if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
 257                 fail(service, u, lc, "Illegal configuration-file syntax");
 258             int cp = ln.codePointAt(0);
 259             if (!Character.isJavaIdentifierStart(cp))
 260                 fail(service, u, lc, "Illegal provider-class name: " + ln);
 261             for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
 262                 cp = ln.codePointAt(i);
 263                 if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))


 269         return lc + 1;
 270     }
 271 
 272     // Parse the content of the given URL as a provider-configuration file.
 273     //
 274     // @param  service
 275     //         The service type for which providers are being sought;
 276     //         used to construct error detail strings
 277     //
 278     // @param  u
 279     //         The URL naming the configuration file to be parsed
 280     //
 281     // @return A (possibly empty) iterator that will yield the provider-class
 282     //         names in the given configuration file that are not yet members
 283     //         of the returned set
 284     //
 285     // @throws ServiceConfigurationError
 286     //         If an I/O error occurs while reading from the given URL, or
 287     //         if a configuration-file format error is detected
 288     //
 289     private Iterator<String> parse(Class service, URL u)
 290         throws ServiceConfigurationError
 291     {
 292         InputStream in = null;
 293         BufferedReader r = null;
 294         ArrayList<String> names = new ArrayList<>();
 295         try {
 296             in = u.openStream();
 297             r = new BufferedReader(new InputStreamReader(in, "utf-8"));
 298             int lc = 1;
 299             while ((lc = parseLine(service, u, r, lc, names)) >= 0);
 300         } catch (IOException x) {
 301             fail(service, "Error reading configuration file", x);
 302         } finally {
 303             try {
 304                 if (r != null) r.close();
 305                 if (in != null) in.close();
 306             } catch (IOException y) {
 307                 fail(service, "Error closing configuration file", y);
 308             }
 309         }



 201      * reloaded.
 202      *
 203      * <p> After invoking this method, subsequent invocations of the {@link
 204      * #iterator() iterator} method will lazily look up and instantiate
 205      * providers from scratch, just as is done by a newly-created loader.
 206      *
 207      * <p> This method is intended for use in situations in which new providers
 208      * can be installed into a running Java virtual machine.
 209      */
 210     public void reload() {
 211         providers.clear();
 212         lookupIterator = new LazyIterator(service, loader);
 213     }
 214 
 215     private ServiceLoader(Class<S> svc, ClassLoader cl) {
 216         service = svc;
 217         loader = cl;
 218         reload();
 219     }
 220 
 221     private static void fail(Class<?> service, String msg, Throwable cause)
 222         throws ServiceConfigurationError
 223     {
 224         throw new ServiceConfigurationError(service.getName() + ": " + msg,
 225                                             cause);
 226     }
 227 
 228     private static void fail(Class<?> service, String msg)
 229         throws ServiceConfigurationError
 230     {
 231         throw new ServiceConfigurationError(service.getName() + ": " + msg);
 232     }
 233 
 234     private static void fail(Class<?> service, URL u, int line, String msg)
 235         throws ServiceConfigurationError
 236     {
 237         fail(service, u + ":" + line + ": " + msg);
 238     }
 239 
 240     // Parse a single line from the given configuration file, adding the name
 241     // on the line to the names list.
 242     //
 243     private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
 244                           List<String> names)
 245         throws IOException, ServiceConfigurationError
 246     {
 247         String ln = r.readLine();
 248         if (ln == null) {
 249             return -1;
 250         }
 251         int ci = ln.indexOf('#');
 252         if (ci >= 0) ln = ln.substring(0, ci);
 253         ln = ln.trim();
 254         int n = ln.length();
 255         if (n != 0) {
 256             if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
 257                 fail(service, u, lc, "Illegal configuration-file syntax");
 258             int cp = ln.codePointAt(0);
 259             if (!Character.isJavaIdentifierStart(cp))
 260                 fail(service, u, lc, "Illegal provider-class name: " + ln);
 261             for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
 262                 cp = ln.codePointAt(i);
 263                 if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))


 269         return lc + 1;
 270     }
 271 
 272     // Parse the content of the given URL as a provider-configuration file.
 273     //
 274     // @param  service
 275     //         The service type for which providers are being sought;
 276     //         used to construct error detail strings
 277     //
 278     // @param  u
 279     //         The URL naming the configuration file to be parsed
 280     //
 281     // @return A (possibly empty) iterator that will yield the provider-class
 282     //         names in the given configuration file that are not yet members
 283     //         of the returned set
 284     //
 285     // @throws ServiceConfigurationError
 286     //         If an I/O error occurs while reading from the given URL, or
 287     //         if a configuration-file format error is detected
 288     //
 289     private Iterator<String> parse(Class<?> service, URL u)
 290         throws ServiceConfigurationError
 291     {
 292         InputStream in = null;
 293         BufferedReader r = null;
 294         ArrayList<String> names = new ArrayList<>();
 295         try {
 296             in = u.openStream();
 297             r = new BufferedReader(new InputStreamReader(in, "utf-8"));
 298             int lc = 1;
 299             while ((lc = parseLine(service, u, r, lc, names)) >= 0);
 300         } catch (IOException x) {
 301             fail(service, "Error reading configuration file", x);
 302         } finally {
 303             try {
 304                 if (r != null) r.close();
 305                 if (in != null) in.close();
 306             } catch (IOException y) {
 307                 fail(service, "Error closing configuration file", y);
 308             }
 309         }