author | mchung |
Tue, 06 Nov 2018 10:01:16 -0800 | |
changeset 52427 | 3c6aa484536c |
parent 51703 | 4ffb0a33f265 |
child 54206 | 003cc64366da |
permissions | -rw-r--r-- |
2 | 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 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package java.util; |
|
27 |
||
28 |
import java.io.BufferedReader; |
|
29 |
import java.io.IOException; |
|
30 |
import java.io.InputStream; |
|
31 |
import java.io.InputStreamReader; |
|
36511 | 32 |
import java.lang.reflect.Constructor; |
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 | 35 |
import java.lang.reflect.Modifier; |
2 | 36 |
import java.net.URL; |
36511 | 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 | 47 |
|
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; |
52427
3c6aa484536c
8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents:
51703
diff
changeset
|
50 |
import jdk.internal.access.JavaLangAccess; |
3c6aa484536c
8211122: Reduce the number of internal classes made accessible to jdk.unsupported
mchung
parents:
51703
diff
changeset
|
51 |
import jdk.internal.access.SharedSecrets; |
36511 | 52 |
import jdk.internal.misc.VM; |
53 |
import jdk.internal.module.ServicesCatalog; |
|
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 | 57 |
|
58 |
||
59 |
/** |
|
45661 | 60 |
* A facility to load implementations of a service. |
2 | 61 |
* |
45661 | 62 |
* <p> A <i>service</i> is a well-known interface or class for which zero, one, |
63 |
* or many service providers exist. A <i>service provider</i> (or just |
|
64 |
* <i>provider</i>) is a class that implements or subclasses the well-known |
|
65 |
* interface or class. A {@code ServiceLoader} is an object that locates and |
|
66 |
* loads service providers deployed in the run time environment at a time of an |
|
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 | 71 |
* |
72 |
* <h3> Obtaining a service loader </h3> |
|
2 | 73 |
* |
45661 | 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 | 84 |
* <p> A service loader can be used to locate and instantiate providers of the |
85 |
* service by means of the {@link #iterator() iterator} method. {@code ServiceLoader} |
|
86 |
* also defines the {@link #stream() stream} method to obtain a stream of providers |
|
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 | 89 |
* <p> As an example, suppose the service is {@code com.example.CodecFactory}, an |
90 |
* interface that defines methods for producing encoders and decoders: |
|
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 | 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 | 99 |
* |
100 |
* <p> The following code obtains a service loader for the {@code CodecFactory} |
|
101 |
* service, then uses its iterator (created automatically by the enhanced-for |
|
102 |
* loop) to yield instances of the service providers that are located: |
|
103 |
* |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
104 |
* <pre>{@code |
45661 | 105 |
* ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class); |
106 |
* for (CodecFactory factory : loader) { |
|
107 |
* Encoder enc = factory.getEncoder("PNG"); |
|
108 |
* if (enc != null) |
|
109 |
* ... use enc to encode a PNG file |
|
110 |
* break; |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
111 |
* } |
45661 | 112 |
* }</pre> |
113 |
* |
|
114 |
* <p> If this code resides in a module, then in order to refer to the |
|
115 |
* {@code com.example.CodecFactory} interface, the module declaration would |
|
116 |
* require the module which exports the interface. The module declaration would |
|
117 |
* also specify use of {@code com.example.CodecFactory}: |
|
118 |
* <pre>{@code |
|
119 |
* requires com.example.codec.core; |
|
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 | 123 |
* <p> Sometimes an application may wish to inspect a service provider before |
124 |
* instantiating it, in order to determine if an instance of that service |
|
125 |
* provider would be useful. For example, a service provider for {@code |
|
126 |
* CodecFactory} that is capable of producing a "PNG" encoder may be annotated |
|
127 |
* with {@code @PNG}. The following code uses service loader's {@code stream} |
|
128 |
* method to yield instances of {@code Provider<CodecFactory>} in contrast to |
|
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 | 131 |
* ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class); |
132 |
* Set<CodecFactory> pngFactories = loader |
|
133 |
* .stream() // Note a below |
|
134 |
* .filter(p -> p.type().isAnnotationPresent(PNG.class)) // Note b |
|
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 | 138 |
* <ol type="a"> |
139 |
* <li> A stream of {@code Provider<CodecFactory>} objects </li> |
|
140 |
* <li> {@code p.type()} yields a {@code Class<CodecFactory>} </li> |
|
141 |
* <li> {@code get()} yields an instance of {@code CodecFactory} </li> |
|
142 |
* </ol> |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
143 |
* |
45661 | 144 |
* <h3> Designing services </h3> |
145 |
* |
|
146 |
* <p> A service is a single type, usually an interface or abstract class. A |
|
147 |
* concrete class can be used, but this is not recommended. The type may have |
|
148 |
* any accessibility. The methods of a service are highly domain-specific, so |
|
149 |
* this API specification cannot give concrete advice about their form or |
|
150 |
* function. However, there are two general guidelines: |
|
151 |
* <ol> |
|
152 |
* <li><p> A service should declare as many methods as needed to allow service |
|
153 |
* providers to communicate their domain-specific properties and other |
|
154 |
* quality-of-implementation factors. An application which obtains a service |
|
155 |
* loader for the service may then invoke these methods on each instance of |
|
156 |
* a service provider, in order to choose the best provider for the |
|
157 |
* application. </p></li> |
|
158 |
* <li><p> A service should express whether its service providers are intended |
|
159 |
* to be direct implementations of the service or to be an indirection |
|
160 |
* mechanism such as a "proxy" or a "factory". Service providers tend to be |
|
161 |
* indirection mechanisms when domain-specific objects are relatively |
|
162 |
* expensive to instantiate; in this case, the service should be designed |
|
163 |
* so that service providers are abstractions which create the "real" |
|
164 |
* implementation on demand. For example, the {@code CodecFactory} service |
|
165 |
* expresses through its name that its service providers are factories |
|
166 |
* for codecs, rather than codecs themselves, because it may be expensive |
|
167 |
* or complicated to produce certain codecs. </p></li> |
|
168 |
* </ol> |
|
169 |
* |
|
170 |
* <h3> <a id="developing-service-providers">Developing service providers</a> </h3> |
|
171 |
* |
|
172 |
* <p> A service provider is a single type, usually a concrete class. An |
|
173 |
* interface or abstract class is permitted because it may declare a static |
|
174 |
* provider method, discussed later. The type must be public and must not be |
|
175 |
* an inner class. |
|
176 |
* |
|
177 |
* <p> A service provider and its supporting code may be developed in a module, |
|
178 |
* which is then deployed on the application module path or in a modular |
|
179 |
* image. Alternatively, a service provider and its supporting code may be |
|
180 |
* packaged as a JAR file and deployed on the application class path. The |
|
181 |
* advantage of developing a service provider in a module is that the provider |
|
182 |
* can be fully encapsulated to hide all details of its implementation. |
|
183 |
* |
|
184 |
* <p> An application that obtains a service loader for a given service is |
|
185 |
* indifferent to whether providers of the service are deployed in modules or |
|
186 |
* packaged as JAR files. The application instantiates service providers via |
|
187 |
* the service loader's iterator, or via {@link Provider Provider} objects in |
|
188 |
* the service loader's stream, without knowledge of the service providers' |
|
189 |
* locations. |
|
190 |
* |
|
191 |
* <h3> Deploying service providers as modules </h3> |
|
192 |
* |
|
193 |
* <p> A service provider that is developed in a module must be specified in a |
|
194 |
* <i>provides</i> directive in the module declaration. The provides directive |
|
195 |
* specifies both the service and the service provider; this helps to locate the |
|
196 |
* provider when another module, with a <i>uses</i> directive for the service, |
|
197 |
* obtains a service loader for the service. It is strongly recommended that the |
|
198 |
* module does not export the package containing the service provider. There is |
|
199 |
* no support for a module specifying, in a <i>provides</i> directive, a service |
|
200 |
* provider in another module. |
|
201 |
||
202 |
* <p> A service provider that is developed in a module has no control over when |
|
203 |
* it is instantiated, since that occurs at the behest of the application, but it |
|
204 |
* does have control over how it is instantiated: |
|
205 |
* |
|
206 |
* <ul> |
|
207 |
* |
|
208 |
* <li> If the service provider declares a provider method, then the service |
|
209 |
* loader invokes that method to obtain an instance of the service provider. A |
|
210 |
* provider method is a public static method named "provider" with no formal |
|
211 |
* parameters and a return type that is assignable to the service's interface |
|
212 |
* or class. |
|
213 |
* <p> In this case, the service provider itself need not be assignable to the |
|
214 |
* service's interface or class. </li> |
|
215 |
* |
|
216 |
* <li> If the service provider does not declare a provider method, then the |
|
217 |
* service provider is instantiated directly, via its provider constructor. A |
|
218 |
* provider constructor is a public constructor with no formal parameters. |
|
219 |
* <p> In this case, the service provider must be assignable to the service's |
|
220 |
* interface or class </li> |
|
221 |
* |
|
222 |
* </ul> |
|
223 |
* |
|
224 |
* <p> A service provider that is deployed as an |
|
225 |
* {@linkplain java.lang.module.ModuleDescriptor#isAutomatic automatic module} on |
|
226 |
* the application module path must have a provider constructor. There is no |
|
227 |
* support for a provider method in this case. |
|
228 |
* |
|
229 |
* <p> As an example, suppose a module specifies the following directives: |
|
230 |
* <pre>{@code |
|
231 |
* provides com.example.CodecFactory with com.example.impl.StandardCodecs; |
|
232 |
* provides com.example.CodecFactory with com.example.impl.ExtendedCodecsFactory; |
|
233 |
* }</pre> |
|
234 |
* |
|
235 |
* <p> where |
|
236 |
* |
|
237 |
* <ul> |
|
238 |
* <li> {@code com.example.CodecFactory} is the two-method service from |
|
239 |
* earlier. </li> |
|
240 |
* |
|
241 |
* <li> {@code com.example.impl.StandardCodecs} is a public class that implements |
|
242 |
* {@code CodecFactory} and has a public no-args constructor. </li> |
|
243 |
* |
|
244 |
* <li> {@code com.example.impl.ExtendedCodecsFactory} is a public class that |
|
245 |
* does not implement CodecFactory, but it declares a public static no-args |
|
246 |
* method named "provider" with a return type of {@code CodecFactory}. </li> |
|
247 |
* </ul> |
|
248 |
* |
|
249 |
* <p> A service loader will instantiate {@code StandardCodecs} via its |
|
250 |
* constructor, and will instantiate {@code ExtendedCodecsFactory} by invoking |
|
251 |
* its {@code provider} method. The requirement that the provider constructor or |
|
252 |
* provider method is public helps to document the intent that the class (that is, |
|
253 |
* the service provider) will be instantiated by an entity (that is, a service |
|
254 |
* loader) which is outside the class's package. |
|
255 |
* |
|
256 |
* <h3> Deploying service providers on the class path </h3> |
|
257 |
* |
|
258 |
* A service provider that is packaged as a JAR file for the class path is |
|
259 |
* identified by placing a <i>provider-configuration file</i> in the resource |
|
260 |
* directory {@code META-INF/services}. The name of the provider-configuration |
|
261 |
* file is the fully qualified binary name of the service. The provider-configuration |
|
262 |
* file contains a list of fully qualified binary names of service providers, one |
|
263 |
* per line. |
|
264 |
* |
|
265 |
* <p> For example, suppose the service provider |
|
266 |
* {@code com.example.impl.StandardCodecs} is packaged in a JAR file for the |
|
267 |
* class path. The JAR file will contain a provider-configuration file named: |
|
268 |
* |
|
269 |
* <blockquote>{@code |
|
270 |
* META-INF/services/com.example.CodecFactory |
|
271 |
* }</blockquote> |
|
272 |
* |
|
273 |
* that contains the line: |
|
274 |
* |
|
275 |
* <blockquote>{@code |
|
276 |
* com.example.impl.StandardCodecs # Standard codecs |
|
277 |
* }</blockquote> |
|
278 |
* |
|
279 |
* <p><a id="format">The provider-configuration file must be encoded in UTF-8. </a> |
|
280 |
* Space and tab characters surrounding each service provider's name, as well as |
|
281 |
* blank lines, are ignored. The comment character is {@code '#'} |
|
282 |
* ({@code '\u0023'} <span style="font-size:smaller;">NUMBER SIGN</span>); |
|
283 |
* on each line all characters following the first comment character are ignored. |
|
284 |
* If a service provider class name is listed more than once in a |
|
285 |
* provider-configuration file then the duplicate is ignored. If a service |
|
286 |
* provider class is named in more than one configuration file then the duplicate |
|
287 |
* is ignored. |
|
288 |
* |
|
289 |
* <p> A service provider that is mentioned in a provider-configuration file may |
|
290 |
* be located in the same JAR file as the provider-configuration file or in a |
|
291 |
* different JAR file. The service provider must be visible from the class loader |
|
292 |
* that is initially queried to locate the provider-configuration file; this is |
|
293 |
* not necessarily the class loader which ultimately locates the |
|
294 |
* provider-configuration file. |
|
295 |
* |
|
296 |
* <h3> Timing of provider discovery </h3> |
|
297 |
* |
|
298 |
* <p> Service providers are loaded and instantiated lazily, that is, on demand. |
|
299 |
* A service loader maintains a cache of the providers that have been loaded so |
|
300 |
* far. Each invocation of the {@code iterator} method returns an {@code Iterator} |
|
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 | 303 |
* providers, adding each one to the cache in turn. Similarly, each invocation |
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 | 309 |
* <h3> <a id="errors">Errors</a> </h3> |
2 | 310 |
* |
45661 | 311 |
* <p> When using the service loader's {@code iterator}, the {@link |
312 |
* Iterator#hasNext() hasNext} and {@link Iterator#next() next} methods will |
|
313 |
* fail with {@link ServiceConfigurationError} if an error occurs locating, |
|
314 |
* loading or instantiating a service provider. When processing the service |
|
315 |
* loader's stream then {@code ServiceConfigurationError} may be thrown by any |
|
316 |
* method that causes a service provider to be located or loaded. |
|
2 | 317 |
* |
45661 | 318 |
* <p> When loading or instantiating a service provider in a module, {@code |
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 | 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 | 325 |
* <li> The service provider does not declare a provider method, and either |
326 |
* it is not assignable to the service's interface/class or does not have a |
|
327 |
* provider constructor. </li> |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
328 |
* |
45661 | 329 |
* <li> The service provider declares a public static no-args method named |
330 |
* "provider" with a return type that is not assignable to the service's |
|
331 |
* interface or class. </li> |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
332 |
* |
45661 | 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 | 336 |
* <li> The service provider declares a provider method and it fails by |
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 | 339 |
* <li> The service provider does not declare a provider method, and its |
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 | 344 |
* <p> When reading a provider-configuration file, or loading or instantiating |
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 | 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 | 358 |
* <li> A service provider is not assignable to the service's interface or |
359 |
* class, or does not define a provider constructor, or cannot be |
|
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 | 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 | 368 |
* context of the caller that created the service loader. |
2 | 369 |
* Trusted system code should typically invoke the methods in this class, and |
370 |
* the methods of the iterators which they return, from within a privileged |
|
371 |
* security context. |
|
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 | 375 |
* <p> Instances of this class are not safe for use by multiple concurrent |
376 |
* threads. |
|
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 | 381 |
* method in this class will cause a {@link NullPointerException} to be thrown. |
382 |
* |
|
383 |
* @param <S> |
|
384 |
* The type of the service to be loaded by this loader |
|
385 |
* |
|
386 |
* @author Mark Reinhold |
|
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 | 390 |
*/ |
391 |
||
392 |
public final class ServiceLoader<S> |
|
393 |
implements Iterable<S> |
|
394 |
{ |
|
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 | 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 | 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 | 404 |
|
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 | 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 | 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 | 420 |
|
421 |
// Incremented when reload is called |
|
422 |
private int reloadCount; |
|
2 | 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 | 428 |
|
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 | 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 | 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 | 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 | 468 |
} |
469 |
||
470 |
/** |
|
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 | 473 |
* |
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 | 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 | 483 |
|
484 |
this.service = svc; |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
485 |
this.serviceName = svc.getName(); |
36511 | 486 |
this.layer = layer; |
487 |
this.loader = null; |
|
488 |
this.acc = (System.getSecurityManager() != null) |
|
489 |
? AccessController.getContext() |
|
490 |
: null; |
|
2 | 491 |
} |
492 |
||
36511 | 493 |
/** |
494 |
* Initializes a new instance of this class for locating service providers |
|
495 |
* via a class loader. |
|
496 |
* |
|
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 | 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 | 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 | 506 |
if (cl == null) { |
507 |
cl = ClassLoader.getSystemClassLoader(); |
|
508 |
} |
|
509 |
} else { |
|
510 |
||
511 |
// if we get here then it means that ServiceLoader is being used |
|
512 |
// before the VM initialization has completed. At this point then |
|
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 | 515 |
Module base = Object.class.getModule(); |
516 |
Module svcModule = svc.getModule(); |
|
517 |
if (callerModule != base || svcModule != base) { |
|
518 |
fail(svc, "not accessible to " + callerModule + " during VM init"); |
|
519 |
} |
|
520 |
||
521 |
// restricted to boot loader during startup |
|
522 |
cl = null; |
|
523 |
} |
|
524 |
||
525 |
this.service = svc; |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
526 |
this.serviceName = svc.getName(); |
36511 | 527 |
this.layer = null; |
528 |
this.loader = cl; |
|
529 |
this.acc = (System.getSecurityManager() != null) |
|
530 |
? AccessController.getContext() |
|
531 |
: null; |
|
2 | 532 |
} |
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 | 555 |
} |
556 |
||
557 |
/** |
|
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 | 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 | 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 | 571 |
} |
572 |
||
573 |
// If the caller is in a named module then it should "uses" the |
|
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 | 577 |
} |
578 |
} |
|
579 |
||
12448 | 580 |
private static void fail(Class<?> service, String msg, Throwable cause) |
2 | 581 |
throws ServiceConfigurationError |
582 |
{ |
|
583 |
throw new ServiceConfigurationError(service.getName() + ": " + msg, |
|
584 |
cause); |
|
585 |
} |
|
586 |
||
12448 | 587 |
private static void fail(Class<?> service, String msg) |
2 | 588 |
throws ServiceConfigurationError |
589 |
{ |
|
590 |
throw new ServiceConfigurationError(service.getName() + ": " + msg); |
|
591 |
} |
|
592 |
||
12448 | 593 |
private static void fail(Class<?> service, URL u, int line, String msg) |
2 | 594 |
throws ServiceConfigurationError |
595 |
{ |
|
596 |
fail(service, u + ":" + line + ": " + msg); |
|
597 |
} |
|
598 |
||
36511 | 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 | 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 | 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 | 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 | 677 |
} |
678 |
||
36511 | 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 | 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 | 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 | 711 |
} |
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 | 716 |
} |
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 | 722 |
} else { |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
723 |
return newInstance(); |
36511 | 724 |
} |
725 |
} |
|
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 | 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 | 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 | 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 | 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 | 829 |
} |
830 |
} |
|
831 |
||
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 | 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 | 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 | 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 | 917 |
|
36511 | 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 | 921 |
} |
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 | 926 |
} |
927 |
||
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 | 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 | 946 |
} |
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 | 957 |
} |
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
958 |
return true; |
2 | 959 |
} |
960 |
||
36511 | 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 | 964 |
throw new NoSuchElementException(); |
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 | 976 |
} |
977 |
} |
|
978 |
||
979 |
/** |
|
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 | 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 | 986 |
{ |
987 |
ClassLoader currentLoader; |
|
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 | 992 |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
993 |
ModuleServicesLookupIterator() { |
36511 | 994 |
this.currentLoader = loader; |
995 |
this.iterator = iteratorFor(loader); |
|
996 |
} |
|
997 |
||
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 | 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 | 1024 |
*/ |
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 | 1038 |
} |
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 | 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 | 1057 |
} |
1058 |
} |
|
1059 |
||
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 | 1071 |
} |
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 | 1081 |
} |
1082 |
} |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
1083 |
return true; |
36511 | 1084 |
} |
1085 |
||
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 | 1089 |
throw new NoSuchElementException(); |
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 | 1101 |
} |
1102 |
} |
|
1103 |
||
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 | 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 | 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 | 1115 |
Enumeration<URL> configs; |
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 | 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 | 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 | 1241 |
} |
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
1242 |
} |
2 | 1243 |
return true; |
1244 |
} |
|
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 | 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 | 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 | 1285 |
} |
1286 |
||
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 | 1317 |
* Returns an iterator to lazily load and instantiate the available |
1318 |
* providers of this loader's service. |
|
2 | 1319 |
* |
36511 | 1320 |
* <p> To achieve laziness the actual work of locating and instantiating |
45661 | 1321 |
* providers is done by the iterator itself. Its {@link Iterator#hasNext |
1322 |
* hasNext} and {@link Iterator#next next} methods can therefore throw a |
|
1323 |
* {@link ServiceConfigurationError} for any of the reasons specified in |
|
1324 |
* the <a href="#errors">Errors</a> section above. To write robust code it |
|
1325 |
* is only necessary to catch {@code ServiceConfigurationError} when using |
|
1326 |
* the iterator. If an error is thrown then subsequent invocations of the |
|
2 | 1327 |
* iterator will make a best effort to locate and instantiate the next |
1328 |
* available provider, but in general such recovery cannot be guaranteed. |
|
1329 |
* |
|
45661 | 1330 |
* <p> Caching: The iterator returned by this method first yields all of |
1331 |
* the elements of the provider cache, in the order that they were loaded. |
|
1332 |
* It then lazily loads and instantiates any remaining service providers, |
|
1333 |
* adding each one to the cache in turn. If this loader's provider caches are |
|
1334 |
* cleared by invoking the {@link #reload() reload} method then existing |
|
1335 |
* iterators for this service loader should be discarded. |
|
1336 |
* The {@code hasNext} and {@code next} methods of the iterator throw {@link |
|
36511 | 1337 |
* java.util.ConcurrentModificationException ConcurrentModificationException} |
1338 |
* if used after the provider cache has been cleared. |
|
1339 |
* |
|
2 | 1340 |
* <p> The iterator returned by this method does not support removal. |
1341 |
* Invoking its {@link java.util.Iterator#remove() remove} method will |
|
1342 |
* cause an {@link UnsupportedOperationException} to be thrown. |
|
1343 |
* |
|
45661 | 1344 |
* @apiNote Throwing an error in these cases may seem extreme. The rationale |
1345 |
* for this behavior is that a malformed provider-configuration file, like a |
|
1346 |
* malformed class file, indicates a serious problem with the way the Java |
|
1347 |
* virtual machine is configured or is being used. As such it is preferable |
|
1348 |
* to throw an error rather than try to recover or, even worse, fail silently. |
|
1349 |
* |
|
2 | 1350 |
* @return An iterator that lazily loads providers for this loader's |
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 | 1355 |
*/ |
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 | 1363 |
return new Iterator<S>() { |
1364 |
||
36511 | 1365 |
// record reload count |
1366 |
final int expectedReloadCount = ServiceLoader.this.reloadCount; |
|
1367 |
||
1368 |
// index into the cached providers list |
|
1369 |
int index; |
|
1370 |
||
1371 |
/** |
|
1372 |
* Throws ConcurrentModificationException if the list of cached |
|
1373 |
* providers has been cleared by reload. |
|
1374 |
*/ |
|
1375 |
private void checkReloadCount() { |
|
1376 |
if (ServiceLoader.this.reloadCount != expectedReloadCount) |
|
1377 |
throw new ConcurrentModificationException(); |
|
1378 |
} |
|
2 | 1379 |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1380 |
@Override |
2 | 1381 |
public boolean hasNext() { |
36511 | 1382 |
checkReloadCount(); |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1383 |
if (index < instantiatedProviders.size()) |
2 | 1384 |
return true; |
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1385 |
return lookupIterator1.hasNext(); |
2 | 1386 |
} |
1387 |
||
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1388 |
@Override |
2 | 1389 |
public S next() { |
36511 | 1390 |
checkReloadCount(); |
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 | 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 | 1397 |
} |
1398 |
index++; |
|
1399 |
return next; |
|
2 | 1400 |
} |
1401 |
||
1402 |
}; |
|
1403 |
} |
|
1404 |
||
1405 |
/** |
|
45661 | 1406 |
* Returns a stream to lazily load available providers of this loader's |
1407 |
* service. The stream elements are of type {@link Provider Provider}, the |
|
1408 |
* {@code Provider}'s {@link Provider#get() get} method must be invoked to |
|
1409 |
* get or instantiate the provider. |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1410 |
* |
45661 | 1411 |
* <p> To achieve laziness the actual work of locating providers is done |
1412 |
* when processing the stream. If a service provider cannot be loaded for any |
|
47471 | 1413 |
* of the reasons specified in the <a href="#errors">Errors</a> section |
45661 | 1414 |
* above then {@link ServiceConfigurationError} is thrown by whatever method |
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 | 1417 |
* <p> Caching: When processing the stream then providers that were previously |
1418 |
* loaded by stream operations are processed first, in load order. It then |
|
1419 |
* lazily loads any remaining service providers. If this loader's provider |
|
1420 |
* caches are cleared by invoking the {@link #reload() reload} method then |
|
1421 |
* existing streams for this service loader should be discarded. The returned |
|
1422 |
* stream's source {@link Spliterator spliterator} is <em>fail-fast</em> and |
|
1423 |
* will throw {@link ConcurrentModificationException} if the provider cache |
|
1424 |
* has been cleared. </p> |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1425 |
* |
45661 | 1426 |
* <p> The following examples demonstrate usage. The first example creates |
1427 |
* a stream of {@code CodecFactory} objects, the second example is the same |
|
1428 |
* except that it sorts the providers by provider class name (and so locate |
|
1429 |
* all providers). |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1430 |
* <pre>{@code |
45661 | 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 | 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 | 1514 |
* Creates a new service loader for the given service type, class |
1515 |
* loader, and caller. |
|
1516 |
* |
|
1517 |
* @param <S> the class of the service type |
|
1518 |
* |
|
1519 |
* @param service |
|
1520 |
* The interface or abstract class representing the service |
|
1521 |
* |
|
1522 |
* @param loader |
|
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 | 1525 |
* loader (or, failing that, the bootstrap class loader) is to be |
1526 |
* used |
|
1527 |
* |
|
1528 |
* @param callerModule |
|
1529 |
* The caller's module for which a new service loader is created |
|
1530 |
* |
|
1531 |
* @return A new service loader |
|
1532 |
*/ |
|
1533 |
static <S> ServiceLoader<S> load(Class<S> service, |
|
1534 |
ClassLoader loader, |
|
1535 |
Module callerModule) |
|
1536 |
{ |
|
1537 |
return new ServiceLoader<>(callerModule, service, loader); |
|
1538 |
} |
|
1539 |
||
1540 |
/** |
|
45661 | 1541 |
* Creates a new service loader for the given service. The service loader |
1542 |
* uses the given class loader as the starting point to locate service |
|
1543 |
* providers for the service. The service loader's {@link #iterator() |
|
1544 |
* iterator} and {@link #stream() stream} locate providers in both named |
|
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 | 1548 |
* <li> <p> Step 1: Locate providers in named modules. </p> |
1549 |
* |
|
1550 |
* <p> Service providers are located in all named modules of the class |
|
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 | 1553 |
* <p> In addition, if the class loader is not the bootstrap or {@linkplain |
1554 |
* ClassLoader#getPlatformClassLoader() platform class loader}, then service |
|
1555 |
* providers may be located in the named modules of other class loaders. |
|
1556 |
* Specifically, if the class loader, or any class loader reachable via |
|
1557 |
* parent delegation, has a module in a {@linkplain ModuleLayer module |
|
1558 |
* layer}, then service providers in all modules in the module layer are |
|
1559 |
* located. </p> |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
1560 |
* |
45661 | 1561 |
* <p> For example, suppose there is a module layer where each module is |
1562 |
* in its own class loader (see {@link ModuleLayer#defineModulesWithManyLoaders |
|
1563 |
* defineModulesWithManyLoaders}). If this {@code ServiceLoader.load} method |
|
1564 |
* is invoked to locate providers using any of the class loaders created for |
|
1565 |
* the module layer, then it will locate all of the providers in the module |
|
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 | 1568 |
* <p> Ordering: The service loader will first locate any service providers |
1569 |
* in modules defined to the class loader, then its parent class loader, |
|
1570 |
* its parent parent, and so on to the bootstrap class loader. If a class |
|
1571 |
* loader has modules in a module layer then all providers in that module |
|
1572 |
* layer are located (irrespective of their class loader) before the |
|
1573 |
* providers in the parent class loader are located. The ordering of |
|
1574 |
* modules in same class loader, or the ordering of modules in a module |
|
1575 |
* layer, is not defined. </p> |
|
1576 |
* |
|
1577 |
* <p> If a module declares more than one provider then the providers |
|
1578 |
* are located in the order that its module descriptor {@linkplain |
|
1579 |
* java.lang.module.ModuleDescriptor.Provides#providers() lists the |
|
1580 |
* providers}. Providers added dynamically by instrumentation agents (see |
|
1581 |
* {@link java.lang.instrument.Instrumentation#redefineModule redefineModule}) |
|
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 | 1584 |
* <li> <p> Step 2: Locate providers in unnamed modules. </p> |
1585 |
* |
|
1586 |
* <p> Service providers in unnamed modules are located if their class names |
|
1587 |
* are listed in provider-configuration files located by the class loader's |
|
1588 |
* {@link ClassLoader#getResources(String) getResources} method. </p> |
|
45652
33342314ce89
8181087: Module system implementation refresh (6/2017)
alanb
parents:
44848
diff
changeset
|
1589 |
* |
45661 | 1590 |
* <p> The ordering is based on the order that the class loader's {@code |
1591 |
* getResources} method finds the service configuration files and within |
|
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 | 1594 |
* <p> In a provider-configuration file, any mention of a service provider |
1595 |
* that is deployed in a named module is ignored. This is to avoid |
|
1596 |
* duplicates that would otherwise arise when a named module has both a |
|
1597 |
* <i>provides</i> directive and a provider-configuration file that mention |
|
1598 |
* the same service provider. </p> |
|
1599 |
* |
|
1600 |
* <p> The provider class must be visible to the class loader. </p> </li> |
|
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 | 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 | 1624 |
* @param service |
1625 |
* The interface or abstract class representing the service |
|
1626 |
* |
|
1627 |
* @param loader |
|
1628 |
* The class loader to be used to load provider-configuration files |
|
36511 | 1629 |
* and provider classes, or {@code null} if the system class |
2 | 1630 |
* loader (or, failing that, the bootstrap class loader) is to be |
1631 |
* used |
|
1632 |
* |
|
1633 |
* @return A new service loader |
|
36511 | 1634 |
* |
1635 |
* @throws ServiceConfigurationError |
|
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 | 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 | 1642 |
*/ |
36511 | 1643 |
@CallerSensitive |
2 | 1644 |
public static <S> ServiceLoader<S> load(Class<S> service, |
1645 |
ClassLoader loader) |
|
1646 |
{ |
|
36511 | 1647 |
return new ServiceLoader<>(Reflection.getCallerClass(), service, loader); |
2 | 1648 |
} |
1649 |
||
1650 |
/** |
|
1651 |
* Creates a new service loader for the given service type, using the |
|
1652 |
* current thread's {@linkplain java.lang.Thread#getContextClassLoader |
|
1653 |
* context class loader}. |
|
1654 |
* |
|
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 | 1659 |
* |
1660 |
* is equivalent to |
|
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 | 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 | 1676 |
* @param service |
1677 |
* The interface or abstract class representing the service |
|
1678 |
* |
|
1679 |
* @return A new service loader |
|
36511 | 1680 |
* |
1681 |
* @throws ServiceConfigurationError |
|
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 | 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 | 1688 |
*/ |
36511 | 1689 |
@CallerSensitive |
2 | 1690 |
public static <S> ServiceLoader<S> load(Class<S> service) { |
1691 |
ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
|
36511 | 1692 |
return new ServiceLoader<>(Reflection.getCallerClass(), service, cl); |
2 | 1693 |
} |
1694 |
||
1695 |
/** |
|
1696 |
* Creates a new service loader for the given service type, using the |
|
36511 | 1697 |
* {@linkplain ClassLoader#getPlatformClassLoader() platform class loader}. |
2 | 1698 |
* |
36511 | 1699 |
* <p> This convenience method is equivalent to: </p> |
2 | 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 | 1704 |
* |
1705 |
* <p> This method is intended for use when only installed providers are |
|
1706 |
* desired. The resulting service will only find and load providers that |
|
1707 |
* have been installed into the current Java virtual machine; providers on |
|
36511 | 1708 |
* the application's module path or class path will be ignored. |
2 | 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 | 1712 |
* @param service |
1713 |
* The interface or abstract class representing the service |
|
1714 |
* |
|
1715 |
* @return A new service loader |
|
36511 | 1716 |
* |
1717 |
* @throws ServiceConfigurationError |
|
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 | 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 | 1724 |
*/ |
36511 | 1725 |
@CallerSensitive |
2 | 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 | 1729 |
} |
1730 |
||
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 | 1734 |
* does not locate providers in unnamed modules. The ordering that the service |
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 | 1747 |
* <li><p> If a module declares more than one provider then the providers |
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 | 1755 |
* |
1756 |
* @apiNote Unlike the other load methods defined here, the service type |
|
1757 |
* is the second parameter. The reason for this is to avoid source |
|
1758 |
* compatibility issues for code that uses {@code load(S, null)}. |
|
1759 |
* |
|
1760 |
* @param <S> the class of the service type |
|
1761 |
* |
|
1762 |
* @param layer |
|
44545
83b611b88ac8
8177530: Module system implementation refresh (4/2017)
alanb
parents:
44359
diff
changeset
|
1763 |
* The module layer |
36511 | 1764 |
* |
1765 |
* @param service |
|
1766 |
* The interface or abstract class representing the service |
|
1767 |
* |
|
1768 |
* @return A new service loader |
|
1769 |
* |
|
1770 |
* @throws ServiceConfigurationError |
|
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 | 1773 |
* not declare that it uses {@code service} |
1774 |
* |
|
1775 |
* @since 9 |
|
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42338
diff
changeset
|
1776 |
* @spec JPMS |
36511 | 1777 |
*/ |
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 | 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 | 1790 |
* <p> The following example loads the first available service provider. If |
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 | 1793 |
* CodecFactory factory = ServiceLoader.load(CodecFactory.class) |
1794 |
* .findFirst() |
|
1795 |
* .orElse(DEFAULT_CODECSET_FACTORY); |
|
42338
a60f280f803c
8169069: Module system implementation refresh (11/2016)
alanb
parents:
37782
diff
changeset
|
1796 |
* }</pre> |
45661 | 1797 |
* @return The first service provider or empty {@code Optional} if no |
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 | 1801 |
* If a provider class cannot be loaded for any of the reasons |
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 | 1822 |
* locate providers (and instantiate in the case of {@code iterator}) |
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 | 1825 |
* <p> This method is intended for use in situations in which new service |
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 | 1838 |
} |
1839 |
||
1840 |
/** |
|
1841 |
* Returns a string describing this service. |
|
1842 |
* |
|
1843 |
* @return A descriptive string |
|
1844 |
*/ |
|
1845 |
public String toString() { |
|
1846 |
return "java.util.ServiceLoader[" + service.getName() + "]"; |
|
1847 |
} |
|
1848 |
||
1849 |
} |