< 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 >