Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/ModuleLayer/LayerAndLoadersTest.java
41149 views
1
/*
2
* Copyright (c) 2015, 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
* @library /test/lib
27
* @modules jdk.compiler
28
* @build LayerAndLoadersTest
29
* jdk.test.lib.compiler.CompilerUtils
30
* jdk.test.lib.util.ModuleUtils
31
* @run testng LayerAndLoadersTest
32
* @summary Tests for java.lang.ModuleLayer@defineModulesWithXXX methods
33
*/
34
35
import java.io.IOException;
36
import java.io.InputStream;
37
import java.io.UncheckedIOException;
38
import java.lang.module.Configuration;
39
import java.lang.module.ModuleDescriptor;
40
import java.lang.module.ModuleFinder;
41
import java.lang.module.ModuleReference;
42
import java.lang.module.ResolvedModule;
43
import java.lang.reflect.Method;
44
import java.net.URL;
45
import java.nio.file.Path;
46
import java.nio.file.Paths;
47
import java.util.ArrayList;
48
import java.util.Enumeration;
49
import java.util.HashMap;
50
import java.util.Iterator;
51
import java.util.List;
52
import java.util.Map;
53
import java.util.Optional;
54
import java.util.ServiceLoader;
55
import java.util.Set;
56
import java.util.stream.Collectors;
57
58
import jdk.test.lib.compiler.CompilerUtils;
59
import jdk.test.lib.util.ModuleUtils;
60
61
import org.testng.annotations.BeforeTest;
62
import org.testng.annotations.Test;
63
import static org.testng.Assert.*;
64
65
@Test
66
public class LayerAndLoadersTest {
67
68
private static final String TEST_SRC = System.getProperty("test.src");
69
70
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
71
private static final Path MODS_DIR = Paths.get("mods");
72
73
@BeforeTest
74
public void setup() throws Exception {
75
// javac -d mods --module-source-path src src/**
76
assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR,
77
"--module-source-path", SRC_DIR.toString()));
78
}
79
80
81
/**
82
* Basic test of ModuleLayer.defineModulesWithOneLoader
83
*
84
* Test scenario:
85
* m1 requires m2 and m3
86
*/
87
public void testWithOneLoader() throws Exception {
88
Configuration cf = resolve("m1");
89
90
ClassLoader scl = ClassLoader.getSystemClassLoader();
91
92
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
93
94
checkLayer(layer, "m1", "m2", "m3");
95
96
ClassLoader cl1 = layer.findLoader("m1");
97
ClassLoader cl2 = layer.findLoader("m2");
98
ClassLoader cl3 = layer.findLoader("m3");
99
100
assertTrue(cl1.getParent() == scl);
101
assertTrue(cl2 == cl1);
102
assertTrue(cl3 == cl1);
103
104
invoke(layer, "m1", "p.Main");
105
}
106
107
108
/**
109
* Basic test of ModuleLayer.defineModulesWithManyLoaders
110
*
111
* Test scenario:
112
* m1 requires m2 and m3
113
*/
114
public void testWithManyLoaders() throws Exception {
115
Configuration cf = resolve("m1");
116
117
ClassLoader scl = ClassLoader.getSystemClassLoader();
118
119
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
120
121
checkLayer(layer, "m1", "m2", "m3");
122
123
ClassLoader cl1 = layer.findLoader("m1");
124
ClassLoader cl2 = layer.findLoader("m2");
125
ClassLoader cl3 = layer.findLoader("m3");
126
127
assertTrue(cl1.getParent() == scl);
128
assertTrue(cl2.getParent() == scl);
129
assertTrue(cl3.getParent() == scl);
130
assertTrue(cl2 != cl1);
131
assertTrue(cl3 != cl1);
132
assertTrue(cl3 != cl2);
133
134
invoke(layer, "m1", "p.Main");
135
}
136
137
138
/**
139
* Basic test of ModuleLayer.defineModulesWithOneLoader where one of the
140
* modules is a service provider module.
141
*
142
* Test scenario:
143
* m1 requires m2 and m3
144
* m1 uses S
145
* m4 provides S with ...
146
*/
147
public void testServicesWithOneLoader() throws Exception {
148
Configuration cf = resolveAndBind("m1");
149
150
ClassLoader scl = ClassLoader.getSystemClassLoader();
151
152
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
153
154
checkLayer(layer, "m1", "m2", "m3", "m4");
155
156
ClassLoader cl1 = layer.findLoader("m1");
157
ClassLoader cl2 = layer.findLoader("m2");
158
ClassLoader cl3 = layer.findLoader("m3");
159
ClassLoader cl4 = layer.findLoader("m4");
160
161
assertTrue(cl1.getParent() == scl);
162
assertTrue(cl2 == cl1);
163
assertTrue(cl3 == cl1);
164
assertTrue(cl4 == cl1);
165
166
Class<?> serviceType = cl1.loadClass("p.Service");
167
assertTrue(serviceType.getClassLoader() == cl1);
168
169
Iterator<?> iter = ServiceLoader.load(serviceType, cl1).iterator();
170
Object provider = iter.next();
171
assertTrue(serviceType.isInstance(provider));
172
assertTrue(provider.getClass().getClassLoader() == cl1);
173
assertFalse(iter.hasNext());
174
}
175
176
177
/**
178
* Basic test of ModuleLayer.defineModulesWithManyLoaders where one of the
179
* modules is a service provider module.
180
*
181
* Test scenario:
182
* m1 requires m2 and m3
183
* m1 uses S
184
* m4 provides S with ...
185
*/
186
public void testServicesWithManyLoaders() throws Exception {
187
Configuration cf = resolveAndBind("m1");
188
189
ClassLoader scl = ClassLoader.getSystemClassLoader();
190
191
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
192
193
checkLayer(layer, "m1", "m2", "m3", "m4");
194
195
ClassLoader cl1 = layer.findLoader("m1");
196
ClassLoader cl2 = layer.findLoader("m2");
197
ClassLoader cl3 = layer.findLoader("m3");
198
ClassLoader cl4 = layer.findLoader("m4");
199
200
assertTrue(cl1.getParent() == scl);
201
assertTrue(cl2.getParent() == scl);
202
assertTrue(cl3.getParent() == scl);
203
assertTrue(cl4.getParent() == scl);
204
assertTrue(cl2 != cl1);
205
assertTrue(cl3 != cl1);
206
assertTrue(cl3 != cl2);
207
assertTrue(cl4 != cl1);
208
assertTrue(cl4 != cl2);
209
assertTrue(cl4 != cl3);
210
211
Class<?> serviceType = cl1.loadClass("p.Service");
212
assertTrue(serviceType.getClassLoader() == cl1);
213
214
// Test that the service provider can be located via any of
215
// the class loaders in the layer
216
for (Module m : layer.modules()) {
217
ClassLoader loader = m.getClassLoader();
218
Iterator<?> iter = ServiceLoader.load(serviceType, loader).iterator();
219
Object provider = iter.next();
220
assertTrue(serviceType.isInstance(provider));
221
assertTrue(provider.getClass().getClassLoader() == cl4);
222
assertFalse(iter.hasNext());
223
}
224
}
225
226
227
/**
228
* Tests that the class loaders created by defineModulesWithXXX delegate
229
* to the given parent class loader.
230
*/
231
public void testDelegationToParent() throws Exception {
232
Configuration cf = resolve("m1");
233
234
ClassLoader parent = this.getClass().getClassLoader();
235
String cn = this.getClass().getName();
236
237
// one loader
238
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent);
239
testLoad(layer, cn);
240
241
// one loader with boot loader as parent
242
layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, null);
243
testLoadFail(layer, cn);
244
245
// many loaders
246
layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, parent);
247
testLoad(layer, cn);
248
249
// many loader with boot loader as parent
250
layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null);
251
testLoadFail(layer, cn);
252
}
253
254
255
/**
256
* Test defineModulesWithXXX when modules that have overlapping packages.
257
*
258
* Test scenario:
259
* m1 exports p
260
* m2 exports p
261
*/
262
public void testOverlappingPackages() {
263
ModuleDescriptor descriptor1
264
= ModuleDescriptor.newModule("m1").exports("p").build();
265
266
ModuleDescriptor descriptor2
267
= ModuleDescriptor.newModule("m2").exports("p").build();
268
269
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
270
271
Configuration cf = ModuleLayer.boot()
272
.configuration()
273
.resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
274
275
// cannot define both module m1 and m2 to the same class loader
276
try {
277
ModuleLayer.boot().defineModulesWithOneLoader(cf, null);
278
assertTrue(false);
279
} catch (LayerInstantiationException expected) { }
280
281
// should be okay to have one module per class loader
282
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null);
283
checkLayer(layer, "m1", "m2");
284
}
285
286
287
/**
288
* Test ModuleLayer.defineModulesWithXXX with split delegation.
289
*
290
* Test scenario:
291
* layer1: m1 exports p, m2 exports p
292
* layer2: m3 reads m1, m4 reads m2
293
*/
294
public void testSplitDelegation() {
295
ModuleDescriptor descriptor1
296
= ModuleDescriptor.newModule("m1").exports("p").build();
297
298
ModuleDescriptor descriptor2
299
= ModuleDescriptor.newModule("m2").exports("p").build();
300
301
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
302
303
Configuration cf1 = ModuleLayer.boot()
304
.configuration()
305
.resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
306
307
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);
308
checkLayer(layer1, "m1", "m2");
309
310
ModuleDescriptor descriptor3
311
= ModuleDescriptor.newModule("m3").requires("m1").build();
312
313
ModuleDescriptor descriptor4
314
= ModuleDescriptor.newModule("m4").requires("m2").build();
315
316
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
317
318
Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(),
319
Set.of("m3", "m4"));
320
321
// package p cannot be supplied by two class loaders
322
try {
323
layer1.defineModulesWithOneLoader(cf2, null);
324
assertTrue(false);
325
} catch (LayerInstantiationException expected) { }
326
327
// no split delegation when modules have their own class loader
328
ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
329
checkLayer(layer2, "m3", "m4");
330
}
331
332
333
/**
334
* Test ModuleLayer.defineModulesWithXXX when the modules that override same
335
* named modules in the parent layer.
336
*
337
* Test scenario:
338
* layer1: m1, m2, m3 => same loader
339
* layer2: m1, m2, m4 => same loader
340
*/
341
public void testOverriding1() throws Exception {
342
Configuration cf1 = resolve("m1");
343
344
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);
345
checkLayer(layer1, "m1", "m2", "m3");
346
347
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
348
Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
349
Set.of("m1"));
350
351
ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
352
checkLayer(layer2, "m1", "m2", "m3");
353
invoke(layer1, "m1", "p.Main");
354
355
ClassLoader loader1 = layer1.findLoader("m1");
356
ClassLoader loader2 = layer1.findLoader("m2");
357
ClassLoader loader3 = layer1.findLoader("m3");
358
359
ClassLoader loader4 = layer2.findLoader("m1");
360
ClassLoader loader5 = layer2.findLoader("m2");
361
ClassLoader loader6 = layer2.findLoader("m3");
362
363
assertTrue(loader1 == loader2);
364
assertTrue(loader1 == loader3);
365
366
assertTrue(loader4 == loader5);
367
assertTrue(loader4 == loader6);
368
assertTrue(loader4 != loader1);
369
370
assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
371
assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
372
assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
373
374
assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
375
assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4);
376
assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4);
377
}
378
379
380
/**
381
* Test Layer defineModulesWithXXX when the modules that override same
382
* named modules in the parent layer.
383
*
384
* Test scenario:
385
* layer1: m1, m2, m3 => loader pool
386
* layer2: m1, m2, m3 => loader pool
387
*/
388
public void testOverriding2() throws Exception {
389
Configuration cf1 = resolve("m1");
390
391
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);
392
checkLayer(layer1, "m1", "m2", "m3");
393
394
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
395
Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
396
Set.of("m1"));
397
398
ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
399
checkLayer(layer2, "m1", "m2", "m3");
400
invoke(layer1, "m1", "p.Main");
401
402
ClassLoader loader1 = layer1.findLoader("m1");
403
ClassLoader loader2 = layer1.findLoader("m2");
404
ClassLoader loader3 = layer1.findLoader("m3");
405
406
ClassLoader loader4 = layer2.findLoader("m1");
407
ClassLoader loader5 = layer2.findLoader("m2");
408
ClassLoader loader6 = layer2.findLoader("m3");
409
410
assertTrue(loader4 != loader1);
411
assertTrue(loader5 != loader2);
412
assertTrue(loader6 != loader3);
413
414
assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
415
assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);
416
assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3);
417
418
// p.Main is not visible via loader2
419
try {
420
loader2.loadClass("p.Main");
421
assertTrue(false);
422
} catch (ClassNotFoundException expected) { }
423
424
// w.Hello is not visible via loader2
425
try {
426
loader2.loadClass("w.Hello");
427
assertTrue(false);
428
} catch (ClassNotFoundException expected) { }
429
430
// p.Main is not visible via loader3
431
try {
432
loader3.loadClass("p.Main");
433
assertTrue(false);
434
} catch (ClassNotFoundException expected) { }
435
436
// q.Hello is not visible via loader3
437
try {
438
loader3.loadClass("q.Hello");
439
assertTrue(false);
440
} catch (ClassNotFoundException expected) { }
441
442
443
assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
444
assertTrue(loader5.loadClass("q.Hello").getClassLoader() == loader5);
445
assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);
446
447
// p.Main is not visible via loader5
448
try {
449
loader5.loadClass("p.Main");
450
assertTrue(false);
451
} catch (ClassNotFoundException expected) { }
452
453
// w.Hello is not visible via loader5
454
try {
455
loader5.loadClass("w.Hello");
456
assertTrue(false);
457
} catch (ClassNotFoundException expected) { }
458
459
// p.Main is not visible via loader6
460
try {
461
loader6.loadClass("p.Main");
462
assertTrue(false);
463
} catch (ClassNotFoundException expected) { }
464
465
// q.Hello is not visible via loader6
466
try {
467
loader6.loadClass("q.Hello");
468
assertTrue(false);
469
} catch (ClassNotFoundException expected) { }
470
}
471
472
473
/**
474
* Test ModuleLayer.defineModulesWithXXX when the modules that override same
475
* named modules in the parent layer.
476
*
477
* layer1: m1, m2, m3 => same loader
478
* layer2: m1, m3 => same loader
479
*/
480
public void testOverriding3() throws Exception {
481
Configuration cf1 = resolve("m1");
482
483
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);
484
checkLayer(layer1, "m1", "m2", "m3");
485
486
ModuleFinder finder = finderFor("m1", "m3");
487
488
Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
489
Set.of("m1"));
490
491
ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
492
checkLayer(layer2, "m1", "m3");
493
invoke(layer1, "m1", "p.Main");
494
495
ClassLoader loader1 = layer1.findLoader("m1");
496
ClassLoader loader2 = layer2.findLoader("m1");
497
498
assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
499
assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
500
assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
501
502
assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2);
503
assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1);
504
assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2);
505
}
506
507
508
/**
509
* Test Layer defineModulesWithXXX when the modules that override same
510
* named modules in the parent layer.
511
*
512
* layer1: m1, m2, m3 => loader pool
513
* layer2: m1, m3 => loader pool
514
*/
515
public void testOverriding4() throws Exception {
516
Configuration cf1 = resolve("m1");
517
518
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);
519
checkLayer(layer1, "m1", "m2", "m3");
520
521
ModuleFinder finder = finderFor("m1", "m3");
522
523
Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
524
Set.of("m1"));
525
526
ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
527
checkLayer(layer2, "m1", "m3");
528
invoke(layer1, "m1", "p.Main");
529
530
ClassLoader loader1 = layer1.findLoader("m1");
531
ClassLoader loader2 = layer1.findLoader("m2");
532
ClassLoader loader3 = layer1.findLoader("m3");
533
534
ClassLoader loader4 = layer2.findLoader("m1");
535
ClassLoader loader5 = layer2.findLoader("m2");
536
ClassLoader loader6 = layer2.findLoader("m3");
537
538
assertTrue(loader4 != loader1);
539
assertTrue(loader5 == loader2); // m2 not overridden
540
assertTrue(loader6 != loader3);
541
542
assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
543
assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);
544
assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3);
545
546
assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader2);
547
548
assertTrue(loader3.loadClass("w.Hello").getClassLoader() == loader3);
549
550
assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
551
assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader2);
552
assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader6);
553
554
assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);
555
}
556
557
/**
558
* Basic test for locating resources with a class loader created by
559
* defineModulesWithOneLoader.
560
*/
561
public void testResourcesWithOneLoader() throws Exception {
562
testResourcesWithOneLoader(ClassLoader.getSystemClassLoader());
563
testResourcesWithOneLoader(null);
564
}
565
566
/**
567
* Test locating resources with the class loader created by
568
* defineModulesWithOneLoader. The class loader has the given class
569
* loader as its parent.
570
*/
571
void testResourcesWithOneLoader(ClassLoader parent) throws Exception {
572
Configuration cf = resolve("m1");
573
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent);
574
575
ClassLoader loader = layer.findLoader("m1");
576
assertNotNull(loader);
577
assertTrue(loader.getParent() == parent);
578
579
// check that getResource and getResources are consistent
580
URL url1 = loader.getResource("module-info.class");
581
URL url2 = loader.getResources("module-info.class").nextElement();
582
assertEquals(url1.toURI(), url2.toURI());
583
584
// use getResources to find module-info.class resources
585
Enumeration<URL> urls = loader.getResources("module-info.class");
586
List<String> list = readModuleNames(urls);
587
588
// m1, m2, ... should be first (order not specified)
589
int count = cf.modules().size();
590
cf.modules().stream()
591
.map(ResolvedModule::name)
592
.forEach(mn -> assertTrue(list.indexOf(mn) < count));
593
594
// java.base should be after m1, m2, ...
595
assertTrue(list.indexOf("java.base") >= count);
596
597
// check resources(String)
598
List<String> list2 = loader.resources("module-info.class")
599
.map(this::readModuleName)
600
.collect(Collectors.toList());
601
assertEquals(list2, list);
602
603
// check nulls
604
try {
605
loader.getResource(null);
606
assertTrue(false);
607
} catch (NullPointerException e) { }
608
try {
609
loader.getResources(null);
610
assertTrue(false);
611
} catch (NullPointerException e) { }
612
try {
613
loader.resources(null);
614
assertTrue(false);
615
} catch (NullPointerException e) { }
616
}
617
618
/**
619
* Basic test for locating resources with class loaders created by
620
* defineModulesWithManyLoaders.
621
*/
622
public void testResourcesWithManyLoaders() throws Exception {
623
testResourcesWithManyLoaders(ClassLoader.getSystemClassLoader());
624
testResourcesWithManyLoaders(null);
625
}
626
627
/**
628
* Test locating resources with class loaders created by
629
* defineModulesWithManyLoaders. The class loaders have the given class
630
* loader as their parent.
631
*/
632
void testResourcesWithManyLoaders(ClassLoader parent) throws Exception {
633
Configuration cf = resolve("m1");
634
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, parent);
635
636
for (Module m : layer.modules()) {
637
String name = m.getName();
638
ClassLoader loader = m.getClassLoader();
639
assertNotNull(loader);
640
assertTrue(loader.getParent() == parent);
641
642
// getResource should find the module-info.class for the module
643
URL url = loader.getResource("module-info.class");
644
assertEquals(readModuleName(url), name);
645
646
// list of modules names read from module-info.class
647
Enumeration<URL> urls = loader.getResources("module-info.class");
648
List<String> list = readModuleNames(urls);
649
650
// module should be the first element
651
assertTrue(list.indexOf(name) == 0);
652
653
// the module-info.class for the other modules in the layer
654
// should not be found
655
layer.modules().stream()
656
.map(Module::getName)
657
.filter(mn -> !mn.equals(name))
658
.forEach(mn -> assertTrue(list.indexOf(mn) < 0));
659
660
// java.base cannot be the first element
661
assertTrue(list.indexOf("java.base") > 0);
662
663
// check resources(String)
664
List<String> list2 = loader.resources("module-info.class")
665
.map(this::readModuleName)
666
.collect(Collectors.toList());
667
assertEquals(list2, list);
668
669
// check nulls
670
try {
671
loader.getResource(null);
672
assertTrue(false);
673
} catch (NullPointerException e) { }
674
try {
675
loader.getResources(null);
676
assertTrue(false);
677
} catch (NullPointerException e) { }
678
try {
679
loader.resources(null);
680
assertTrue(false);
681
} catch (NullPointerException e) { }
682
}
683
}
684
685
private List<String> readModuleNames(Enumeration<URL> e) {
686
List<String> list = new ArrayList<>();
687
while (e.hasMoreElements()) {
688
URL url = e.nextElement();
689
list.add(readModuleName(url));
690
}
691
return list;
692
}
693
694
private String readModuleName(URL url) {
695
try (InputStream in = url.openStream()) {
696
ModuleDescriptor descriptor = ModuleDescriptor.read(in);
697
return descriptor.name();
698
} catch (IOException ioe) {
699
throw new UncheckedIOException(ioe);
700
}
701
}
702
703
704
// -- supporting methods --
705
706
707
/**
708
* Resolve the given modules, by name, and returns the resulting
709
* Configuration.
710
*/
711
private static Configuration resolve(String... roots) {
712
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
713
return ModuleLayer.boot()
714
.configuration()
715
.resolve(finder, ModuleFinder.of(), Set.of(roots));
716
}
717
718
/**
719
* Resolve the given modules, by name, and returns the resulting
720
* Configuration.
721
*/
722
private static Configuration resolveAndBind(String... roots) {
723
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
724
return ModuleLayer.boot()
725
.configuration()
726
.resolveAndBind(finder, ModuleFinder.of(), Set.of(roots));
727
}
728
729
730
/**
731
* Invokes the static void main(String[]) method on the given class
732
* in the given module.
733
*/
734
private static void invoke(ModuleLayer layer, String mn, String mc) throws Exception {
735
ClassLoader loader = layer.findLoader(mn);
736
Class<?> c = loader.loadClass(mc);
737
Method mainMethod = c.getMethod("main", String[].class);
738
mainMethod.invoke(null, (Object)new String[0]);
739
}
740
741
742
/**
743
* Checks that the given layer contains exactly the expected modules
744
* (by name).
745
*/
746
private void checkLayer(ModuleLayer layer, String ... expected) {
747
Set<String> names = layer.modules().stream()
748
.map(Module::getName)
749
.collect(Collectors.toSet());
750
assertTrue(names.size() == expected.length);
751
for (String name : expected) {
752
assertTrue(names.contains(name));
753
}
754
}
755
756
757
/**
758
* Test that a class can be loaded via the class loader of all modules
759
* in the given layer.
760
*/
761
static void testLoad(ModuleLayer layer, String cn) throws Exception {
762
for (Module m : layer.modules()) {
763
ClassLoader l = m.getClassLoader();
764
l.loadClass(cn);
765
}
766
}
767
768
769
/**
770
* Test that a class cannot be loaded via any of the class loaders of
771
* the modules in the given layer.
772
*/
773
static void testLoadFail(ModuleLayer layer, String cn) throws Exception {
774
for (Module m : layer.modules()) {
775
ClassLoader l = m.getClassLoader();
776
try {
777
l.loadClass(cn);
778
assertTrue(false);
779
} catch (ClassNotFoundException expected) { }
780
}
781
}
782
783
784
/**
785
* Returns a ModuleFinder that only finds the given test modules
786
*/
787
static ModuleFinder finderFor(String... names) {
788
789
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
790
791
Map<String, ModuleReference> mrefs = new HashMap<>();
792
for (String name : names) {
793
Optional<ModuleReference> omref = finder.find(name);
794
assert omref.isPresent();
795
mrefs.put(name, omref.get());
796
}
797
798
return new ModuleFinder() {
799
@Override
800
public Optional<ModuleReference> find(String name) {
801
ModuleReference mref = mrefs.get(name);
802
return Optional.ofNullable(mref);
803
}
804
@Override
805
public Set<ModuleReference> findAll() {
806
return mrefs.values().stream().collect(Collectors.toSet());
807
}
808
};
809
}
810
811
}
812
813