< prev index next >

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

Print this page

        

*** 117,127 **** * * <p> An application or library using this loading facility and developed * and deployed as an explicit module must have an appropriate <i>uses</i> * clause in its <i>module descriptor</i> to declare that the module uses * implementations of the service. A corresponding requirement is that a ! * provider deployed as a named module must have an appropriate * <i>provides</i> clause in its module descriptor to declare that the module * provides an implementation of the service. The <i>uses</i> and * <i>provides</i> allow consumers of a service to be <i>linked</i> to modules * containing providers of the service. * --- 117,127 ---- * * <p> An application or library using this loading facility and developed * and deployed as an explicit module must have an appropriate <i>uses</i> * clause in its <i>module descriptor</i> to declare that the module uses * implementations of the service. A corresponding requirement is that a ! * provider deployed as an explicit module must have an appropriate * <i>provides</i> clause in its module descriptor to declare that the module * provides an implementation of the service. The <i>uses</i> and * <i>provides</i> allow consumers of a service to be <i>linked</i> to modules * containing providers of the service. *
*** 201,212 **** * all providers in that layer are located, irrespective of their class * loader. The ordering of modules defined to the same class loader, or the * ordering of modules in a layer, is not defined. </li> * * <li> If a named module declares more than one provider then the providers ! * are located in the order that they appear in the {@code provides} table of ! * the {@code Module} class file attribute ({@code module-info.class}). </li> * * <li> When locating providers in unnamed modules then the ordering is * based on the order that the class loader's {@link * ClassLoader#getResources(String) ClassLoader.getResources(String)} * method finds the service configuration files. </li> --- 201,215 ---- * all providers in that layer are located, irrespective of their class * loader. The ordering of modules defined to the same class loader, or the * ordering of modules in a layer, is not defined. </li> * * <li> If a named module declares more than one provider then the providers ! * are located in the iteration order of the {@link ! * java.lang.module.ModuleDescriptor.Provides#providers() providers} list. ! * Providers added dynamically by instrumentation agents ({@link ! * java.lang.instrument.Instrumentation#redefineModule redefineModule}) ! * are always located after providers declared by the module. </li> * * <li> When locating providers in unnamed modules then the ordering is * based on the order that the class loader's {@link * ClassLoader#getResources(String) ClassLoader.getResources(String)} * method finds the service configuration files. </li>
*** 333,342 **** --- 336,347 ---- * @param <S> * The type of the service to be loaded by this loader * * @author Mark Reinhold * @since 1.6 + * @revised 9 + * @spec JPMS */ public final class ServiceLoader<S> implements Iterable<S> {
*** 384,393 **** --- 389,399 ---- * to select or filter on the provider class without instantiating the * provider. </p> * * @param <S> The service type * @since 9 + * @spec JPMS */ public static interface Provider<S> extends Supplier<S> { /** * Returns the provider type. There is no guarantee that this type is * accessible or that it has a public no-args constructor. The {@link
*** 925,954 **** if (loader == null) { catalog = BootLoader.getServicesCatalog(); } else { catalog = ServicesCatalog.getServicesCatalogOrNull(loader); } ! Stream<ServiceProvider> stream1; if (catalog == null) { ! stream1 = Stream.empty(); } else { ! stream1 = catalog.findServices(serviceName).stream(); } // modules in custom layers that define modules to the class loader - Stream<ServiceProvider> stream2; if (loader == null) { ! stream2 = Stream.empty(); } else { Layer bootLayer = Layer.boot(); ! stream2 = JLRM_ACCESS.layers(loader) ! .filter(l -> (l != bootLayer)) ! .map(l -> providers(l)) ! .flatMap(List::stream); } - - return Stream.concat(stream1, stream2).iterator(); } @Override public boolean hasNext() { // already have the next provider cached --- 931,962 ---- if (loader == null) { catalog = BootLoader.getServicesCatalog(); } else { catalog = ServicesCatalog.getServicesCatalogOrNull(loader); } ! List<ServiceProvider> providers; if (catalog == null) { ! providers = List.of(); } else { ! providers = catalog.findServices(serviceName); } // modules in custom layers that define modules to the class loader if (loader == null) { ! return providers.iterator(); } else { + List<ServiceProvider> allProviders = new ArrayList<>(providers); Layer bootLayer = Layer.boot(); ! Iterator<Layer> iterator = JLRM_ACCESS.layers(loader).iterator(); ! while (iterator.hasNext()) { ! Layer layer = iterator.next(); ! if (layer != bootLayer) { ! allProviders.addAll(providers(layer)); ! } ! } ! return allProviders.iterator(); } } @Override public boolean hasNext() { // already have the next provider cached
*** 1212,1221 **** --- 1220,1232 ---- * Invoking its {@link java.util.Iterator#remove() remove} method will * cause an {@link UnsupportedOperationException} to be thrown. * * @return An iterator that lazily loads providers for this loader's * service + * + * @revised 9 + * @spec JPMS */ public Iterator<S> iterator() { // create lookup iterator if needed if (lookupIterator1 == null) {
*** 1277,1288 **** * thrown when locating the provider then it is wrapped with a {@code * ServiceConfigurationError} and thrown by whatever method caused the * provider to be loaded. </p> * * <p> If this loader's provider caches are cleared by invoking the {@link ! * #reload() reload} method then existing streams for this service ! * loader should be discarded. </p> * * <p> The following examples demonstrate usage. The first example * creates a stream of providers, the second example is the same except * that it sorts the providers by provider class name (and so locate all * providers). --- 1288,1301 ---- * thrown when locating the provider then it is wrapped with a {@code * ServiceConfigurationError} and thrown by whatever method caused the * provider to be loaded. </p> * * <p> If this loader's provider caches are cleared by invoking the {@link ! * #reload() reload} method then existing streams for this service loader ! * should be discarded. The returned stream's source {@code Spliterator} is ! * <em>fail-fast</em> and will throw {@link ConcurrentModificationException} ! * if the provider cache has been cleared. </p> * * <p> The following examples demonstrate usage. The first example * creates a stream of providers, the second example is the same except * that it sorts the providers by provider class name (and so locate all * providers).
*** 1298,1307 **** --- 1311,1321 ---- * }</pre> * * @return A stream that lazily loads providers for this loader's service * * @since 9 + * @spec JPMS */ public Stream<Provider<S>> stream() { // use cached providers as the source when all providers loaded if (loadedAllProviders) { return loadedProviders.stream();
*** 1412,1421 **** --- 1426,1438 ---- * * @throws ServiceConfigurationError * if the service type is not accessible to the caller or the * caller is in an explicit module and its module descriptor does * not declare that it uses {@code service} + * + * @revised 9 + * @spec JPMS */ @CallerSensitive public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader) {
*** 1455,1464 **** --- 1472,1484 ---- * * @throws ServiceConfigurationError * if the service type is not accessible to the caller or the * caller is in an explicit module and its module descriptor does * not declare that it uses {@code service} + * + * @revised 9 + * @spec JPMS */ @CallerSensitive public static <S> ServiceLoader<S> load(Class<S> service) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); return new ServiceLoader<>(Reflection.getCallerClass(), service, cl);
*** 1488,1497 **** --- 1508,1520 ---- * * @throws ServiceConfigurationError * if the service type is not accessible to the caller or the * caller is in an explicit module and its module descriptor does * not declare that it uses {@code service} + * + * @revised 9 + * @spec JPMS */ @CallerSensitive public static <S> ServiceLoader<S> loadInstalled(Class<S> service) { ClassLoader cl = ClassLoader.getPlatformClassLoader(); return new ServiceLoader<>(Reflection.getCallerClass(), service, cl);
*** 1520,1529 **** --- 1543,1553 ---- * if the service type is not accessible to the caller or the * caller is in an explicit module and its module descriptor does * not declare that it uses {@code service} * * @since 9 + * @spec JPMS */ @CallerSensitive public static <S> ServiceLoader<S> load(Layer layer, Class<S> service) { return new ServiceLoader<>(Reflection.getCallerClass(), layer, service); }
*** 1549,1558 **** --- 1573,1583 ---- * appropriate static factory method or constructor, can't be * assigned to the service type, or if any other kind of exception * or error is thrown when locating or instantiating the provider. * * @since 9 + * @spec JPMS */ public Optional<S> findFirst() { Iterator<S> iterator = iterator(); if (iterator.hasNext()) { return Optional.of(iterator.next());
< prev index next >