src/java.base/share/classes/java/util/ServiceLoader.java
author igerasim
Tue, 11 Sep 2018 14:51:45 -0700
changeset 51703 4ffb0a33f265
parent 51111 99a7d10f248c
child 52427 3c6aa484536c
permissions -rw-r--r--
8210347: Combine subsequent calls to Set.contains() and Set.add() Reviewed-by: smarks, bpb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
51111
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
     2
 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.util;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.BufferedReader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.InputStreamReader;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    32
import java.lang.reflect.Constructor;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    33
import java.lang.reflect.InvocationTargetException;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    34
import java.lang.reflect.Method;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    35
import java.lang.reflect.Modifier;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.net.URL;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    37
import java.net.URLConnection;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    38
import java.security.AccessControlContext;
18777
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
    39
import java.security.AccessController;
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
    40
import java.security.PrivilegedAction;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    41
import java.security.PrivilegedActionException;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    42
import java.security.PrivilegedExceptionAction;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    43
import java.util.function.Consumer;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    44
import java.util.function.Supplier;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    45
import java.util.stream.Stream;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    46
import java.util.stream.StreamSupport;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    47
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    48
import jdk.internal.loader.BootLoader;
44003
dc26a57d2570 8175385: ServiceLoader$LazyClassPathLookupIterator scans boot and platform modules for services
redestad
parents: 43712
diff changeset
    49
import jdk.internal.loader.ClassLoaders;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    50
import jdk.internal.misc.JavaLangAccess;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    51
import jdk.internal.misc.SharedSecrets;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    52
import jdk.internal.misc.VM;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    53
import jdk.internal.module.ServicesCatalog;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
    54
import jdk.internal.module.ServicesCatalog.ServiceProvider;
37363
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 36511
diff changeset
    55
import jdk.internal.reflect.CallerSensitive;
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 36511
diff changeset
    56
