Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/util/ServiceLoader/ModulesTest.java
41149 views
1
/*
2
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
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
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/**
25
* @test
26
* @modules java.scripting
27
* @library modules /test/lib
28
* @build bananascript/*
29
* @build jdk.test.lib.util.JarUtils
30
* @compile classpath/pearscript/org/pear/PearScriptEngineFactory.java
31
* classpath/pearscript/org/pear/PearScript.java
32
* @run testng/othervm ModulesTest
33
* @summary Basic test for ServiceLoader with a provider deployed as a module.
34
*/
35
36
import java.io.File;
37
import java.lang.module.Configuration;
38
import java.lang.module.ModuleFinder;
39
import java.nio.file.Files;
40
import java.nio.file.Path;
41
import java.nio.file.Paths;
42
import java.nio.file.StandardCopyOption;
43
import java.util.ArrayList;
44
import java.util.Collections;
45
import java.util.HashSet;
46
import java.util.Iterator;
47
import java.util.List;
48
import java.util.Optional;
49
import java.util.ServiceLoader;
50
import java.util.ServiceLoader.Provider;
51
import java.util.Set;
52
import java.util.stream.Collectors;
53
import java.util.stream.Stream;
54
import javax.script.ScriptEngineFactory;
55
56
import jdk.test.lib.util.JarUtils;
57
58
import org.testng.annotations.Test;
59
import org.testng.annotations.BeforeTest;
60
import static org.testng.Assert.*;
61
62
/**
63
* Basic test for ServiceLoader. The test make use of two service providers:
64
* 1. BananaScriptEngine - a ScriptEngineFactory deployed as a module on the
65
* module path. It implementations a singleton via the public static
66
* provider method.
67
* 2. PearScriptEngine - a ScriptEngineFactory deployed on the class path
68
* with a service configuration file.
69
*/
70
71
public class ModulesTest {
72
73
// Copy the services configuration file for "pearscript" into place.
74
@BeforeTest
75
public void setup() throws Exception {
76
Path src = Paths.get(System.getProperty("test.src"));
77
Path classes = Paths.get(System.getProperty("test.classes"));
78
String st = ScriptEngineFactory.class.getName();
79
Path config = Paths.get("META-INF", "services", st);
80
Path source = src.resolve("classpath").resolve("pearscript").resolve(config);
81
Path target = classes.resolve(config);
82
Files.createDirectories(target.getParent());
83
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
84
}
85
86
/**
87
* Basic test of iterator() to ensure that providers located as modules
88
* and on the class path are found.
89
*/
90
@Test
91
public void testIterator() {
92
ServiceLoader<ScriptEngineFactory> loader
93
= ServiceLoader.load(ScriptEngineFactory.class);
94
Set<String> names = collectAll(loader)
95
.stream()
96
.map(ScriptEngineFactory::getEngineName)
97
.collect(Collectors.toSet());
98
assertTrue(names.contains("BananaScriptEngine"));
99
assertTrue(names.contains("PearScriptEngine"));
100
}
101
102
/**
103
* Basic test of iterator() to test iteration order. Providers deployed
104
* as named modules should be found before providers deployed on the class
105
* path.
106
*/
107
@Test
108
public void testIteratorOrder() {
109
ServiceLoader<ScriptEngineFactory> loader
110
= ServiceLoader.load(ScriptEngineFactory.class);
111
boolean foundUnnamed = false;
112
for (ScriptEngineFactory factory : collectAll(loader)) {
113
if (factory.getClass().getModule().isNamed()) {
114
if (foundUnnamed) {
115
assertTrue(false, "Named module element after unnamed");
116
}
117
} else {
118
foundUnnamed = true;
119
}
120
}
121
}
122
123
/**
124
* Basic test of Provider::type
125
*/
126
@Test
127
public void testProviderType() {
128
Set<String> types = ServiceLoader.load(ScriptEngineFactory.class)
129
.stream()
130
.map(Provider::type)
131
.map(Class::getName)
132
.collect(Collectors.toSet());
133
assertTrue(types.contains("org.banana.BananaScriptEngineFactory"));
134
assertTrue(types.contains("org.pear.PearScriptEngineFactory"));
135
}
136
137
/**
138
* Basic test of Provider::get
139
*/
140
@Test
141
public void testProviderGet() {
142
Set<String> names = ServiceLoader.load(ScriptEngineFactory.class)
143
.stream()
144
.map(Provider::get)
145
.map(ScriptEngineFactory::getEngineName)
146
.collect(Collectors.toSet());
147
assertTrue(names.contains("BananaScriptEngine"));
148
assertTrue(names.contains("PearScriptEngine"));
149
}
150
151
/**
152
* Basic test of the public static provider method. BananaScriptEngine
153
* defines a provider method that returns the same instance.
154
*/
155
@Test
156
public void testSingleton() {
157
Optional<Provider<ScriptEngineFactory>> oprovider
158
= ServiceLoader.load(ScriptEngineFactory.class)
159
.stream()
160
.filter(p -> p.type().getName().equals("org.banana.BananaScriptEngineFactory"))
161
.findFirst();
162
assertTrue(oprovider.isPresent());
163
Provider<ScriptEngineFactory> provider = oprovider.get();
164
165
// invoke Provider::get twice
166
ScriptEngineFactory factory1 = provider.get();
167
ScriptEngineFactory factory2 = provider.get();
168
assertTrue(factory1 == factory2);
169
}
170
171
/**
172
* Basic test of stream() to ensure that elements for providers in named
173
* modules come before elements for providers in unnamed modules.
174
*/
175
@Test
176
public void testStreamOrder() {
177
List<Class<?>> types = ServiceLoader.load(ScriptEngineFactory.class)
178
.stream()
179
.map(Provider::type)
180
.collect(Collectors.toList());
181
182
boolean foundUnnamed = false;
183
for (Class<?> factoryClass : types) {
184
if (factoryClass.getModule().isNamed()) {
185
if (foundUnnamed) {
186
assertTrue(false, "Named module element after unnamed");
187
}
188
} else {
189
foundUnnamed = true;
190
}
191
}
192
}
193
194
/**
195
* Basic test of ServiceLoader.findFirst()
196
*/
197
@Test
198
public void testFindFirst() {
199
Optional<ScriptEngineFactory> ofactory
200
= ServiceLoader.load(ScriptEngineFactory.class).findFirst();
201
assertTrue(ofactory.isPresent());
202
ScriptEngineFactory factory = ofactory.get();
203
assertTrue(factory.getClass().getModule().isNamed());
204
205
class S { }
206
assertFalse(ServiceLoader.load(S.class).findFirst().isPresent());
207
}
208
209
/**
210
* Basic test ServiceLoader.load specifying the platform class loader.
211
* The providers on the module path and class path should not be located.
212
*/
213
@Test
214
public void testWithPlatformClassLoader() {
215
ClassLoader pcl = ClassLoader.getPlatformClassLoader();
216
217
// iterator
218
ServiceLoader<ScriptEngineFactory> loader
219
= ServiceLoader.load(ScriptEngineFactory.class, pcl);
220
Set<String> names = collectAll(loader)
221
.stream()
222
.map(ScriptEngineFactory::getEngineName)
223
.collect(Collectors.toSet());
224
assertFalse(names.contains("BananaScriptEngine"));
225
assertFalse(names.contains("PearScriptEngine"));
226
227
// stream
228
names = ServiceLoader.load(ScriptEngineFactory.class, pcl)
229
.stream()
230
.map(Provider::get)
231
.map(ScriptEngineFactory::getEngineName)
232
.collect(Collectors.toSet());
233
assertFalse(names.contains("BananaScriptEngine"));
234
assertFalse(names.contains("PearScriptEngine"));
235
}
236
237
/**
238
* Basic test of ServiceLoader.load where the service provider module is an
239
* automatic module.
240
*/
241
@Test
242
public void testWithAutomaticModule() throws Exception {
243
Path here = Paths.get("");
244
Path jar = Files.createTempDirectory(here, "lib").resolve("pearscript.jar");
245
Path classes = Paths.get(System.getProperty("test.classes"));
246
247
JarUtils.createJarFile(jar, classes, "META-INF", "org");
248
249
ModuleFinder finder = ModuleFinder.of(jar);
250
ModuleLayer bootLayer = ModuleLayer.boot();
251
Configuration parent = bootLayer.configuration();
252
Configuration cf = parent.resolveAndBind(finder, ModuleFinder.of(), Set.of());
253
assertTrue(cf.modules().size() == 1);
254
255
ClassLoader scl = ClassLoader.getSystemClassLoader();
256
ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
257
assertTrue(layer.modules().size() == 1);
258
259
ClassLoader loader = layer.findLoader("pearscript");
260
ScriptEngineFactory factory;
261
262
// load using the class loader as context
263
factory = ServiceLoader.load(ScriptEngineFactory.class, loader)
264
.findFirst()
265
.orElse(null);
266
assertNotNull(factory);
267
assertTrue(factory.getClass().getClassLoader() == loader);
268
269
// load using the layer as context
270
factory = ServiceLoader.load(layer, ScriptEngineFactory.class)
271
.findFirst()
272
.orElse(null);
273
assertNotNull(factory);
274
assertTrue(factory.getClass().getClassLoader() == loader);
275
}
276
277
/**
278
* Basic test of ServiceLoader.load, using the class loader for
279
* a module in a custom layer as the context.
280
*/
281
@Test
282
public void testWithCustomLayer1() {
283
ModuleLayer layer = createCustomLayer("bananascript");
284
285
ClassLoader loader = layer.findLoader("bananascript");
286
List<ScriptEngineFactory> providers
287
= collectAll(ServiceLoader.load(ScriptEngineFactory.class, loader));
288
289
// should have at least 2 x bananascript + pearscript
290
assertTrue(providers.size() >= 3);
291
292
// first element should be the provider in the custom layer
293
ScriptEngineFactory factory = providers.get(0);
294
assertTrue(factory.getClass().getClassLoader() == loader);
295
assertTrue(factory.getClass().getModule().getLayer() == layer);
296
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
297
298
// remainder should be the boot layer
299
providers.remove(0);
300
Set<String> names = providers.stream()
301
.map(ScriptEngineFactory::getEngineName)
302
.collect(Collectors.toSet());
303
assertTrue(names.contains("BananaScriptEngine"));
304
assertTrue(names.contains("PearScriptEngine"));
305
}
306
307
/**
308
* Basic test of ServiceLoader.load using a custom Layer as the context.
309
*/
310
@Test
311
public void testWithCustomLayer2() {
312
ModuleLayer layer = createCustomLayer("bananascript");
313
314
List<ScriptEngineFactory> factories
315
= collectAll(ServiceLoader.load(layer, ScriptEngineFactory.class));
316
317
// should have at least 2 x bananascript
318
assertTrue(factories.size() >= 2);
319
320
// first element should be the provider in the custom layer
321
ScriptEngineFactory factory = factories.get(0);
322
assertTrue(factory.getClass().getModule().getLayer() == layer);
323
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
324
325
// remainder should be the boot layer
326
factories.remove(0);
327
Set<String> names = factories.stream()
328
.map(ScriptEngineFactory::getEngineName)
329
.collect(Collectors.toSet());
330
assertTrue(names.contains("BananaScriptEngine"));
331
assertFalse(names.contains("PearScriptEngine"));
332
}
333
334
/**
335
* Basic test of ServiceLoader.load with a tree of layers.
336
*
337
* Test scenario:
338
* - boot layer contains "bananascript", maybe other script engines
339
* - layer1, with boot layer as parent, contains "bananascript"
340
* - layer2, with boot layer as parent, contains "bananascript"
341
* - layer3, with layer1 ad layer as parents, contains "bananascript"
342
*
343
* ServiceLoader should locate all 4 script engine factories in DFS order.
344
*/
345
@Test
346
public void testWithCustomLayer3() {
347
ModuleLayer bootLayer = ModuleLayer.boot();
348
Configuration cf0 = bootLayer.configuration();
349
350
// boot layer should contain "bananascript"
351
List<ScriptEngineFactory> factories
352
= collectAll(ServiceLoader.load(bootLayer, ScriptEngineFactory.class));
353
int countInBootLayer = factories.size();
354
assertTrue(countInBootLayer >= 1);
355
assertTrue(factories.stream()
356
.map(p -> p.getEngineName())
357
.filter("BananaScriptEngine"::equals)
358
.findAny()
359
.isPresent());
360
361
ClassLoader scl = ClassLoader.getSystemClassLoader();
362
ModuleFinder finder = ModuleFinder.of(testModulePath());
363
364
// layer1
365
Configuration cf1 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
366
ModuleLayer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl);
367
assertTrue(layer1.modules().size() == 1);
368
369
// layer2
370
Configuration cf2 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
371
ModuleLayer layer2 = bootLayer.defineModulesWithOneLoader(cf2, scl);
372
assertTrue(layer2.modules().size() == 1);
373
374
// layer3 with layer1 and layer2 as parents
375
Configuration cf3 = Configuration.resolveAndBind(finder,
376
List.of(cf1, cf2),
377
ModuleFinder.of(),
378
Set.of());
379
ModuleLayer layer3
380
= ModuleLayer.defineModulesWithOneLoader(cf3, List.of(layer1, layer2), scl).layer();
381
assertTrue(layer3.modules().size() == 1);
382
383
384
// class loaders
385
ClassLoader loader1 = layer1.findLoader("bananascript");
386
ClassLoader loader2 = layer2.findLoader("bananascript");
387
ClassLoader loader3 = layer3.findLoader("bananascript");
388
assertTrue(loader1 != loader2);
389
assertTrue(loader1 != loader3);
390
assertTrue(loader2 != loader3);
391
392
// load all factories with layer3 as the context
393
factories = collectAll(ServiceLoader.load(layer3, ScriptEngineFactory.class));
394
int count = factories.size();
395
assertTrue(count == countInBootLayer + 3);
396
397
// the ordering should be layer3, layer1, boot layer, layer2
398
399
ScriptEngineFactory factory = factories.get(0);
400
assertTrue(factory.getClass().getModule().getLayer() == layer3);
401
assertTrue(factory.getClass().getClassLoader() == loader3);
402
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
403
404
factory = factories.get(1);
405
assertTrue(factory.getClass().getModule().getLayer() == layer1);
406
assertTrue(factory.getClass().getClassLoader() == loader1);
407
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
408
409
// boot layer "bananascript" and maybe other factories
410
int last = count -1;
411
boolean found = false;
412
for (int i=2; i<last; i++) {
413
factory = factories.get(i);
414
assertTrue(factory.getClass().getModule().getLayer() == bootLayer);
415
if (factory.getEngineName().equals("BananaScriptEngine")) {
416
assertFalse(found);
417
found = true;
418
}
419
}
420
assertTrue(found);
421
422
factory = factories.get(last);
423
assertTrue(factory.getClass().getModule().getLayer() == layer2);
424
assertTrue(factory.getClass().getClassLoader() == loader2);
425
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
426
}
427
428
429
// -- nulls --
430
431
@Test(expectedExceptions = { NullPointerException.class })
432
public void testLoadNull1() {
433
ServiceLoader.load(null);
434
}
435
436
@Test(expectedExceptions = { NullPointerException.class })
437
public void testLoadNull2() {
438
ServiceLoader.load((Class<?>) null, ClassLoader.getSystemClassLoader());
439
}
440
441
@Test(expectedExceptions = { NullPointerException.class })
442
public void testLoadNull3() {
443
class S { }
444
ServiceLoader.load((ModuleLayer) null, S.class);
445
}
446
447
@Test(expectedExceptions = { NullPointerException.class })
448
public void testLoadNull4() {
449
ServiceLoader.load(ModuleLayer.empty(), null);
450
}
451
452
@Test(expectedExceptions = { NullPointerException.class })
453
public void testLoadNull5() {
454
ServiceLoader.loadInstalled(null);
455
}
456
457
/**
458
* Create a custom layer by resolving the given module names. The modules
459
* are located on the test module path ({@code ${test.module.path}}).
460
*/
461
private ModuleLayer createCustomLayer(String... modules) {
462
ModuleFinder finder = ModuleFinder.of(testModulePath());
463
Set<String> roots = new HashSet<>();
464
Collections.addAll(roots, modules);
465
ModuleLayer bootLayer = ModuleLayer.boot();
466
Configuration parent = bootLayer.configuration();
467
Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
468
ClassLoader scl = ClassLoader.getSystemClassLoader();
469
ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
470
assertTrue(layer.modules().size() == 1);
471
return layer;
472
}
473
474
private Path[] testModulePath() {
475
String mp = System.getProperty("test.module.path");
476
return Stream.of(mp.split(File.pathSeparator))
477
.map(Paths::get)
478
.toArray(Path[]::new);
479
}
480
481
private <E> List<E> collectAll(ServiceLoader<E> loader) {
482
List<E> list = new ArrayList<>();
483
Iterator<E> iterator = loader.iterator();
484
while (iterator.hasNext()) {
485
list.add(iterator.next());
486
}
487
return list;
488
}
489
}
490
491
492