--- old/src/java.base/share/classes/java/util/ServiceLoader.java 2017-02-07 13:13:38.132567438 +0000 +++ new/src/java.base/share/classes/java/util/ServiceLoader.java 2017-02-07 13:13:37.962555763 +0000 @@ -119,7 +119,7 @@ * and deployed as an explicit module must have an appropriate uses * clause in its module descriptor 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 + * provider deployed as an explicit module must have an appropriate * provides clause in its module descriptor to declare that the module * provides an implementation of the service. The uses and * provides allow consumers of a service to be linked to modules @@ -203,8 +203,11 @@ * ordering of modules in a layer, is not defined. * *
  • 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}).
  • + * 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. * *
  • When locating providers in unnamed modules then the ordering is * based on the order that the class loader's {@link @@ -335,6 +338,8 @@ * * @author Mark Reinhold * @since 1.6 + * @revised 9 + * @spec JPMS */ public final class ServiceLoader @@ -386,6 +391,7 @@ * * @param The service type * @since 9 + * @spec JPMS */ public static interface Provider extends Supplier { /** @@ -927,26 +933,28 @@ } else { catalog = ServicesCatalog.getServicesCatalogOrNull(loader); } - Stream stream1; + List providers; if (catalog == null) { - stream1 = Stream.empty(); + providers = List.of(); } else { - stream1 = catalog.findServices(serviceName).stream(); + providers = catalog.findServices(serviceName); } // modules in custom layers that define modules to the class loader - Stream stream2; if (loader == null) { - stream2 = Stream.empty(); + return providers.iterator(); } else { + List allProviders = new ArrayList<>(providers); Layer bootLayer = Layer.boot(); - stream2 = JLRM_ACCESS.layers(loader) - .filter(l -> (l != bootLayer)) - .map(l -> providers(l)) - .flatMap(List::stream); + Iterator iterator = JLRM_ACCESS.layers(loader).iterator(); + while (iterator.hasNext()) { + Layer layer = iterator.next(); + if (layer != bootLayer) { + allProviders.addAll(providers(layer)); + } + } + return allProviders.iterator(); } - - return Stream.concat(stream1, stream2).iterator(); } @Override @@ -1214,6 +1222,9 @@ * * @return An iterator that lazily loads providers for this loader's * service + * + * @revised 9 + * @spec JPMS */ public Iterator iterator() { @@ -1279,8 +1290,10 @@ * provider to be loaded.

    * *

    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.

    + * #reload() reload} method then existing streams for this service loader + * should be discarded. The returned stream's source {@code Spliterator} is + * fail-fast and will throw {@link ConcurrentModificationException} + * if the provider cache has been cleared.

    * *

    The following examples demonstrate usage. The first example * creates a stream of providers, the second example is the same except @@ -1300,6 +1313,7 @@ * @return A stream that lazily loads providers for this loader's service * * @since 9 + * @spec JPMS */ public Stream> stream() { // use cached providers as the source when all providers loaded @@ -1414,6 +1428,9 @@ * 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 ServiceLoader load(Class service, @@ -1457,6 +1474,9 @@ * 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 ServiceLoader load(Class service) { @@ -1490,6 +1510,9 @@ * 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 ServiceLoader loadInstalled(Class service) { @@ -1522,6 +1545,7 @@ * not declare that it uses {@code service} * * @since 9 + * @spec JPMS */ @CallerSensitive public static ServiceLoader load(Layer layer, Class service) { @@ -1551,6 +1575,7 @@ * or error is thrown when locating or instantiating the provider. * * @since 9 + * @spec JPMS */ public Optional findFirst() { Iterator iterator = iterator();