import jdk.internal.reflect.Reflection;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
/**
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    60
 * A facility to load implementations of a service.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    62
 * <p> A <i>service</i> is a well-known interface or class for which zero, one,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    63
 * or many service providers exist. A <i>service provider</i> (or just
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    64
 * <i>provider</i>) is a class that implements or subclasses the well-known
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    65
 * interface or class. A {@code ServiceLoader} is an object that locates and
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    66
 * loads service providers deployed in the run time environment at a time of an
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    67
 * application's choosing. Application code refers only to the service, not to
51111
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    68
 * service providers, and is assumed to be capable of choosing between multiple
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    69
 * service providers (based on the functionality they expose through the service),
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    70
 * and handling the possibility that no service providers are located.
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    71
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    72
 * <h3> Obtaining a service loader </h3>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    74
 * <p> An application obtains a service loader for a given service by invoking
51111
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    75
 * one of the static {@code load} methods of {@code ServiceLoader}. If the
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    76
 * application is a module, then its module declaration must have a <i>uses</i>
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    77
 * directive that specifies the service; this helps to locate providers and ensure
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    78
 * they will execute reliably. In addition, if the application module does not
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    79
 * contain the service, then its module declaration must have a <i>requires</i>
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    80
 * directive that specifies the module which exports the service. It is strongly
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    81
 * recommended that the application module does <b>not</b> require modules which
99a7d10f248c 8207393: ServiceLoader class description improvements
alanb
parents: 47471
diff changeset
    82
 * contain providers of the service.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
    83
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    84
 * <p> A service loader can be used to locate and instantiate providers of the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    85
 * service by means of the {@link #iterator() iterator} method. {@code ServiceLoader}
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    86
 * also defines the {@link #stream() stream} method to obtain a stream of providers
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    87
 * that can be inspected and filtered without instantiating them.
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    88
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    89
 * <p> As an example, suppose the service is {@code com.example.CodecFactory}, an
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    90
 * interface that defines methods for producing encoders and decoders:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    91
 *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    92
 * <pre>{@code
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    93
 *     package com.example;
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    94
 *     public interface CodecFactory {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    95
 *         Encoder getEncoder(String encodingName);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    96
 *         Decoder getDecoder(String encodingName);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    97
 *     }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
    98
 * }</pre>
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
    99
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   100
 * <p> The following code obtains a service loader for the {@code CodecFactory}
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   101
 * service, then uses its iterator (created automatically by the enhanced-for
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   102
 * loop) to yield instances of the service providers that are located:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   103
 *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   104
 * <pre>{@code
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   105
 *     ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   106
 *     for (CodecFactory factory : loader) {
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   107
 *         Encoder enc = factory.getEncoder("PNG");
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   108
 *         if (enc != null)
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   109
 *             ... use enc to encode a PNG file
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   110
 *             break;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   111
 *         }
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   112
 * }</pre>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   113
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   114
 * <p> If this code resides in a module, then in order to refer to the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   115
 * {@code com.example.CodecFactory} interface, the module declaration would
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   116
 * require the module which exports the interface. The module declaration would
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   117
 * also specify use of {@code com.example.CodecFactory}:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   118
 * <pre>{@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   119
 *     requires com.example.codec.core;
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   120
 *     uses com.example.CodecFactory;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   121
 * }</pre>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   122
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   123
 * <p> Sometimes an application may wish to inspect a service provider before
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   124
 * instantiating it, in order to determine if an instance of that service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   125
 * provider would be useful. For example, a service provider for {@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   126
 * CodecFactory} that is capable of producing a "PNG" encoder may be annotated
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   127
 * with {@code @PNG}. The following code uses service loader's {@code stream}
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   128
 * method to yield instances of {@code Provider<CodecFactory>} in contrast to
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   129
 * how the iterator yields instances of {@code CodecFactory}:
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   130
 * <pre>{@code
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   131
 *     ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   132
 *     Set<CodecFactory> pngFactories = loader
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   133
 *            .stream()                                              // Note a below
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   134
 *            .filter(p -> p.type().isAnnotationPresent(PNG.class))  // Note b
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   135
 *            .map(Provider::get)                                    // Note c
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   136
 *            .collect(Collectors.toSet());
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   137
 * }</pre>
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   138
 * <ol type="a">
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   139
 *   <li> A stream of {@code Provider<CodecFactory>} objects </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   140
 *   <li> {@code p.type()} yields a {@code Class<CodecFactory>} </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   141
 *   <li> {@code get()} yields an instance of {@code CodecFactory} </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   142
 * </ol>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   143
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   144
 * <h3> Designing services </h3>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   145
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   146
 * <p> A service is a single type, usually an interface or abstract class. A
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   147
 * concrete class can be used, but this is not recommended. The type may have
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   148
 * any accessibility. The methods of a service are highly domain-specific, so
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   149
 * this API specification cannot give concrete advice about their form or
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   150
 * function. However, there are two general guidelines:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   151
 * <ol>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   152
 *   <li><p> A service should declare as many methods as needed to allow service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   153
 *   providers to communicate their domain-specific properties and other
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   154
 *   quality-of-implementation factors. An application which obtains a service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   155
 *   loader for the service may then invoke these methods on each instance of
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   156
 *   a service provider, in order to choose the best provider for the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   157
 *   application. </p></li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   158
 *   <li><p> A service should express whether its service providers are intended
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   159
 *   to be direct implementations of the service or to be an indirection
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   160
 *   mechanism such as a "proxy" or a "factory". Service providers tend to be
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   161
 *   indirection mechanisms when domain-specific objects are relatively
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   162
 *   expensive to instantiate; in this case, the service should be designed
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   163
 *   so that service providers are abstractions which create the "real"
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   164
 *   implementation on demand. For example, the {@code CodecFactory} service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   165
 *   expresses through its name that its service providers are factories
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   166
 *   for codecs, rather than codecs themselves, because it may be expensive
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   167
 *   or complicated to produce certain codecs. </p></li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   168
 * </ol>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   169
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   170
 * <h3> <a id="developing-service-providers">Developing service providers</a> </h3>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   171
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   172
 * <p> A service provider is a single type, usually a concrete class. An
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   173
 * interface or abstract class is permitted because it may declare a static
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   174
 * provider method, discussed later. The type must be public and must not be
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   175
 * an inner class.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   176
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   177
 * <p> A service provider and its supporting code may be developed in a module,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   178
 * which is then deployed on the application module path or in a modular
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   179
 * image. Alternatively, a service provider and its supporting code may be
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   180
 * packaged as a JAR file and deployed on the application class path. The
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   181
 * advantage of developing a service provider in a module is that the provider
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   182
 * can be fully encapsulated to hide all details of its implementation.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   183
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   184
 * <p> An application that obtains a service loader for a given service is
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   185
 * indifferent to whether providers of the service are deployed in modules or
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   186
 * packaged as JAR files. The application instantiates service providers via
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   187
 * the service loader's iterator, or via {@link Provider Provider} objects in
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   188
 * the service loader's stream, without knowledge of the service providers'
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   189
 * locations.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   190
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   191
 * <h3> Deploying service providers as modules </h3>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   192
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   193
 * <p> A service provider that is developed in a module must be specified in a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   194
 * <i>provides</i> directive in the module declaration. The provides directive
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   195
 * specifies both the service and the service provider; this helps to locate the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   196
 * provider when another module, with a <i>uses</i> directive for the service,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   197
 * obtains a service loader for the service. It is strongly recommended that the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   198
 * module does not export the package containing the service provider. There is
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   199
 * no support for a module specifying, in a <i>provides</i> directive, a service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   200
 * provider in another module.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   201
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   202
 * <p> A service provider that is developed in a module has no control over when
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   203
 * it is instantiated, since that occurs at the behest of the application, but it
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   204
 * does have control over how it is instantiated:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   205
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   206
 * <ul>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   207
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   208
 *   <li> If the service provider declares a provider method, then the service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   209
 *   loader invokes that method to obtain an instance of the service provider. A
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   210
 *   provider method is a public static method named "provider" with no formal
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   211
 *   parameters and a return type that is assignable to the service's interface
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   212
 *   or class.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   213
 *   <p> In this case, the service provider itself need not be assignable to the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   214
 *   service's interface or class. </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   215
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   216
 *   <li> If the service provider does not declare a provider method, then the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   217
 *   service provider is instantiated directly, via its provider constructor. A
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   218
 *   provider constructor is a public constructor with no formal parameters.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   219
 *   <p> In this case, the service provider must be assignable to the service's
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   220
 *   interface or class </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   221
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   222
 * </ul>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   223
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   224
 * <p> A service provider that is deployed as an
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   225
 * {@linkplain java.lang.module.ModuleDescriptor#isAutomatic automatic module} on
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   226
 * the application module path must have a provider constructor. There is no
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   227
 * support for a provider method in this case.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   228
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   229
 * <p> As an example, suppose a module specifies the following directives:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   230
 * <pre>{@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   231
 *     provides com.example.CodecFactory with com.example.impl.StandardCodecs;
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   232
 *     provides com.example.CodecFactory with com.example.impl.ExtendedCodecsFactory;
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   233
 * }</pre>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   234
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   235
 * <p> where
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   236
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   237
 * <ul>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   238
 *   <li> {@code com.example.CodecFactory} is the two-method service from
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   239
 *   earlier. </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   240
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   241
 *   <li> {@code com.example.impl.StandardCodecs} is a public class that implements
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   242
 *   {@code CodecFactory} and has a public no-args constructor. </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   243
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   244
 *   <li> {@code com.example.impl.ExtendedCodecsFactory} is a public class that
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   245
 *   does not implement CodecFactory, but it declares a public static no-args
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   246
 *   method named "provider" with a return type of {@code CodecFactory}. </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   247
 * </ul>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   248
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   249
 * <p> A service loader will instantiate {@code StandardCodecs} via its
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   250
 * constructor, and will instantiate {@code ExtendedCodecsFactory} by invoking
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   251
 * its {@code provider} method. The requirement that the provider constructor or
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   252
 * provider method is public helps to document the intent that the class (that is,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   253
 * the service provider) will be instantiated by an entity (that is, a service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   254
 * loader) which is outside the class's package.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   255
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   256
 * <h3> Deploying service providers on the class path </h3>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   257
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   258
 * A service provider that is packaged as a JAR file for the class path is
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   259
 * identified by placing a <i>provider-configuration file</i> in the resource
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   260
 * directory {@code META-INF/services}. The name of the provider-configuration
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   261
 * file is the fully qualified binary name of the service. The provider-configuration
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   262
 * file contains a list of fully qualified binary names of service providers, one
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   263
 * per line.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   264
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   265
 * <p> For example, suppose the service provider
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   266
 * {@code com.example.impl.StandardCodecs} is packaged in a JAR file for the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   267
 * class path. The JAR file will contain a provider-configuration file named:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   268
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   269
 * <blockquote>{@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   270
 *     META-INF/services/com.example.CodecFactory
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   271
 * }</blockquote>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   272
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   273
 * that contains the line:
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   274
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   275
 * <blockquote>{@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   276
 *     com.example.impl.StandardCodecs # Standard codecs
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   277
 * }</blockquote>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   278
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   279
 * <p><a id="format">The provider-configuration file must be encoded in UTF-8. </a>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   280
 * Space and tab characters surrounding each service provider's name, as well as
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   281
 * blank lines, are ignored. The comment character is {@code '#'}
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   282
 * ({@code '&#92;u0023'} <span style="font-size:smaller;">NUMBER SIGN</span>);
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   283
 * on each line all characters following the first comment character are ignored.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   284
 * If a service provider class name is listed more than once in a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   285
 * provider-configuration file then the duplicate is ignored. If a service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   286
 * provider class is named in more than one configuration file then the duplicate
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   287
 * is ignored.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   288
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   289
 * <p> A service provider that is mentioned in a provider-configuration file may
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   290
 * be located in the same JAR file as the provider-configuration file or in a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   291
 * different JAR file. The service provider must be visible from the class loader
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   292
 * that is initially queried to locate the provider-configuration file; this is
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   293
 * not necessarily the class loader which ultimately locates the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   294
 * provider-configuration file.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   295
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   296
 * <h3> Timing of provider discovery </h3>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   297
 *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   298
 * <p> Service providers are loaded and instantiated lazily, that is, on demand.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   299
 * A service loader maintains a cache of the providers that have been loaded so
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   300
 * far. Each invocation of the {@code iterator} method returns an {@code Iterator}
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   301
 * that first yields all of the elements cached from previous iteration, in
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   302
 * instantiation order, and then lazily locates and instantiates any remaining
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   303
 * providers, adding each one to the cache in turn. Similarly, each invocation
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   304
 * of the stream method returns a {@code Stream} that first processes all
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   305
 * providers loaded by previous stream operations, in load order, and then lazily
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   306
 * locates any remaining providers. Caches are cleared via the {@link #reload
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   307
 * reload} method.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   308
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   309
 * <h3> <a id="errors">Errors</a> </h3>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   311
 * <p> When using the service loader's {@code iterator}, the {@link
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   312
 * Iterator#hasNext() hasNext} and {@link Iterator#next() next} methods will
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   313
 * fail with {@link ServiceConfigurationError} if an error occurs locating,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   314
 * loading or instantiating a service provider. When processing the service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   315
 * loader's stream then {@code ServiceConfigurationError} may be thrown by any
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   316
 * method that causes a service provider to be located or loaded.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   318
 * <p> When loading or instantiating a service provider in a module, {@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   319
 * ServiceConfigurationError} can be thrown for the following reasons:
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   320
 *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   321
 * <ul>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   322
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   323
 *   <li> The service provider cannot be loaded. </li>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   324
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   325
 *   <li> The service provider does not declare a provider method, and either
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   326
 *   it is not assignable to the service's interface/class or does not have a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   327
 *   provider constructor. </li>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   328
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   329
 *   <li> The service provider declares a public static no-args method named
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   330
 *   "provider" with a return type that is not assignable to the service's
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   331
 *   interface or class. </li>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   332
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   333
 *   <li> The service provider class file has more than one public static
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   334
 *   no-args method named "{@code provider}". </li>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   335
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   336
 *   <li> The service provider declares a provider method and it fails by
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   337
 *   returning {@code null} or throwing an exception. </li>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   338
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   339
 *   <li> The service provider does not declare a provider method, and its
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   340
 *   provider constructor fails by throwing an exception. </li>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   341
 *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   342
 * </ul>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   343
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   344
 * <p> When reading a provider-configuration file, or loading or instantiating
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   345
 * a provider class named in a provider-configuration file, then {@code
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   346
 * ServiceConfigurationError} can be thrown for the following reasons:
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   347
 *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   348
 * <ul>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   349
 *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   350
 *   <li> The format of the provider-configuration file violates the <a
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   351
 *   href="ServiceLoader.html#format">format</a> specified above; </li>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   352
 *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   353
 *   <li> An {@link IOException IOException} occurs while reading the
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   354
 *   provider-configuration file; </li>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   355
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   356
 *   <li> A service provider cannot be loaded; </li>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   357
 *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   358
 *   <li> A service provider is not assignable to the service's interface or
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   359
 *   class, or does not define a provider constructor, or cannot be
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
   360
 *   instantiated. </li>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   361
 *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   362
 * </ul>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   363
 *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   364
 * <h3> Security </h3>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   365
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   366
 * <p> Service loaders always execute in the security context of the caller
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   367
 * of the iterator or stream methods and may also be restricted by the security
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   368
 * context of the caller that created the service loader.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
 * Trusted system code should typically invoke the methods in this class, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
 * the methods of the iterators which they return, from within a privileged
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
 * security context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
 *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   373
 * <h3> Concurrency </h3>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   374
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
 * <p> Instances of this class are not safe for use by multiple concurrent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
 * threads.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
 *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   378
 * <h3> Null handling </h3>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   379
 *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   380
 * <p> Unless otherwise specified, passing a {@code null} argument to any
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
 * method in this class will cause a {@link NullPointerException} to be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
 * @param  <S>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
 *         The type of the service to be loaded by this loader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
 * @author Mark Reinhold
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
 * @since 1.6
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
   388
 * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
   389
 * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
public final class ServiceLoader<S>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    implements Iterable<S>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    // The class or interface representing the service being loaded
18777
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
   396
    private final Class<S> service;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   398
    // The class of the service type
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   399
    private final String serviceName;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   400
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   401
    // The module layer used to locate providers; null when locating
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   402
    // providers using a class loader
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   403
    private final ModuleLayer layer;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   404
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   405
    // The class loader used to locate, load, and instantiate providers;
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   406
    // null when locating provider using a module layer
18777
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
   407
    private final ClassLoader loader;
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
   408
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
   409
    // The access control context taken when the ServiceLoader is created
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
   410
    private final AccessControlContext acc;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   412
    // The lazy-lookup iterator for iterator operations
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   413
    private Iterator<Provider<S>> lookupIterator1;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   414
    private final List<S> instantiatedProviders = new ArrayList<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   415
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   416
    // The lazy-lookup iterator for stream operations
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   417
    private Iterator<Provider<S>> lookupIterator2;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   418
    private final List<Provider<S>> loadedProviders = new ArrayList<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   419
    private boolean loadedAllProviders; // true when all providers loaded
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   420
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   421
    // Incremented when reload is called
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   422
    private int reloadCount;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   424
    private static JavaLangAccess LANG_ACCESS;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   425
    static {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   426
        LANG_ACCESS = SharedSecrets.getJavaLangAccess();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   427
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   430
     * Represents a service provider located by {@code ServiceLoader}.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   431
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   432
     * <p> When using a loader's {@link ServiceLoader#stream() stream()} method
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   433
     * then the elements are of type {@code Provider}. This allows processing
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   434
     * to select or filter on the provider class without instantiating the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   435
     * provider. </p>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   437
     * @param  <S> The service type
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   438
     * @since 9
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
   439
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   441
    public static interface Provider<S> extends Supplier<S> {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   442
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   443
         * Returns the provider type. There is no guarantee that this type is
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   444
         * accessible or that it has a public no-args constructor. The {@link
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   445
         * #get() get()} method should be used to obtain the provider instance.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   446
         *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   447
         * <p> When a module declares that the provider class is created by a
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   448
         * provider factory then this method returns the return type of its
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   449
         * public static "{@code provider()}" method.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   450
         *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   451
         * @return The provider type
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   452
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   453
        Class<? extends S> type();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   454
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   455
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   456
         * Returns an instance of the provider.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   457
         *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   458
         * @return An instance of the provider.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   459
         *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   460
         * @throws ServiceConfigurationError
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   461
         *         If the service provider cannot be instantiated, or in the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   462
         *         case of a provider factory, the public static
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   463
         *         "{@code provider()}" method returns {@code null} or throws
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   464
         *         an error or exception. The {@code ServiceConfigurationError}
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   465
         *         will carry an appropriate cause where possible.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   466
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   467
        @Override S get();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   468
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   469
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   470
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   471
     * Initializes a new instance of this class for locating service providers
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   472
     * in a module layer.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   473
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   474
     * @throws ServiceConfigurationError
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   475
     *         If {@code svc} is not accessible to {@code caller} or the caller
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   476
     *         module does not use the service type.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   477
     */
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   478
    private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   479
        Objects.requireNonNull(caller);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   480
        Objects.requireNonNull(layer);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   481
        Objects.requireNonNull(svc);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   482
        checkCaller(caller, svc);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   483
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   484
        this.service = svc;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   485
        this.serviceName = svc.getName();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   486
        this.layer = layer;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   487
        this.loader = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   488
        this.acc = (System.getSecurityManager() != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   489
                ? AccessController.getContext()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   490
                : null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   493
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   494
     * Initializes a new instance of this class for locating service providers
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   495
     * via a class loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   496
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   497
     * @throws ServiceConfigurationError
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   498
     *         If {@code svc} is not accessible to {@code caller} or the caller
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   499
     *         module does not use the service type.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   500
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   501
    private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   502
        Objects.requireNonNull(svc);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   503
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   504
        if (VM.isBooted()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   505
            checkCaller(caller, svc);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   506
            if (cl == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   507
                cl = ClassLoader.getSystemClassLoader();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   508
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   509
        } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   510
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   511
            // if we get here then it means that ServiceLoader is being used
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   512
            // before the VM initialization has completed. At this point then
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   513
            // only code in the java.base should be executing.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   514
            Module callerModule = caller.getModule();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   515
            Module base = Object.class.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   516
            Module svcModule = svc.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   517
            if (callerModule != base || svcModule != base) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   518
                fail(svc, "not accessible to " + callerModule + " during VM init");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   519
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   520
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   521
            // restricted to boot loader during startup
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   522
            cl = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   523
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   524
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   525
        this.service = svc;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   526
        this.serviceName = svc.getName();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   527
        this.layer = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   528
        this.loader = cl;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   529
        this.acc = (System.getSecurityManager() != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   530
                ? AccessController.getContext()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   531
                : null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   534
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   535
     * Initializes a new instance of this class for locating service providers
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   536
     * via a class loader.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   537
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   538
     * @apiNote For use by ResourceBundle
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   539
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   540
     * @throws ServiceConfigurationError
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   541
     *         If the caller module does not use the service type.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   542
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   543
    private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   544
        if (!callerModule.canUse(svc)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   545
            fail(svc, callerModule + " does not declare `uses`");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   546
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   547
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   548
        this.service = Objects.requireNonNull(svc);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   549
        this.serviceName = svc.getName();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   550
        this.layer = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   551
        this.loader = cl;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   552
        this.acc = (System.getSecurityManager() != null)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   553
                ? AccessController.getContext()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   554
                : null;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   555
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   556
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   557
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   558
     * Checks that the given service type is accessible to types in the given
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   559
     * module, and check that the module declares that it uses the service type.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   560
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   561
    private static void checkCaller(Class<?> caller, Class<?> svc) {
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   562
        if (caller == null) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   563
            fail(svc, "no caller to check if it declares `uses`");
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   564
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   565
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   566
        // Check access to the service type
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   567
        Module callerModule = caller.getModule();
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   568
        int mods = svc.getModifiers();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   569
        if (!Reflection.verifyMemberAccess(caller, svc, null, mods)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   570
            fail(svc, "service type not accessible to " + callerModule);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   571
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   572
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   573
        // If the caller is in a named module then it should "uses" the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   574
        // service type
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   575
        if (!callerModule.canUse(svc)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   576
            fail(svc, callerModule + " does not declare `uses`");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   577
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   578
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   579
12448
b95438b17098 7157893: Warnings Cleanup in java.util.*
khazra
parents: 9035
diff changeset
   580
    private static void fail(Class<?> service, String msg, Throwable cause)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        throws ServiceConfigurationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        throw new ServiceConfigurationError(service.getName() + ": " + msg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                                            cause);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
12448
b95438b17098 7157893: Warnings Cleanup in java.util.*
khazra
parents: 9035
diff changeset
   587
    private static void fail(Class<?> service, String msg)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        throws ServiceConfigurationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        throw new ServiceConfigurationError(service.getName() + ": " + msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
12448
b95438b17098 7157893: Warnings Cleanup in java.util.*
khazra
parents: 9035
diff changeset
   593
    private static void fail(Class<?> service, URL u, int line, String msg)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        throws ServiceConfigurationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        fail(service, u + ":" + line + ": " + msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   599
    /**
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   600
     * Returns {@code true} if the provider is in an explicit module
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   601
     */
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   602
    private boolean inExplicitModule(Class<?> clazz) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   603
        Module module = clazz.getModule();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   604
        return module.isNamed() && !module.getDescriptor().isAutomatic();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   605
    }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   606
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   607
    /**
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   608
     * Returns the public static "provider" method if found.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   609
     *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   610
     * @throws ServiceConfigurationError if there is an error finding the
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   611
     *         provider method or there is more than one public static
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   612
     *         provider method
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   613
     */
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   614
    private Method findStaticProviderMethod(Class<?> clazz) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   615
        List<Method> methods = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   616
        try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   617
            methods = LANG_ACCESS.getDeclaredPublicMethods(clazz, "provider");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   618
        } catch (Throwable x) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   619
            fail(service, "Unable to get public provider() method", x);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   620
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   621
        if (methods.isEmpty()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   622
            // does not declare a public provider method
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   623
            return null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   624
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   625
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   626
        // locate the static methods, can be at most one
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   627
        Method result = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   628
        for (Method method : methods) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   629
            int mods = method.getModifiers();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   630
            assert Modifier.isPublic(mods);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   631
            if (Modifier.isStatic(mods)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   632
                if (result != null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   633
                    fail(service, clazz + " declares more than one"
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   634
                         + " public static provider() method");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   635
                }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   636
                result = method;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   637
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   639
        if (result != null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   640
            Method m = result;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   641
            PrivilegedAction<Void> pa = () -> {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   642
                m.setAccessible(true);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   643
                return null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   644
            };
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   645
            AccessController.doPrivileged(pa);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   646
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   647
        return result;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   648
    }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   649
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   650
    /**
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   651
     * Returns the public no-arg constructor of a class.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   652
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   653
     * @throws ServiceConfigurationError if the class does not have
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   654
     *         public no-arg constructor
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   655
     */
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   656
    private Constructor<?> getConstructor(Class<?> clazz) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   657
        PrivilegedExceptionAction<Constructor<?>> pa
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   658
            = new PrivilegedExceptionAction<>() {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   659
                @Override
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   660
                public Constructor<?> run() throws Exception {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   661
                    Constructor<?> ctor = clazz.getConstructor();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   662
                    if (inExplicitModule(clazz))
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   663
                        ctor.setAccessible(true);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   664
                    return ctor;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   665
                }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   666
            };
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   667
        Constructor<?> ctor = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   668
        try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   669
            ctor = AccessController.doPrivileged(pa);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   670
        } catch (Throwable x) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   671
            if (x instanceof PrivilegedActionException)
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   672
                x = x.getCause();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   673
            String cn = clazz.getName();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   674
            fail(service, cn + " Unable to get public no-arg constructor", x);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   675
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   676
        return ctor;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   679
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   680
     * A Provider implementation that supports invoking, with reduced
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   681
     * permissions, the static factory to obtain the provider or the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   682
     * provider's no-arg constructor.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   683
     */
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   684
    private static class ProviderImpl<S> implements Provider<S> {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   685
        final Class<S> service;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   686
        final Class<? extends S> type;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   687
        final Method factoryMethod;  // factory method or null
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   688
        final Constructor<? extends S> ctor; // public no-args constructor or null
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   689
        final AccessControlContext acc;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   690
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   691
        ProviderImpl(Class<S> service,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   692
                     Class<? extends S> type,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   693
                     Method factoryMethod,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   694
                     AccessControlContext acc) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   695
            this.service = service;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   696
            this.type = type;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   697
            this.factoryMethod = factoryMethod;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   698
            this.ctor = null;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   699
            this.acc = acc;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   700
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   701
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   702
        ProviderImpl(Class<S> service,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   703
                     Class<? extends S> type,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   704
                     Constructor<? extends S> ctor,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   705
                     AccessControlContext acc) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   706
            this.service = service;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   707
            this.type = type;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   708
            this.factoryMethod = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   709
            this.ctor = ctor;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   710
            this.acc = acc;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   711
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   712
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   713
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   714
        public Class<? extends S> type() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   715
            return type;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   716
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   717
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   718
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   719
        public S get() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   720
            if (factoryMethod != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   721
                return invokeFactoryMethod();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   722
            } else {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   723
                return newInstance();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   724
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   725
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   726
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   727
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   728
         * Invokes the provider's "provider" method to instantiate a provider.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   729
         * When running with a security manager then the method runs with
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   730
         * permissions that are restricted by the security context of whatever
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   731
         * created this loader.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   732
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   733
        private S invokeFactoryMethod() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   734
            Object result = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   735
            Throwable exc = null;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   736
            if (acc == null) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   737
                try {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   738
                    result = factoryMethod.invoke(null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   739
                } catch (Throwable x) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   740
                    exc = x;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   741
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   742
            } else {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   743
                PrivilegedExceptionAction<?> pa = new PrivilegedExceptionAction<>() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   744
                    @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   745
                    public Object run() throws Exception {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   746
                        return factoryMethod.invoke(null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   747
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   748
                };
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   749
                // invoke factory method with permissions restricted by acc
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   750
                try {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   751
                    result = AccessController.doPrivileged(pa, acc);
47345
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   752
                } catch (Throwable x) {
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   753
                    if (x instanceof PrivilegedActionException)
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   754
                        x = x.getCause();
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   755
                    exc = x;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   756
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   757
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   758
            if (exc != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   759
                if (exc instanceof InvocationTargetException)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   760
                    exc = exc.getCause();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   761
                fail(service, factoryMethod + " failed", exc);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   762
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   763
            if (result == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   764
                fail(service, factoryMethod + " returned null");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   765
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   766
            @SuppressWarnings("unchecked")
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   767
            S p = (S) result;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   768
            return p;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   769
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   770
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   771
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   772
         * Invokes Constructor::newInstance to instantiate a provider. When running
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   773
         * with a security manager then the constructor runs with permissions that
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   774
         * are restricted by the security context of whatever created this loader.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   775
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   776
        private S newInstance() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   777
            S p = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   778
            Throwable exc = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   779
            if (acc == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   780
                try {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   781
                    p = ctor.newInstance();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   782
                } catch (Throwable x) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   783
                    exc = x;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   784
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   785
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   786
                PrivilegedExceptionAction<S> pa = new PrivilegedExceptionAction<>() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   787
                    @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   788
                    public S run() throws Exception {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   789
                        return ctor.newInstance();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   790
                    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   791
                };
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   792
                // invoke constructor with permissions restricted by acc
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   793
                try {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   794
                    p = AccessController.doPrivileged(pa, acc);
47345
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   795
                } catch (Throwable x) {
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   796
                    if (x instanceof PrivilegedActionException)
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   797
                        x = x.getCause();
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   798
                    exc = x;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   799
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   800
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   801
            if (exc != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   802
                if (exc instanceof InvocationTargetException)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   803
                    exc = exc.getCause();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   804
                String cn = ctor.getDeclaringClass().getName();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   805
                fail(service,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   806
                     "Provider " + cn + " could not be instantiated", exc);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   807
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   808
            return p;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   809
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   810
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   811
        // For now, equals/hashCode uses the access control context to ensure
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   812
        // that two Providers created with different contexts are not equal
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   813
        // when running with a security manager.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   814
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   815
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   816
        public int hashCode() {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   817
            return Objects.hash(service, type, acc);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   818
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   819
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   820
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   821
        public boolean equals(Object ob) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   822
            if (!(ob instanceof ProviderImpl))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   823
                return false;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   824
            @SuppressWarnings("unchecked")
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   825
            ProviderImpl<?> that = (ProviderImpl<?>)ob;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   826
            return this.service == that.service
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   827
                    && this.type == that.type
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   828
                    && Objects.equals(this.acc, that.acc);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   829
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   830
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   831
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   832
    /**
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   833
     * Loads a service provider in a module.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   834
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   835
     * Returns {@code null} if the service provider's module doesn't read
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   836
     * the module with the service type.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   837
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   838
     * @throws ServiceConfigurationError if the class cannot be loaded or
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   839
     *         isn't the expected sub-type (or doesn't define a provider
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   840
     *         factory method that returns the expected type)
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   841
     */
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   842
    private Provider<S> loadProvider(ServiceProvider provider) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   843
        Module module = provider.module();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   844
        if (!module.canRead(service.getModule())) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   845
            // module does not read the module with the service type
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   846
            return null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   847
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   848
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   849
        String cn = provider.providerName();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   850
        Class<?> clazz = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   851
        if (acc == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   852
            try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   853
                clazz = Class.forName(module, cn);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   854
            } catch (LinkageError e) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   855
                fail(service, "Unable to load " + cn, e);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   856
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   857
        } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   858
            PrivilegedExceptionAction<Class<?>> pa = () -> Class.forName(module, cn);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   859
            try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   860
                clazz = AccessController.doPrivileged(pa);
47345
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   861
            } catch (Throwable x) {
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   862
                if (x instanceof PrivilegedActionException)
0a1fc9f3779c 8189264: (sl) ServiceLoader does not wrap Errors thrown by provider classes when running with a security manager
alanb
parents: 47335
diff changeset
   863
                    x = x.getCause();
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   864
                fail(service, "Unable to load " + cn, x);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   865
                return null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   866
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   867
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   868
        if (clazz == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   869
            fail(service, "Provider " + cn + " not found");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   870
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   871
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   872
        int mods = clazz.getModifiers();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   873
        if (!Modifier.isPublic(mods)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   874
            fail(service, clazz + " is not public");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   875
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   876
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   877
        // if provider in explicit module then check for static factory method
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   878
        if (inExplicitModule(clazz)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   879
            Method factoryMethod = findStaticProviderMethod(clazz);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   880
            if (factoryMethod != null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   881
                Class<?> returnType = factoryMethod.getReturnType();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   882
                if (!service.isAssignableFrom(returnType)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   883
                    fail(service, factoryMethod + " return type not a subtype");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   884
                }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   885
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   886
                @SuppressWarnings("unchecked")
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   887
                Class<? extends S> type = (Class<? extends S>) returnType;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   888
                return new ProviderImpl<S>(service, type, factoryMethod, acc);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   889
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   890
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   891
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   892
        // no factory method so must be a subtype
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   893
        if (!service.isAssignableFrom(clazz)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   894
            fail(service, clazz.getName() + " not a subtype");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   895
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   896
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   897
        @SuppressWarnings("unchecked")
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   898
        Class<? extends S> type = (Class<? extends S>) clazz;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   899
        @SuppressWarnings("unchecked")
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   900
        Constructor<? extends S> ctor = (Constructor<? extends S> ) getConstructor(clazz);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   901
        return new ProviderImpl<S>(service, type, ctor, acc);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   902
    }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   903
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   904
    /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   905
     * Implements lazy service provider lookup of service providers that
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   906
     * are provided by modules in a module layer (or parent layers)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   907
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   908
    private final class LayerLookupIterator<T>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   909
        implements Iterator<Provider<T>>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   910
    {
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   911
        Deque<ModuleLayer> stack = new ArrayDeque<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   912
        Set<ModuleLayer> visited = new HashSet<>();
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   913
        Iterator<ServiceProvider> iterator;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   914
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   915
        Provider<T> nextProvider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   916
        ServiceConfigurationError nextError;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   918
        LayerLookupIterator() {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   919
            visited.add(layer);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   920
            stack.push(layer);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   921
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   922
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   923
        private Iterator<ServiceProvider> providers(ModuleLayer layer) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
   924
            ServicesCatalog catalog = LANG_ACCESS.getServicesCatalog(layer);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   925
            return catalog.findServices(serviceName).iterator();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   926
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   927
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   928
        @Override
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   929
        public boolean hasNext() {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   930
            while (nextProvider == null && nextError == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   931
                // get next provider to load
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   932
                while (iterator == null || !iterator.hasNext()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   933
                    // next layer (DFS order)
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   934
                    if (stack.isEmpty())
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   935
                        return false;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   936
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   937
                    ModuleLayer layer = stack.pop();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   938
                    List<ModuleLayer> parents = layer.parents();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   939
                    for (int i = parents.size() - 1; i >= 0; i--) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   940
                        ModuleLayer parent = parents.get(i);
51703
4ffb0a33f265 8210347: Combine subsequent calls to Set.contains() and Set.add()
igerasim
parents: 51111
diff changeset
   941
                        if (visited.add(parent)) {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   942
                            stack.push(parent);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   943
                        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   944
                    }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   945
                    iterator = providers(layer);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   946
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   947
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   948
                // attempt to load provider
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   949
                ServiceProvider provider = iterator.next();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   950
                try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   951
                    @SuppressWarnings("unchecked")
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   952
                    Provider<T> next = (Provider<T>) loadProvider(provider);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   953
                    nextProvider = next;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   954
                } catch (ServiceConfigurationError e) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   955
                    nextError = e;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   956
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   957
            }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   958
            return true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   961
        @Override
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   962
        public Provider<T> next() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   963
            if (!hasNext())
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   964
                throw new NoSuchElementException();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   965
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   966
            Provider<T> provider = nextProvider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   967
            if (provider != null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   968
                nextProvider = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   969
                return provider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   970
            } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   971
                ServiceConfigurationError e = nextError;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   972
                assert e != null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   973
                nextError = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   974
                throw e;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   975
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   976
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   977
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   978
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   979
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   980
     * Implements lazy service provider lookup of service providers that
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   981
     * are provided by modules defined to a class loader or to modules in
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   982
     * layers with a module defined to the class loader.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   983
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   984
    private final class ModuleServicesLookupIterator<T>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   985
        implements Iterator<Provider<T>>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   986
    {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   987
        ClassLoader currentLoader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   988
        Iterator<ServiceProvider> iterator;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   989
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   990
        Provider<T> nextProvider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
   991
        ServiceConfigurationError nextError;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   992
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   993
        ModuleServicesLookupIterator() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   994
            this.currentLoader = loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   995
            this.iterator = iteratorFor(loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   996
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   997
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
   998
        /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
   999
         * Returns iterator to iterate over the implementations of {@code
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1000
         * service} in the given layer.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1001
         */
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
  1002
        private List<ServiceProvider> providers(ModuleLayer layer) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
  1003
            ServicesCatalog catalog = LANG_ACCESS.getServicesCatalog(layer);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1004
            return catalog.findServices(serviceName);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1005
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1006
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1007
        /**
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1008
         * Returns the class loader that a module is defined to
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1009
         */
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1010
        private ClassLoader loaderFor(Module module) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1011
            SecurityManager sm = System.getSecurityManager();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1012
            if (sm == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1013
                return module.getClassLoader();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1014
            } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1015
                PrivilegedAction<ClassLoader> pa = module::getClassLoader;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1016
                return AccessController.doPrivileged(pa);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1017
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1018
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1019
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1020
        /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1021
         * Returns an iterator to iterate over the implementations of {@code
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1022
         * service} in modules defined to the given class loader or in custom
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1023
         * layers with a module defined to this class loader.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1024
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1025
        private Iterator<ServiceProvider> iteratorFor(ClassLoader loader) {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1026
            // modules defined to the class loader
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1027
            ServicesCatalog catalog;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1028
            if (loader == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1029
                catalog = BootLoader.getServicesCatalog();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1030
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1031
                catalog = ServicesCatalog.getServicesCatalogOrNull(loader);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1032
            }
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1033
            List<ServiceProvider> providers;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1034
            if (catalog == null) {
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1035
                providers = List.of();
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1036
            } else {
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1037
                providers = catalog.findServices(serviceName);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1038
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1039
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1040
            // modules in layers that define modules to the class loader
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1041
            ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1042
            if (loader == null || loader == platformClassLoader) {
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1043
                return providers.iterator();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1044
            } else {
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1045
                List<ServiceProvider> allProviders = new ArrayList<>(providers);
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
  1046
                Iterator<ModuleLayer> iterator = LANG_ACCESS.layers(loader).iterator();
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1047
                while (iterator.hasNext()) {
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
  1048
                    ModuleLayer layer = iterator.next();
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1049
                    for (ServiceProvider sp : providers(layer)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1050
                        ClassLoader l = loaderFor(sp.module());
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1051
                        if (l != null && l != platformClassLoader) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1052
                            allProviders.add(sp);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1053
                        }
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1054
                    }
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1055
                }
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1056
                return allProviders.iterator();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1057
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1058
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1059
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1060
        @Override
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1061
        public boolean hasNext() {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1062
            while (nextProvider == null && nextError == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1063
                // get next provider to load
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1064
                while (!iterator.hasNext()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1065
                    if (currentLoader == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1066
                        return false;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1067
                    } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1068
                        currentLoader = currentLoader.getParent();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1069
                        iterator = iteratorFor(currentLoader);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1070
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1071
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1072
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1073
                // attempt to load provider
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1074
                ServiceProvider provider = iterator.next();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1075
                try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1076
                    @SuppressWarnings("unchecked")
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1077
                    Provider<T> next = (Provider<T>) loadProvider(provider);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1078
                    nextProvider = next;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1079
                } catch (ServiceConfigurationError e) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1080
                    nextError = e;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1081
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1082
            }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1083
            return true;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1084
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1085
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1086
        @Override
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1087
        public Provider<T> next() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1088
            if (!hasNext())
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1089
                throw new NoSuchElementException();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1090
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1091
            Provider<T> provider = nextProvider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1092
            if (provider != null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1093
                nextProvider = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1094
                return provider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1095
            } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1096
                ServiceConfigurationError e = nextError;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1097
                assert e != null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1098
                nextError = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1099
                throw e;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1100
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1101
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1102
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1103
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1104
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1105
     * Implements lazy service provider lookup where the service providers are
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1106
     * configured via service configuration files. Service providers in named
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1107
     * modules are silently ignored by this lookup iterator.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1108
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1109
    private final class LazyClassPathLookupIterator<T>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1110
        implements Iterator<Provider<T>>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1111
    {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1112
        static final String PREFIX = "META-INF/services/";
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1113
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 44003
diff changeset
  1114
        Set<String> providerNames = new HashSet<>();  // to avoid duplicates
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1115
        Enumeration<URL> configs;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1116
        Iterator<String> pending;
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1117
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1118
        Provider<T> nextProvider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1119
        ServiceConfigurationError nextError;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1120
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1121
        LazyClassPathLookupIterator() { }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1122
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1123
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1124
         * Parse a single line from the given configuration file, adding the
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 44003
diff changeset
  1125
         * name on the line to set of names if not already seen.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1126
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1127
        private int parseLine(URL u, BufferedReader r, int lc, Set<String> names)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1128
            throws IOException
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1129
        {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1130
            String ln = r.readLine();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1131
            if (ln == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1132
                return -1;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1133
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1134
            int ci = ln.indexOf('#');
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1135
            if (ci >= 0) ln = ln.substring(0, ci);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1136
            ln = ln.trim();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1137
            int n = ln.length();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1138
            if (n != 0) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1139
                if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1140
                    fail(service, u, lc, "Illegal configuration-file syntax");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1141
                int cp = ln.codePointAt(0);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1142
                if (!Character.isJavaIdentifierStart(cp))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1143
                    fail(service, u, lc, "Illegal provider-class name: " + ln);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1144
                int start = Character.charCount(cp);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1145
                for (int i = start; i < n; i += Character.charCount(cp)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1146
                    cp = ln.codePointAt(i);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1147
                    if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1148
                        fail(service, u, lc, "Illegal provider-class name: " + ln);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1149
                }
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 44003
diff changeset
  1150
                if (providerNames.add(ln)) {
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 44003
diff changeset
  1151
                    names.add(ln);
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 44003
diff changeset
  1152
                }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1153
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1154
            return lc + 1;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1155
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1156
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1157
        /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1158
         * Parse the content of the given URL as a provider-configuration file.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1159
         */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1160
        private Iterator<String> parse(URL u) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1161
            Set<String> names = new LinkedHashSet<>(); // preserve insertion order
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1162
            try {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1163
                URLConnection uc = u.openConnection();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1164
                uc.setUseCaches(false);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1165
                try (InputStream in = uc.getInputStream();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1166
                     BufferedReader r
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1167
                         = new BufferedReader(new InputStreamReader(in, "utf-8")))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1168
                {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1169
                    int lc = 1;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1170
                    while ((lc = parseLine(u, r, lc, names)) >= 0);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1171
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1172
            } catch (IOException x) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1173
                fail(service, "Error accessing configuration file", x);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1174
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1175
            return names.iterator();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1176
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1177
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1178
        /**
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1179
         * Loads and returns the next provider class.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1180
         */
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1181
        private Class<?> nextProviderClass() {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1182
            if (configs == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1183
                try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1184
                    String fullName = PREFIX + service.getName();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1185
                    if (loader == null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1186
                        configs = ClassLoader.getSystemResources(fullName);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1187
                    } else if (loader == ClassLoaders.platformClassLoader()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1188
                        // The platform classloader doesn't have a class path,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1189
                        // but the boot loader might.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1190
                        if (BootLoader.hasClassPath()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1191
                            configs = BootLoader.findResources(fullName);
44003
dc26a57d2570 8175385: ServiceLoader$LazyClassPathLookupIterator scans boot and platform modules for services
redestad
parents: 43712
diff changeset
  1192
                        } else {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1193
                            configs = Collections.emptyEnumeration();
44003
dc26a57d2570 8175385: ServiceLoader$LazyClassPathLookupIterator scans boot and platform modules for services
redestad
parents: 43712
diff changeset
  1194
                        }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1195
                    } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1196
                        configs = loader.getResources(fullName);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1197
                    }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1198
                } catch (IOException x) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1199
                    fail(service, "Error locating configuration files", x);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1200
                }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1201
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1202
            while ((pending == null) || !pending.hasNext()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1203
                if (!configs.hasMoreElements()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1204
                    return null;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1205
                }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1206
                pending = parse(configs.nextElement());
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1207
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1208
            String cn = pending.next();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1209
            try {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1210
                return Class.forName(cn, false, loader);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1211
            } catch (ClassNotFoundException x) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1212
                fail(service, "Provider " + cn + " not found");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1213
                return null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1214
            }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1215
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1216
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1217
        @SuppressWarnings("unchecked")
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1218
        private boolean hasNextService() {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1219
            while (nextProvider == null && nextError == null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
                try {
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1221
                    Class<?> clazz = nextProviderClass();
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1222
                    if (clazz == null)
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1223
                        return false;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1224
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1225
                    if (clazz.getModule().isNamed()) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1226
                        // ignore class if in named module
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1227
                        continue;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1228
                    }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1229
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1230
                    if (service.isAssignableFrom(clazz)) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1231
                        Class<? extends S> type = (Class<? extends S>) clazz;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1232
                        Constructor<? extends S> ctor
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1233
                            = (Constructor<? extends S>)getConstructor(clazz);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1234
                        ProviderImpl<S> p = new ProviderImpl<S>(service, type, ctor, acc);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1235
                        nextProvider = (ProviderImpl<T>) p;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1236
                    } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1237
                        fail(service, clazz.getName() + " not a subtype");
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1238
                    }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1239
                } catch (ServiceConfigurationError e) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1240
                    nextError = e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
                }
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1242
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1246
        private Provider<T> nextService() {
18777
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
  1247
            if (!hasNextService())
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                throw new NoSuchElementException();
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1249
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1250
            Provider<T> provider = nextProvider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1251
            if (provider != null) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1252
                nextProvider = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1253
                return provider;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1254
            } else {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1255
                ServiceConfigurationError e = nextError;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1256
                assert e != null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1257
                nextError = null;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1258
                throw e;
14218
c6f2434dd88d 7195919: (sl) ServiceLoader can throw CCE without needing to create instance
smarks
parents: 12448
diff changeset
  1259
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1260
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1261
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1262
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1263
        public boolean hasNext() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1264
            if (acc == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1265
                return hasNextService();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1266
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1267
                PrivilegedAction<Boolean> action = new PrivilegedAction<>() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1268
                    public Boolean run() { return hasNextService(); }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1269
                };
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1270
                return AccessController.doPrivileged(action, acc);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1272
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1273
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1274
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1275
        public Provider<T> next() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1276
            if (acc == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1277
                return nextService();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1278
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1279
                PrivilegedAction<Provider<T>> action = new PrivilegedAction<>() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1280
                    public Provider<T> run() { return nextService(); }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1281
                };
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1282
                return AccessController.doPrivileged(action, acc);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1283
            }
18777
cb1cc62972b8 8019622: (sl) ServiceLoader.next incorrect when creation and usages are in different contexts
alanb
parents: 14229
diff changeset
  1284
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1288
     * Returns a new lookup iterator.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1289
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1290
    private Iterator<Provider<S>> newLookupIterator() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1291
        assert layer == null || loader == null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1292
        if (layer != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1293
            return new LayerLookupIterator<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1294
        } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1295
            Iterator<Provider<S>> first = new ModuleServicesLookupIterator<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1296
            Iterator<Provider<S>> second = new LazyClassPathLookupIterator<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1297
            return new Iterator<Provider<S>>() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1298
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1299
                public boolean hasNext() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1300
                    return (first.hasNext() || second.hasNext());
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1301
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1302
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1303
                public Provider<S> next() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1304
                    if (first.hasNext()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1305
                        return first.next();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1306
                    } else if (second.hasNext()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1307
                        return second.next();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1308
                    } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1309
                        throw new NoSuchElementException();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1310
                    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1311
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1312
            };
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1313
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1314
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1315
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1316
    /**
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1317
     * Returns an iterator to lazily load and instantiate the available
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1318
     * providers of this loader's service.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1320
     * <p> To achieve laziness the actual work of locating and instantiating
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1321
     * providers is done by the iterator itself. Its {@link Iterator#hasNext
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1322
     * hasNext} and {@link Iterator#next next} methods can therefore throw a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1323
     * {@link ServiceConfigurationError} for any of the reasons specified in
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1324
     * the <a href="#errors">Errors</a> section above. To write robust code it
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1325
     * is only necessary to catch {@code ServiceConfigurationError} when using
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1326
     * the iterator. If an error is thrown then subsequent invocations of the
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
     * iterator will make a best effort to locate and instantiate the next
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
     * available provider, but in general such recovery cannot be guaranteed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1330
     * <p> Caching: The iterator returned by this method first yields all of
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1331
     * the elements of the provider cache, in the order that they were loaded.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1332
     * It then lazily loads and instantiates any remaining service providers,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1333
     * adding each one to the cache in turn. If this loader's provider caches are
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1334
     * cleared by invoking the {@link #reload() reload} method then existing
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1335
     * iterators for this service loader should be discarded.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1336
     * The {@code  hasNext} and {@code next} methods of the iterator throw {@link
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1337
     * java.util.ConcurrentModificationException ConcurrentModificationException}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1338
     * if used after the provider cache has been cleared.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1339
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
     * <p> The iterator returned by this method does not support removal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
     * Invoking its {@link java.util.Iterator#remove() remove} method will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
     * cause an {@link UnsupportedOperationException} to be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1344
     * @apiNote Throwing an error in these cases may seem extreme.  The rationale
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1345
     * for this behavior is that a malformed provider-configuration file, like a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1346
     * malformed class file, indicates a serious problem with the way the Java
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1347
     * virtual machine is configured or is being used.  As such it is preferable
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1348
     * to throw an error rather than try to recover or, even worse, fail silently.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1349
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
     * @return  An iterator that lazily loads providers for this loader's
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
     *          service
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1352
     *
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1353
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1354
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
    public Iterator<S> iterator() {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1357
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1358
        // create lookup iterator if needed
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1359
        if (lookupIterator1 == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1360
            lookupIterator1 = newLookupIterator();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1361
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1362
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
        return new Iterator<S>() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1365
            // record reload count
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1366
            final int expectedReloadCount = ServiceLoader.this.reloadCount;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1367
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1368
            // index into the cached providers list
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1369
            int index;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1370
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1371
            /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1372
             * Throws ConcurrentModificationException if the list of cached
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1373
             * providers has been cleared by reload.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1374
             */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1375
            private void checkReloadCount() {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1376
                if (ServiceLoader.this.reloadCount != expectedReloadCount)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1377
                    throw new ConcurrentModificationException();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1378
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1380
            @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
            public boolean hasNext() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1382
                checkReloadCount();
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1383
                if (index < instantiatedProviders.size())
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
                    return true;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1385
                return lookupIterator1.hasNext();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1388
            @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
            public S next() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1390
                checkReloadCount();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1391
                S next;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1392
                if (index < instantiatedProviders.size()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1393
                    next = instantiatedProviders.get(index);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1394
                } else {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1395
                    next = lookupIterator1.next().get();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1396
                    instantiatedProviders.add(next);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1397
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1398
                index++;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1399
                return next;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
        };
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
    /**
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1406
     * Returns a stream to lazily load available providers of this loader's
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1407
     * service. The stream elements are of type {@link Provider Provider}, the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1408
     * {@code Provider}'s {@link Provider#get() get} method must be invoked to
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1409
     * get or instantiate the provider.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1410
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1411
     * <p> To achieve laziness the actual work of locating providers is done
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1412
     * when processing the stream. If a service provider cannot be loaded for any
47471
304ef03403b1 8190323: "the the" typos
rriggs
parents: 47345
diff changeset
  1413
     * of the reasons specified in the <a href="#errors">Errors</a> section
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1414
     * above then {@link ServiceConfigurationError} is thrown by whatever method
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1415
     * caused the service provider to be loaded. </p>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1416
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1417
     * <p> Caching: When processing the stream then providers that were previously
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1418
     * loaded by stream operations are processed first, in load order. It then
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1419
     * lazily loads any remaining service providers. If this loader's provider
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1420
     * caches are cleared by invoking the {@link #reload() reload} method then
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1421
     * existing streams for this service loader should be discarded. The returned
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1422
     * stream's source {@link Spliterator spliterator} is <em>fail-fast</em> and
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1423
     * will throw {@link ConcurrentModificationException} if the provider cache
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1424
     * has been cleared. </p>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1425
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1426
     * <p> The following examples demonstrate usage. The first example creates
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1427
     * a stream of {@code CodecFactory} objects, the second example is the same
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1428
     * except that it sorts the providers by provider class name (and so locate
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1429
     * all providers).
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1430
     * <pre>{@code
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1431
     *    Stream<CodecFactory> providers = ServiceLoader.load(CodecFactory.class)
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1432
     *            .stream()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1433
     *            .map(Provider::get);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1434
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1435
     *    Stream<CodecFactory> providers = ServiceLoader.load(CodecFactory.class)
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1436
     *            .stream()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1437
     *            .sorted(Comparator.comparing(p -> p.type().getName()))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1438
     *            .map(Provider::get);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1439
     * }</pre>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1440
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1441
     * @return  A stream that lazily loads providers for this loader's service
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1442
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1443
     * @since 9
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1444
     * @spec JPMS
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1445
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1446
    public Stream<Provider<S>> stream() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1447
        // use cached providers as the source when all providers loaded
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1448
        if (loadedAllProviders) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1449
            return loadedProviders.stream();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1450
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1451
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1452
        // create lookup iterator if needed
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1453
        if (lookupIterator2 == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1454
            lookupIterator2 = newLookupIterator();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1455
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1456
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1457
        // use lookup iterator and cached providers as source
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1458
        Spliterator<Provider<S>> s = new ProviderSpliterator<>(lookupIterator2);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1459
        return StreamSupport.stream(s, false);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1460
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1461
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1462
    private class ProviderSpliterator<T> implements Spliterator<Provider<T>> {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1463
        final int expectedReloadCount = ServiceLoader.this.reloadCount;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1464
        final Iterator<Provider<T>> iterator;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1465
        int index;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1466
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1467
        ProviderSpliterator(Iterator<Provider<T>> iterator) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1468
            this.iterator = iterator;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1469
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1470
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1471
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1472
        public Spliterator<Provider<T>> trySplit() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1473
            return null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1474
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1475
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1476
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1477
        @SuppressWarnings("unchecked")
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1478
        public boolean tryAdvance(Consumer<? super Provider<T>> action) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1479
            if (ServiceLoader.this.reloadCount != expectedReloadCount)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1480
                throw new ConcurrentModificationException();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1481
            Provider<T> next = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1482
            if (index < loadedProviders.size()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1483
                next = (Provider<T>) loadedProviders.get(index++);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1484
            } else if (iterator.hasNext()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1485
                next = iterator.next();
47335
e8bd8e969070 8186738: (sl) ServiceLoader::stream doesn't update cache
alanb
parents: 47216
diff changeset
  1486
                loadedProviders.add((Provider<S>)next);
e8bd8e969070 8186738: (sl) ServiceLoader::stream doesn't update cache
alanb
parents: 47216
diff changeset
  1487
                index++;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1488
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1489
                loadedAllProviders = true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1490
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1491
            if (next != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1492
                action.accept(next);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1493
                return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1494
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1495
                return false;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1496
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1497
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1498
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1499
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1500
        public int characteristics() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1501
            // not IMMUTABLE as structural interference possible
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1502
            // not NOTNULL so that the characteristics are a subset of the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1503
            // characteristics when all Providers have been located.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1504
            return Spliterator.ORDERED;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1505
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1506
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1507
        @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1508
        public long estimateSize() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1509
            return Long.MAX_VALUE;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1510
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1511
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1512
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1513
    /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1514
     * Creates a new service loader for the given service type, class
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1515
     * loader, and caller.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1516
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1517
     * @param  <S> the class of the service type
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1518
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1519
     * @param  service
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1520
     *         The interface or abstract class representing the service
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1521
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1522
     * @param  loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1523
     *         The class loader to be used to load provider-configuration files
44848
e946981dc37c 8179370: Replace use of <tt>, <center> and <font> tags in java.base
jjg
parents: 44545
diff changeset
  1524
     *         and provider classes, or {@code null} if the system class
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1525
     *         loader (or, failing that, the bootstrap class loader) is to be
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1526
     *         used
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1527
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1528
     * @param  callerModule
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1529
     *         The caller's module for which a new service loader is created
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1530
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1531
     * @return A new service loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1532
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1533
    static <S> ServiceLoader<S> load(Class<S> service,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1534
                                     ClassLoader loader,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1535
                                     Module callerModule)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1536
    {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1537
        return new ServiceLoader<>(callerModule, service, loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1538
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1539
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1540
    /**
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1541
     * Creates a new service loader for the given service. The service loader
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1542
     * uses the given class loader as the starting point to locate service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1543
     * providers for the service. The service loader's {@link #iterator()
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1544
     * iterator} and {@link #stream() stream} locate providers in both named
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1545
     * and unnamed modules, as follows:
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1546
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1547
     * <ul>
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1548
     *   <li> <p> Step 1: Locate providers in named modules. </p>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1549
     *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1550
     *   <p> Service providers are located in all named modules of the class
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1551
     *   loader or to any class loader reachable via parent delegation. </p>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1552
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1553
     *   <p> In addition, if the class loader is not the bootstrap or {@linkplain
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1554
     *   ClassLoader#getPlatformClassLoader() platform class loader}, then service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1555
     *   providers may be located in the named modules of other class loaders.
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1556
     *   Specifically, if the class loader, or any class loader reachable via
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1557
     *   parent delegation, has a module in a {@linkplain ModuleLayer module
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1558
     *   layer}, then service providers in all modules in the module layer are
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1559
     *   located.  </p>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1560
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1561
     *   <p> For example, suppose there is a module layer where each module is
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1562
     *   in its own class loader (see {@link ModuleLayer#defineModulesWithManyLoaders
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1563
     *   defineModulesWithManyLoaders}). If this {@code ServiceLoader.load} method
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1564
     *   is invoked to locate providers using any of the class loaders created for
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1565
     *   the module layer, then it will locate all of the providers in the module
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1566
     *   layer, irrespective of their defining class loader. </p>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1567
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1568
     *   <p> Ordering: The service loader will first locate any service providers
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1569
     *   in modules defined to the class loader, then its parent class loader,
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1570
     *   its parent parent, and so on to the bootstrap class loader. If a class
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1571
     *   loader has modules in a module layer then all providers in that module
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1572
     *   layer are located (irrespective of their class loader) before the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1573
     *   providers in the parent class loader are located. The ordering of
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1574
     *   modules in same class loader, or the ordering of modules in a module
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1575
     *   layer, is not defined. </p>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1576
     *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1577
     *   <p> If a module declares more than one provider then the providers
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1578
     *   are located in the order that its module descriptor {@linkplain
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1579
     *   java.lang.module.ModuleDescriptor.Provides#providers() lists the
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1580
     *   providers}. Providers added dynamically by instrumentation agents (see
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1581
     *   {@link java.lang.instrument.Instrumentation#redefineModule redefineModule})
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1582
     *   are always located after providers declared by the module. </p> </li>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1583
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1584
     *   <li> <p> Step 2: Locate providers in unnamed modules. </p>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1585
     *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1586
     *   <p> Service providers in unnamed modules are located if their class names
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1587
     *   are listed in provider-configuration files located by the class loader's
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1588
     *   {@link ClassLoader#getResources(String) getResources} method. </p>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1589
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1590
     *   <p> The ordering is based on the order that the class loader's {@code
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1591
     *   getResources} method finds the service configuration files and within
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1592
     *   that, the order that the class names are listed in the file. </p>
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1593
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1594
     *   <p> In a provider-configuration file, any mention of a service provider
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1595
     *   that is deployed in a named module is ignored. This is to avoid
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1596
     *   duplicates that would otherwise arise when a named module has both a
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1597
     *   <i>provides</i> directive and a provider-configuration file that mention
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1598
     *   the same service provider. </p>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1599
     *
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1600
     *   <p> The provider class must be visible to the class loader. </p> </li>
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1601
     *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1602
     * </ul>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1603
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1604
     * @apiNote If the class path of the class loader includes remote network
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1605
     * URLs then those URLs may be dereferenced in the process of searching for
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1606
     * provider-configuration files.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1607
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1608
     * <p> This activity is normal, although it may cause puzzling entries to be
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1609
     * created in web-server logs.  If a web server is not configured correctly,
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1610
     * however, then this activity may cause the provider-loading algorithm to fail
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1611
     * spuriously.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1612
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1613
     * <p> A web server should return an HTTP 404 (Not Found) response when a
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1614
     * requested resource does not exist.  Sometimes, however, web servers are
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1615
     * erroneously configured to return an HTTP 200 (OK) response along with a
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1616
     * helpful HTML error page in such cases.  This will cause a {@link
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1617
     * ServiceConfigurationError} to be thrown when this class attempts to parse
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1618
     * the HTML page as a provider-configuration file.  The best solution to this
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1619
     * problem is to fix the misconfigured web server to return the correct
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1620
     * response code (HTTP 404) along with the HTML error page.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
     *
19074
84a8d23e8f32 8020539: Clean up doclint problems in java.util package, part 2
bpb
parents: 18777
diff changeset
  1622
     * @param  <S> the class of the service type
84a8d23e8f32 8020539: Clean up doclint problems in java.util package, part 2
bpb
parents: 18777
diff changeset
  1623
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
     * @param  service
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
     *         The interface or abstract class representing the service
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
     * @param  loader
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
     *         The class loader to be used to load provider-configuration files
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1629
     *         and provider classes, or {@code null} if the system class
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
     *         loader (or, failing that, the bootstrap class loader) is to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
     *         used
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
     * @return A new service loader
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1634
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1635
     * @throws ServiceConfigurationError
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1636
     *         if the service type is not accessible to the caller or the
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1637
     *         caller is in an explicit module and its module descriptor does
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1638
     *         not declare that it uses {@code service}
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1639
     *
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1640
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1641
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
     */
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1643
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
    public static <S> ServiceLoader<S> load(Class<S> service,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                                            ClassLoader loader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
    {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1647
        return new ServiceLoader<>(Reflection.getCallerClass(), service, loader);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
     * Creates a new service loader for the given service type, using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
     * current thread's {@linkplain java.lang.Thread#getContextClassLoader
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
     * context class loader}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
     * <p> An invocation of this convenience method of the form
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1656
     * <pre>{@code
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1657
     *     ServiceLoader.load(service)
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1658
     * }</pre>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
     * is equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1662
     * <pre>{@code
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1663
     *     ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1664
     * }</pre>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1665
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1666
     * @apiNote Service loader objects obtained with this method should not be
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1667
     * cached VM-wide. For example, different applications in the same VM may
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1668
     * have different thread context class loaders. A lookup by one application
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1669
     * may locate a service provider that is only visible via its thread
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1670
     * context class loader and so is not suitable to be located by the other
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1671
     * application. Memory leaks can also arise. A thread local may be suited
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1672
     * to some applications.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
     *
19074
84a8d23e8f32 8020539: Clean up doclint problems in java.util package, part 2
bpb
parents: 18777
diff changeset
  1674
     * @param  <S> the class of the service type
84a8d23e8f32 8020539: Clean up doclint problems in java.util package, part 2
bpb
parents: 18777
diff changeset
  1675
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
     * @param  service
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
     *         The interface or abstract class representing the service
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
     * @return A new service loader
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1680
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1681
     * @throws ServiceConfigurationError
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1682
     *         if the service type is not accessible to the caller or the
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1683
     *         caller is in an explicit module and its module descriptor does
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1684
     *         not declare that it uses {@code service}
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1685
     *
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1686
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1687
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
     */
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1689
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
    public static <S> ServiceLoader<S> load(Class<S> service) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1692
        return new ServiceLoader<>(Reflection.getCallerClass(), service, cl);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
     * Creates a new service loader for the given service type, using the
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1697
     * {@linkplain ClassLoader#getPlatformClassLoader() platform class loader}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1699
     * <p> This convenience method is equivalent to: </p>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1701
     * <pre>{@code
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1702
     *     ServiceLoader.load(service, ClassLoader.getPlatformClassLoader())
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1703
     * }</pre>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
     * <p> This method is intended for use when only installed providers are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
     * desired.  The resulting service will only find and load providers that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
     * have been installed into the current Java virtual machine; providers on
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1708
     * the application's module path or class path will be ignored.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
     *
19074
84a8d23e8f32 8020539: Clean up doclint problems in java.util package, part 2
bpb
parents: 18777
diff changeset
  1710
     * @param  <S> the class of the service type
84a8d23e8f32 8020539: Clean up doclint problems in java.util package, part 2
bpb
parents: 18777
diff changeset
  1711
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
     * @param  service
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
     *         The interface or abstract class representing the service
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
     * @return A new service loader
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1716
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1717
     * @throws ServiceConfigurationError
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1718
     *         if the service type is not accessible to the caller or the
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1719
     *         caller is in an explicit module and its module descriptor does
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1720
     *         not declare that it uses {@code service}
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1721
     *
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1722
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1723
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
     */
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1725
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
    public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1727
        ClassLoader cl = ClassLoader.getPlatformClassLoader();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1728
        return new ServiceLoader<>(Reflection.getCallerClass(), service, cl);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1729
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1730
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1731
    /**
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1732
     * Creates a new service loader for the given service type to load service
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1733
     * providers from modules in the given module layer and its ancestors. It
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1734
     * does not locate providers in unnamed modules. The ordering that the service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1735
     * loader's {@link #iterator() iterator} and {@link #stream() stream} locate
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1736
     * providers and yield elements is as follows:
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1737
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1738
     * <ul>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1739
     *   <li><p> Providers are located in a module layer before locating providers
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1740
     *   in parent layers. Traversal of parent layers is depth-first with each
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1741
     *   layer visited at most once. For example, suppose L0 is the boot layer, L1
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1742
     *   and L2 are modules layers with L0 as their parent. Now suppose that L3 is
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1743
     *   created with L1 and L2 as the parents (in that order). Using a service
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1744
     *   loader to locate providers with L3 as the context will locate providers
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1745
     *   in the following order: L3, L1, L0, L2. </p></li>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1746
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1747
     *   <li><p> If a module declares more than one provider then the providers
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1748
     *   are located in the order that its module descriptor
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1749
     *   {@linkplain java.lang.module.ModuleDescriptor.Provides#providers()
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1750
     *   lists the providers}. Providers added dynamically by instrumentation
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1751
     *   agents are always located after providers declared by the module. </p></li>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1752
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1753
     *   <li><p> The ordering of modules in a module layer is not defined. </p></li>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 44848
diff changeset
  1754
     * </ul>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1755
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1756
     * @apiNote Unlike the other load methods defined here, the service type
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1757
     * is the second parameter. The reason for this is to avoid source
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1758
     * compatibility issues for code that uses {@code load(S, null)}.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1759
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1760
     * @param  <S> the class of the service type
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1761
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1762
     * @param  layer
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
  1763
     *         The module layer
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1764
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1765
     * @param  service
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1766
     *         The interface or abstract class representing the service
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1767
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1768
     * @return A new service loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1769
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1770
     * @throws ServiceConfigurationError
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1771
     *         if the service type is not accessible to the caller or the
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1772
     *         caller is in an explicit module and its module descriptor does
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1773
     *         not declare that it uses {@code service}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1774
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1775
     * @since 9
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1776
     * @spec JPMS
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1777
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 27565
diff changeset
  1778
    @CallerSensitive
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents: 44359
diff changeset
  1779
    public static <S> ServiceLoader<S> load(ModuleLayer layer, Class<S> service) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1780
        return new ServiceLoader<>(Reflection.getCallerClass(), layer, service);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1781
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1782
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1783
    /**
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1784
     * Load the first available service provider of this loader's service. This
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1785
     * convenience method is equivalent to invoking the {@link #iterator()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1786
     * iterator()} method and obtaining the first element. It therefore
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1787
     * returns the first element from the provider cache if possible, it
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1788
     * otherwise attempts to load and instantiate the first provider.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1789
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1790
     * <p> The following example loads the first available service provider. If
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1791
     * no service providers are located then it uses a default implementation.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1792
     * <pre>{@code
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1793
     *    CodecFactory factory = ServiceLoader.load(CodecFactory.class)
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1794
     *                                        .findFirst()
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1795
     *                                        .orElse(DEFAULT_CODECSET_FACTORY);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1796
     * }</pre>
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1797
     * @return The first service provider or empty {@code Optional} if no
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1798
     *         service providers are located
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1799
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1800
     * @throws ServiceConfigurationError
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1801
     *         If a provider class cannot be loaded for any of the reasons
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1802
     *         specified in the <a href="#errors">Errors</a> section above.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1803
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1804
     * @since 9
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 42338
diff changeset
  1805
     * @spec JPMS
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1806
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1807
    public Optional<S> findFirst() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1808
        Iterator<S> iterator = iterator();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1809
        if (iterator.hasNext()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1810
            return Optional.of(iterator.next());
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1811
        } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1812
            return Optional.empty();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1813
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1814
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1815
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1816
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1817
     * Clear this loader's provider cache so that all providers will be
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1818
     * reloaded.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1819
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1820
     * <p> After invoking this method, subsequent invocations of the {@link
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1821
     * #iterator() iterator} or {@link #stream() stream} methods will lazily
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1822
     * locate providers (and instantiate in the case of {@code iterator})
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1823
     * from scratch, just as is done by a newly-created service loader.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1824
     *
45661
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1825
     * <p> This method is intended for use in situations in which new service
8f2a3ca7634c 8182482: Module System spec updates
alanb
parents: 45652
diff changeset
  1826
     * providers can be installed into a running Java virtual machine.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1827
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1828
    public void reload() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1829
        lookupIterator1 = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1830
        instantiatedProviders.clear();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1831
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1832
        lookupIterator2 = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1833
        loadedProviders.clear();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1834
        loadedAllProviders = false;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1835
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1836
        // increment count to allow CME be thrown
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 37782
diff changeset
  1837
        reloadCount++;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
     * Returns a string describing this service.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
     * @return  A descriptive string
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
        return "java.util.ServiceLoader[" + service.getName() + "]";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
}