1 /* |
|
2 * Copyright (c) 2014, 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 /lib/testlibrary |
|
27 * @modules java.base/jdk.internal.misc |
|
28 * @build BasicLayerTest ModuleUtils |
|
29 * @compile layertest/Test.java |
|
30 * @run testng BasicLayerTest |
|
31 * @summary Basic tests for java.lang.reflect.Layer |
|
32 */ |
|
33 |
|
34 import java.lang.module.Configuration; |
|
35 import java.lang.module.ModuleDescriptor; |
|
36 import java.lang.module.ModuleDescriptor.Requires; |
|
37 import java.lang.module.ModuleFinder; |
|
38 import java.lang.reflect.Layer; |
|
39 import java.lang.reflect.LayerInstantiationException; |
|
40 import java.lang.reflect.Module; |
|
41 import java.util.HashMap; |
|
42 import java.util.Map; |
|
43 import java.util.Optional; |
|
44 import java.util.Set; |
|
45 import java.util.stream.Collectors; |
|
46 |
|
47 import jdk.internal.misc.SharedSecrets; |
|
48 |
|
49 import org.testng.annotations.DataProvider; |
|
50 import org.testng.annotations.Test; |
|
51 import static org.testng.Assert.*; |
|
52 |
|
53 @Test |
|
54 public class BasicLayerTest { |
|
55 |
|
56 /** |
|
57 * Creates a "non-strict" builder for building a module. This allows the |
|
58 * test the create ModuleDescriptor objects that do not require java.base. |
|
59 */ |
|
60 private static ModuleDescriptor.Builder newBuilder(String mn) { |
|
61 return SharedSecrets.getJavaLangModuleAccess() |
|
62 .newModuleBuilder(mn, false, Set.of()); |
|
63 } |
|
64 |
|
65 /** |
|
66 * Exercise Layer.empty() |
|
67 */ |
|
68 public void testEmpty() { |
|
69 Layer emptyLayer = Layer.empty(); |
|
70 |
|
71 assertTrue(emptyLayer.parents().isEmpty()); |
|
72 |
|
73 assertTrue(emptyLayer.configuration() == Configuration.empty()); |
|
74 |
|
75 assertTrue(emptyLayer.modules().isEmpty()); |
|
76 |
|
77 assertFalse(emptyLayer.findModule("java.base").isPresent()); |
|
78 |
|
79 try { |
|
80 emptyLayer.findLoader("java.base"); |
|
81 assertTrue(false); |
|
82 } catch (IllegalArgumentException expected) { } |
|
83 } |
|
84 |
|
85 |
|
86 /** |
|
87 * Exercise Layer.boot() |
|
88 */ |
|
89 public void testBoot() { |
|
90 Layer bootLayer = Layer.boot(); |
|
91 |
|
92 // configuration |
|
93 Configuration cf = bootLayer.configuration(); |
|
94 assertTrue(cf.findModule("java.base").get() |
|
95 .reference() |
|
96 .descriptor() |
|
97 .exports() |
|
98 .stream().anyMatch(e -> (e.source().equals("java.lang") |
|
99 && !e.isQualified()))); |
|
100 |
|
101 // modules |
|
102 Set<Module> modules = bootLayer.modules(); |
|
103 assertTrue(modules.contains(Object.class.getModule())); |
|
104 int count = (int) modules.stream().map(Module::getName).count(); |
|
105 assertEquals(count, modules.size()); // module names are unique |
|
106 |
|
107 // findModule |
|
108 Module base = Object.class.getModule(); |
|
109 assertTrue(bootLayer.findModule("java.base").get() == base); |
|
110 assertTrue(base.getLayer() == bootLayer); |
|
111 |
|
112 // findLoader |
|
113 assertTrue(bootLayer.findLoader("java.base") == null); |
|
114 |
|
115 // parents |
|
116 assertTrue(bootLayer.parents().size() == 1); |
|
117 assertTrue(bootLayer.parents().get(0) == Layer.empty()); |
|
118 } |
|
119 |
|
120 |
|
121 /** |
|
122 * Exercise Layer defineModules, created with empty layer as parent |
|
123 */ |
|
124 public void testLayerOnEmpty() { |
|
125 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
126 .requires("m2") |
|
127 .exports("p1") |
|
128 .build(); |
|
129 |
|
130 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
131 .requires("m3") |
|
132 .build(); |
|
133 |
|
134 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
135 .build(); |
|
136 |
|
137 ModuleFinder finder |
|
138 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); |
|
139 |
|
140 Configuration cf = resolve(finder, "m1"); |
|
141 |
|
142 // map each module to its own class loader for this test |
|
143 ClassLoader loader1 = new ClassLoader() { }; |
|
144 ClassLoader loader2 = new ClassLoader() { }; |
|
145 ClassLoader loader3 = new ClassLoader() { }; |
|
146 Map<String, ClassLoader> map = new HashMap<>(); |
|
147 map.put("m1", loader1); |
|
148 map.put("m2", loader2); |
|
149 map.put("m3", loader3); |
|
150 |
|
151 Layer layer = Layer.empty().defineModules(cf, map::get); |
|
152 |
|
153 // configuration |
|
154 assertTrue(layer.configuration() == cf); |
|
155 assertTrue(layer.configuration().modules().size() == 3); |
|
156 |
|
157 // modules |
|
158 Set<Module> modules = layer.modules(); |
|
159 assertTrue(modules.size() == 3); |
|
160 Set<String> names = modules.stream() |
|
161 .map(Module::getName) |
|
162 .collect(Collectors.toSet()); |
|
163 assertTrue(names.contains("m1")); |
|
164 assertTrue(names.contains("m2")); |
|
165 assertTrue(names.contains("m3")); |
|
166 |
|
167 // findModule |
|
168 Module m1 = layer.findModule("m1").get(); |
|
169 Module m2 = layer.findModule("m2").get(); |
|
170 Module m3 = layer.findModule("m3").get(); |
|
171 assertEquals(m1.getName(), "m1"); |
|
172 assertEquals(m2.getName(), "m2"); |
|
173 assertEquals(m3.getName(), "m3"); |
|
174 assertTrue(m1.getDescriptor() == descriptor1); |
|
175 assertTrue(m2.getDescriptor() == descriptor2); |
|
176 assertTrue(m3.getDescriptor() == descriptor3); |
|
177 assertTrue(m1.getLayer() == layer); |
|
178 assertTrue(m2.getLayer() == layer); |
|
179 assertTrue(m3.getLayer() == layer); |
|
180 assertTrue(modules.contains(m1)); |
|
181 assertTrue(modules.contains(m2)); |
|
182 assertTrue(modules.contains(m3)); |
|
183 assertFalse(layer.findModule("godot").isPresent()); |
|
184 |
|
185 // findLoader |
|
186 assertTrue(layer.findLoader("m1") == loader1); |
|
187 assertTrue(layer.findLoader("m2") == loader2); |
|
188 assertTrue(layer.findLoader("m3") == loader3); |
|
189 try { |
|
190 ClassLoader loader = layer.findLoader("godot"); |
|
191 assertTrue(false); |
|
192 } catch (IllegalArgumentException ignore) { } |
|
193 |
|
194 // parents |
|
195 assertTrue(layer.parents().size() == 1); |
|
196 assertTrue(layer.parents().get(0) == Layer.empty()); |
|
197 } |
|
198 |
|
199 |
|
200 /** |
|
201 * Exercise Layer defineModules, created with boot layer as parent |
|
202 */ |
|
203 public void testLayerOnBoot() { |
|
204 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
205 .requires("m2") |
|
206 .requires("java.base") |
|
207 .exports("p1") |
|
208 .build(); |
|
209 |
|
210 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
211 .requires("java.base") |
|
212 .build(); |
|
213 |
|
214 ModuleFinder finder |
|
215 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
216 |
|
217 Configuration parent = Layer.boot().configuration(); |
|
218 Configuration cf = resolve(parent, finder, "m1"); |
|
219 |
|
220 ClassLoader loader = new ClassLoader() { }; |
|
221 |
|
222 Layer layer = Layer.boot().defineModules(cf, mn -> loader); |
|
223 |
|
224 // configuration |
|
225 assertTrue(layer.configuration() == cf); |
|
226 assertTrue(layer.configuration().modules().size() == 2); |
|
227 |
|
228 // modules |
|
229 Set<Module> modules = layer.modules(); |
|
230 assertTrue(modules.size() == 2); |
|
231 Set<String> names = modules.stream() |
|
232 .map(Module::getName) |
|
233 .collect(Collectors.toSet()); |
|
234 assertTrue(names.contains("m1")); |
|
235 assertTrue(names.contains("m2")); |
|
236 |
|
237 // findModule |
|
238 Module m1 = layer.findModule("m1").get(); |
|
239 Module m2 = layer.findModule("m2").get(); |
|
240 assertEquals(m1.getName(), "m1"); |
|
241 assertEquals(m2.getName(), "m2"); |
|
242 assertTrue(m1.getDescriptor() == descriptor1); |
|
243 assertTrue(m2.getDescriptor() == descriptor2); |
|
244 assertTrue(m1.getLayer() == layer); |
|
245 assertTrue(m2.getLayer() == layer); |
|
246 assertTrue(modules.contains(m1)); |
|
247 assertTrue(modules.contains(m2)); |
|
248 assertTrue(layer.findModule("java.base").get() == Object.class.getModule()); |
|
249 assertFalse(layer.findModule("godot").isPresent()); |
|
250 |
|
251 // findLoader |
|
252 assertTrue(layer.findLoader("m1") == loader); |
|
253 assertTrue(layer.findLoader("m2") == loader); |
|
254 assertTrue(layer.findLoader("java.base") == null); |
|
255 |
|
256 // parents |
|
257 assertTrue(layer.parents().size() == 1); |
|
258 assertTrue(layer.parents().get(0) == Layer.boot()); |
|
259 } |
|
260 |
|
261 |
|
262 /** |
|
263 * Exercise Layer defineModules with a configuration of two modules that |
|
264 * have the same module-private package. |
|
265 */ |
|
266 public void testPackageContainedInSelfAndOther() { |
|
267 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
268 .requires("m2") |
|
269 .packages(Set.of("p")) |
|
270 .build(); |
|
271 |
|
272 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
273 .packages(Set.of("p")) |
|
274 .build(); |
|
275 |
|
276 ModuleFinder finder |
|
277 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
278 |
|
279 Configuration cf = resolve(finder, "m1"); |
|
280 assertTrue(cf.modules().size() == 2); |
|
281 |
|
282 // one loader per module, should be okay |
|
283 Layer.empty().defineModules(cf, mn -> new ClassLoader() { }); |
|
284 |
|
285 // same class loader |
|
286 try { |
|
287 ClassLoader loader = new ClassLoader() { }; |
|
288 Layer.empty().defineModules(cf, mn -> loader); |
|
289 assertTrue(false); |
|
290 } catch (LayerInstantiationException expected) { } |
|
291 } |
|
292 |
|
293 |
|
294 /** |
|
295 * Exercise Layer defineModules with a configuration that is a partitioned |
|
296 * graph. The same package is exported in both partitions. |
|
297 */ |
|
298 public void testSameExportInPartitionedGraph() { |
|
299 |
|
300 // m1 reads m2, m2 exports p to m1 |
|
301 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
302 .requires("m2") |
|
303 .build(); |
|
304 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
305 .exports("p", Set.of("m1")) |
|
306 .build(); |
|
307 |
|
308 // m3 reads m4, m4 exports p to m3 |
|
309 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
310 .requires("m4") |
|
311 .build(); |
|
312 ModuleDescriptor descriptor4 = newBuilder("m4") |
|
313 .exports("p", Set.of("m3")) |
|
314 .build(); |
|
315 |
|
316 ModuleFinder finder |
|
317 = ModuleUtils.finderOf(descriptor1, |
|
318 descriptor2, |
|
319 descriptor3, |
|
320 descriptor4); |
|
321 |
|
322 Configuration cf = resolve(finder, "m1", "m3"); |
|
323 assertTrue(cf.modules().size() == 4); |
|
324 |
|
325 // one loader per module |
|
326 Layer.empty().defineModules(cf, mn -> new ClassLoader() { }); |
|
327 |
|
328 // m1 & m2 in one loader, m3 & m4 in another loader |
|
329 ClassLoader loader1 = new ClassLoader() { }; |
|
330 ClassLoader loader2 = new ClassLoader() { }; |
|
331 Map<String, ClassLoader> map = new HashMap<>(); |
|
332 map.put("m1", loader1); |
|
333 map.put("m2", loader1); |
|
334 map.put("m3", loader2); |
|
335 map.put("m4", loader2); |
|
336 Layer.empty().defineModules(cf, map::get); |
|
337 |
|
338 // same loader |
|
339 try { |
|
340 ClassLoader loader = new ClassLoader() { }; |
|
341 Layer.empty().defineModules(cf, mn -> loader); |
|
342 assertTrue(false); |
|
343 } catch (LayerInstantiationException expected) { } |
|
344 } |
|
345 |
|
346 |
|
347 /** |
|
348 * Exercise Layer defineModules with a configuration with a module that |
|
349 * contains a package that is the same name as a non-exported package in |
|
350 * a parent layer. |
|
351 */ |
|
352 public void testContainsSamePackageAsBootLayer() { |
|
353 |
|
354 // check assumption that java.base contains sun.launcher |
|
355 ModuleDescriptor base = Object.class.getModule().getDescriptor(); |
|
356 assertTrue(base.packages().contains("sun.launcher")); |
|
357 |
|
358 ModuleDescriptor descriptor = newBuilder("m1") |
|
359 .requires("java.base") |
|
360 .packages(Set.of("sun.launcher")) |
|
361 .build(); |
|
362 |
|
363 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
364 |
|
365 Configuration parent = Layer.boot().configuration(); |
|
366 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
367 assertTrue(cf.modules().size() == 1); |
|
368 |
|
369 ClassLoader loader = new ClassLoader() { }; |
|
370 Layer layer = Layer.boot().defineModules(cf, mn -> loader); |
|
371 assertTrue(layer.modules().size() == 1); |
|
372 } |
|
373 |
|
374 |
|
375 /** |
|
376 * Test layers with implied readability. |
|
377 * |
|
378 * The test consists of three configurations: |
|
379 * - Configuration/layer1: m1, m2 requires transitive m1 |
|
380 * - Configuration/layer2: m3 requires m1 |
|
381 */ |
|
382 public void testImpliedReadabilityWithLayers1() { |
|
383 |
|
384 // cf1: m1 and m2, m2 requires transitive m1 |
|
385 |
|
386 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
387 .build(); |
|
388 |
|
389 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
390 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
391 .build(); |
|
392 |
|
393 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
394 |
|
395 Configuration cf1 = resolve(finder1, "m2"); |
|
396 |
|
397 ClassLoader cl1 = new ClassLoader() { }; |
|
398 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
399 |
|
400 |
|
401 // cf2: m3, m3 requires m2 |
|
402 |
|
403 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
404 .requires("m2") |
|
405 .build(); |
|
406 |
|
407 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3); |
|
408 |
|
409 Configuration cf2 = resolve(cf1, finder2, "m3"); |
|
410 |
|
411 ClassLoader cl2 = new ClassLoader() { }; |
|
412 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
413 |
|
414 assertTrue(layer1.parents().size() == 1); |
|
415 assertTrue(layer1.parents().get(0) == Layer.empty()); |
|
416 |
|
417 assertTrue(layer2.parents().size() == 1); |
|
418 assertTrue(layer2.parents().get(0) == layer1); |
|
419 |
|
420 Module m1 = layer2.findModule("m1").get(); |
|
421 Module m2 = layer2.findModule("m2").get(); |
|
422 Module m3 = layer2.findModule("m3").get(); |
|
423 |
|
424 assertTrue(m1.getLayer() == layer1); |
|
425 assertTrue(m2.getLayer() == layer1); |
|
426 assertTrue(m3.getLayer() == layer2); |
|
427 |
|
428 assertTrue(m1.getClassLoader() == cl1); |
|
429 assertTrue(m2.getClassLoader() == cl1); |
|
430 assertTrue(m3.getClassLoader() == cl2); |
|
431 |
|
432 assertTrue(m1.canRead(m1)); |
|
433 assertFalse(m1.canRead(m2)); |
|
434 assertFalse(m1.canRead(m3)); |
|
435 |
|
436 assertTrue(m2.canRead(m1)); |
|
437 assertTrue(m2.canRead(m2)); |
|
438 assertFalse(m2.canRead(m3)); |
|
439 |
|
440 assertTrue(m3.canRead(m1)); |
|
441 assertTrue(m3.canRead(m2)); |
|
442 assertTrue(m3.canRead(m3)); |
|
443 } |
|
444 |
|
445 |
|
446 /** |
|
447 * Test layers with implied readability. |
|
448 * |
|
449 * The test consists of three configurations: |
|
450 * - Configuration/layer1: m1 |
|
451 * - Configuration/layer2: m2 requires transitive m3, m3 requires m2 |
|
452 */ |
|
453 public void testImpliedReadabilityWithLayers2() { |
|
454 |
|
455 // cf1: m1 |
|
456 |
|
457 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
458 |
|
459 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
460 |
|
461 Configuration cf1 = resolve(finder1, "m1"); |
|
462 |
|
463 ClassLoader cl1 = new ClassLoader() { }; |
|
464 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
465 |
|
466 |
|
467 // cf2: m2, m3: m2 requires transitive m1, m3 requires m2 |
|
468 |
|
469 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
470 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
471 .build(); |
|
472 |
|
473 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
474 .requires("m2") |
|
475 .build(); |
|
476 |
|
477 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3); |
|
478 |
|
479 Configuration cf2 = resolve(cf1, finder2, "m3"); |
|
480 |
|
481 ClassLoader cl2 = new ClassLoader() { }; |
|
482 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
483 |
|
484 assertTrue(layer1.parents().size() == 1); |
|
485 assertTrue(layer1.parents().get(0) == Layer.empty()); |
|
486 |
|
487 assertTrue(layer2.parents().size() == 1); |
|
488 assertTrue(layer2.parents().get(0) == layer1); |
|
489 |
|
490 Module m1 = layer2.findModule("m1").get(); |
|
491 Module m2 = layer2.findModule("m2").get(); |
|
492 Module m3 = layer2.findModule("m3").get(); |
|
493 |
|
494 assertTrue(m1.getLayer() == layer1); |
|
495 assertTrue(m2.getLayer() == layer2); |
|
496 assertTrue(m3.getLayer() == layer2); |
|
497 |
|
498 assertTrue(m1.canRead(m1)); |
|
499 assertFalse(m1.canRead(m2)); |
|
500 assertFalse(m1.canRead(m3)); |
|
501 |
|
502 assertTrue(m2.canRead(m1)); |
|
503 assertTrue(m2.canRead(m2)); |
|
504 assertFalse(m2.canRead(m3)); |
|
505 |
|
506 assertTrue(m3.canRead(m1)); |
|
507 assertTrue(m3.canRead(m2)); |
|
508 assertTrue(m3.canRead(m3)); |
|
509 } |
|
510 |
|
511 |
|
512 /** |
|
513 * Test layers with implied readability. |
|
514 * |
|
515 * The test consists of three configurations: |
|
516 * - Configuration/layer1: m1 |
|
517 * - Configuration/layer2: m2 requires transitive m1 |
|
518 * - Configuration/layer3: m3 requires m1 |
|
519 */ |
|
520 public void testImpliedReadabilityWithLayers3() { |
|
521 |
|
522 // cf1: m1 |
|
523 |
|
524 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
525 |
|
526 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
527 |
|
528 Configuration cf1 = resolve(finder1, "m1"); |
|
529 |
|
530 ClassLoader cl1 = new ClassLoader() { }; |
|
531 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
532 |
|
533 |
|
534 // cf2: m2 requires transitive m1 |
|
535 |
|
536 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
537 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
538 .build(); |
|
539 |
|
540 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
541 |
|
542 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
543 |
|
544 ClassLoader cl2 = new ClassLoader() { }; |
|
545 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
546 |
|
547 |
|
548 // cf3: m3 requires m2 |
|
549 |
|
550 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
551 .requires("m2") |
|
552 .build(); |
|
553 |
|
554 ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3); |
|
555 |
|
556 Configuration cf3 = resolve(cf2, finder3, "m3"); |
|
557 |
|
558 ClassLoader cl3 = new ClassLoader() { }; |
|
559 Layer layer3 = layer2.defineModules(cf3, mn -> cl3); |
|
560 |
|
561 assertTrue(layer1.parents().size() == 1); |
|
562 assertTrue(layer1.parents().get(0) == Layer.empty()); |
|
563 |
|
564 assertTrue(layer2.parents().size() == 1); |
|
565 assertTrue(layer2.parents().get(0) == layer1); |
|
566 |
|
567 assertTrue(layer3.parents().size() == 1); |
|
568 assertTrue(layer3.parents().get(0) == layer2); |
|
569 |
|
570 Module m1 = layer3.findModule("m1").get(); |
|
571 Module m2 = layer3.findModule("m2").get(); |
|
572 Module m3 = layer3.findModule("m3").get(); |
|
573 |
|
574 assertTrue(m1.getLayer() == layer1); |
|
575 assertTrue(m2.getLayer() == layer2); |
|
576 assertTrue(m3.getLayer() == layer3); |
|
577 |
|
578 assertTrue(m1.canRead(m1)); |
|
579 assertFalse(m1.canRead(m2)); |
|
580 assertFalse(m1.canRead(m3)); |
|
581 |
|
582 assertTrue(m2.canRead(m1)); |
|
583 assertTrue(m2.canRead(m2)); |
|
584 assertFalse(m2.canRead(m3)); |
|
585 |
|
586 assertTrue(m3.canRead(m1)); |
|
587 assertTrue(m3.canRead(m2)); |
|
588 assertTrue(m3.canRead(m3)); |
|
589 } |
|
590 |
|
591 |
|
592 /** |
|
593 * Test layers with implied readability. |
|
594 * |
|
595 * The test consists of two configurations: |
|
596 * - Configuration/layer1: m1, m2 requires transitive m1 |
|
597 * - Configuration/layer2: m3 requires transitive m2, m4 requires m3 |
|
598 */ |
|
599 public void testImpliedReadabilityWithLayers4() { |
|
600 |
|
601 // cf1: m1, m2 requires transitive m1 |
|
602 |
|
603 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
604 .build(); |
|
605 |
|
606 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
607 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
608 .build(); |
|
609 |
|
610 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
611 |
|
612 Configuration cf1 = resolve(finder1, "m2"); |
|
613 |
|
614 ClassLoader cl1 = new ClassLoader() { }; |
|
615 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
616 |
|
617 |
|
618 // cf2: m3 requires transitive m2, m4 requires m3 |
|
619 |
|
620 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
621 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2") |
|
622 .build(); |
|
623 |
|
624 ModuleDescriptor descriptor4 = newBuilder("m4") |
|
625 .requires("m3") |
|
626 .build(); |
|
627 |
|
628 |
|
629 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4); |
|
630 |
|
631 Configuration cf2 = resolve(cf1, finder2, "m3", "m4"); |
|
632 |
|
633 ClassLoader cl2 = new ClassLoader() { }; |
|
634 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
635 |
|
636 assertTrue(layer1.parents().size() == 1); |
|
637 assertTrue(layer1.parents().get(0) == Layer.empty()); |
|
638 |
|
639 assertTrue(layer2.parents().size() == 1); |
|
640 assertTrue(layer2.parents().get(0) == layer1); |
|
641 |
|
642 Module m1 = layer2.findModule("m1").get(); |
|
643 Module m2 = layer2.findModule("m2").get(); |
|
644 Module m3 = layer2.findModule("m3").get(); |
|
645 Module m4 = layer2.findModule("m4").get(); |
|
646 |
|
647 assertTrue(m1.getLayer() == layer1); |
|
648 assertTrue(m2.getLayer() == layer1); |
|
649 assertTrue(m3.getLayer() == layer2); |
|
650 assertTrue(m4.getLayer() == layer2); |
|
651 |
|
652 assertTrue(m1.canRead(m1)); |
|
653 assertFalse(m1.canRead(m2)); |
|
654 assertFalse(m1.canRead(m3)); |
|
655 assertFalse(m1.canRead(m4)); |
|
656 |
|
657 assertTrue(m2.canRead(m1)); |
|
658 assertTrue(m2.canRead(m2)); |
|
659 assertFalse(m1.canRead(m3)); |
|
660 assertFalse(m1.canRead(m4)); |
|
661 |
|
662 assertTrue(m3.canRead(m1)); |
|
663 assertTrue(m3.canRead(m2)); |
|
664 assertTrue(m3.canRead(m3)); |
|
665 assertFalse(m3.canRead(m4)); |
|
666 |
|
667 assertTrue(m4.canRead(m1)); |
|
668 assertTrue(m4.canRead(m2)); |
|
669 assertTrue(m4.canRead(m3)); |
|
670 assertTrue(m4.canRead(m4)); |
|
671 } |
|
672 |
|
673 |
|
674 /** |
|
675 * Test layers with a qualified export. The module exporting the package |
|
676 * does not read the target module. |
|
677 * |
|
678 * m1 { exports p to m2 } |
|
679 * m2 { } |
|
680 */ |
|
681 public void testQualifiedExports1() { |
|
682 ModuleDescriptor descriptor1 = newBuilder("m1"). |
|
683 exports("p", Set.of("m2")) |
|
684 .build(); |
|
685 |
|
686 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
687 .build(); |
|
688 |
|
689 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
690 |
|
691 Configuration cf = resolve(finder1, "m1", "m2"); |
|
692 |
|
693 ClassLoader cl = new ClassLoader() { }; |
|
694 Layer layer = Layer.empty().defineModules(cf, mn -> cl); |
|
695 assertTrue(layer.modules().size() == 2); |
|
696 |
|
697 Module m1 = layer.findModule("m1").get(); |
|
698 Module m2 = layer.findModule("m2").get(); |
|
699 |
|
700 // check m1 exports p to m2 |
|
701 assertFalse(m1.isExported("p")); |
|
702 assertTrue(m1.isExported("p", m2)); |
|
703 assertFalse(m1.isOpen("p", m2)); |
|
704 } |
|
705 |
|
706 |
|
707 /** |
|
708 * Test layers with a qualified export. The module exporting the package |
|
709 * reads the target module. |
|
710 * |
|
711 * m1 { exports p to m2; } |
|
712 * m2 { requires m1; } |
|
713 */ |
|
714 public void testQualifiedExports2() { |
|
715 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
716 .exports("p", Set.of("m2")) |
|
717 .build(); |
|
718 |
|
719 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
720 .requires("m1") |
|
721 .build(); |
|
722 |
|
723 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
724 |
|
725 Configuration cf = resolve(finder1, "m2"); |
|
726 ClassLoader cl = new ClassLoader() { }; |
|
727 Layer layer = Layer.empty().defineModules(cf, mn -> cl); |
|
728 assertTrue(layer.modules().size() == 2); |
|
729 |
|
730 Module m1 = layer.findModule("m1").get(); |
|
731 Module m2 = layer.findModule("m2").get(); |
|
732 |
|
733 // check m1 exports p to m2 |
|
734 assertFalse(m1.isExported("p")); |
|
735 assertTrue(m1.isExported("p", m2)); |
|
736 assertFalse(m1.isOpen("p", m2)); |
|
737 } |
|
738 |
|
739 |
|
740 /** |
|
741 * Test layers with a qualified export. The module exporting the package |
|
742 * does not read the target module in the parent layer. |
|
743 * |
|
744 * - Configuration/layer1: m1 { } |
|
745 * - Configuration/layer2: m2 { exports p to m1; } |
|
746 */ |
|
747 public void testQualifiedExports3() { |
|
748 // create layer1 with m1 |
|
749 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
750 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
751 Configuration cf1 = resolve(finder1, "m1"); |
|
752 ClassLoader cl1 = new ClassLoader() { }; |
|
753 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
754 assertTrue(layer1.modules().size() == 1); |
|
755 |
|
756 // create layer2 with m2 |
|
757 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
758 .exports("p", Set.of("m1")) |
|
759 .build(); |
|
760 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
761 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
762 ClassLoader cl2 = new ClassLoader() { }; |
|
763 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
764 assertTrue(layer2.modules().size() == 1); |
|
765 |
|
766 Module m1 = layer1.findModule("m1").get(); |
|
767 Module m2 = layer2.findModule("m2").get(); |
|
768 |
|
769 // check m2 exports p to layer1/m1 |
|
770 assertFalse(m2.isExported("p")); |
|
771 assertTrue(m2.isExported("p", m1)); |
|
772 assertFalse(m2.isOpen("p", m1)); |
|
773 } |
|
774 |
|
775 |
|
776 /** |
|
777 * Test layers with a qualified export. The module exporting the package |
|
778 * reads the target module in the parent layer. |
|
779 * |
|
780 * - Configuration/layer1: m1 { } |
|
781 * - Configuration/layer2: m2 { requires m1; exports p to m1; } |
|
782 */ |
|
783 public void testQualifiedExports4() { |
|
784 // create layer1 with m1 |
|
785 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
786 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
787 Configuration cf1 = resolve(finder1, "m1"); |
|
788 ClassLoader cl1 = new ClassLoader() { }; |
|
789 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
790 assertTrue(layer1.modules().size() == 1); |
|
791 |
|
792 // create layer2 with m2 |
|
793 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
794 .requires("m1") |
|
795 .exports("p", Set.of("m1")) |
|
796 .build(); |
|
797 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
798 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
799 ClassLoader cl2 = new ClassLoader() { }; |
|
800 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
801 assertTrue(layer2.modules().size() == 1); |
|
802 |
|
803 Module m1 = layer1.findModule("m1").get(); |
|
804 Module m2 = layer2.findModule("m2").get(); |
|
805 |
|
806 // check m2 exports p to layer1/m1 |
|
807 assertFalse(m2.isExported("p")); |
|
808 assertTrue(m2.isExported("p", m1)); |
|
809 assertFalse(m2.isOpen("p", m1)); |
|
810 } |
|
811 |
|
812 /** |
|
813 * Test layers with a qualified export. The module exporting the package |
|
814 * does not read the target module. |
|
815 * |
|
816 * - Configuration/layer1: m1 |
|
817 * - Configuration/layer2: m1, m2 { exports p to m1; } |
|
818 */ |
|
819 public void testQualifiedExports5() { |
|
820 // create layer1 with m1 |
|
821 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
822 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
823 Configuration cf1 = resolve(finder1, "m1"); |
|
824 ClassLoader cl1 = new ClassLoader() { }; |
|
825 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
826 assertTrue(layer1.modules().size() == 1); |
|
827 |
|
828 // create layer2 with m1 and m2 |
|
829 ModuleDescriptor descriptor2 = newBuilder("m2").exports("p", Set.of("m1")).build(); |
|
830 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
831 Configuration cf2 = resolve(cf1, finder2, "m1", "m2"); |
|
832 ClassLoader cl2 = new ClassLoader() { }; |
|
833 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
834 assertTrue(layer2.modules().size() == 2); |
|
835 |
|
836 Module m1_v1 = layer1.findModule("m1").get(); |
|
837 Module m1_v2 = layer2.findModule("m1").get(); |
|
838 Module m2 = layer2.findModule("m2").get(); |
|
839 |
|
840 // check m2 exports p to layer2/m2 |
|
841 assertFalse(m2.isExported("p")); |
|
842 assertTrue(m2.isExported("p", m1_v2)); |
|
843 assertFalse(m2.isExported("p", m1_v1)); |
|
844 } |
|
845 |
|
846 |
|
847 /** |
|
848 * Test layers with a qualified export. The module exporting the package |
|
849 * reads the target module in the parent layer (due to requires transitive). |
|
850 * |
|
851 * - Configuration/layer1: m1, m2 { requires transitive m1; } |
|
852 * - Configuration/layer2: m1, m3 { requires m2; exports p to m1; } |
|
853 */ |
|
854 public void testQualifiedExports6() { |
|
855 // create layer1 with m1 and m2 |
|
856 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
857 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
858 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
859 .build(); |
|
860 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
861 Configuration cf1 = resolve(finder1, "m2"); |
|
862 ClassLoader loader1 = new ClassLoader() { }; |
|
863 Layer layer1 = Layer.empty().defineModules(cf1, mn -> loader1); |
|
864 assertTrue(layer1.modules().size() == 2); |
|
865 |
|
866 // create layer2 with m1 and m3 |
|
867 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
868 .requires("m2") |
|
869 .exports("p", Set.of("m1")) |
|
870 .build(); |
|
871 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3); |
|
872 Configuration cf2 = resolve(cf1, finder2, "m1", "m3"); |
|
873 ClassLoader loader2 = new ClassLoader() { }; |
|
874 Layer layer2 = layer1.defineModules(cf2, mn -> loader2); |
|
875 assertTrue(layer2.modules().size() == 2); |
|
876 |
|
877 Module m1_v1 = layer1.findModule("m1").get(); |
|
878 Module m2 = layer1.findModule("m2").get(); |
|
879 |
|
880 Module m1_v2 = layer2.findModule("m1").get(); |
|
881 Module m3 = layer2.findModule("m3").get(); |
|
882 |
|
883 assertTrue(m3.canRead(m1_v1)); |
|
884 assertFalse(m3.canRead(m1_v2)); |
|
885 |
|
886 assertFalse(m3.isExported("p")); |
|
887 assertTrue(m3.isExported("p", m1_v1)); |
|
888 assertFalse(m3.isExported("p", m1_v2)); |
|
889 assertFalse(m3.isExported("p", m2)); |
|
890 } |
|
891 |
|
892 |
|
893 /** |
|
894 * Test layers with a qualified export. The target module is not in any layer. |
|
895 * |
|
896 * - Configuration/layer1: m1 { } |
|
897 * - Configuration/layer2: m2 { exports p to m3; } |
|
898 */ |
|
899 public void testQualifiedExports7() { |
|
900 // create layer1 with m1 |
|
901 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
902 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
903 Configuration cf1 = resolve(finder1, "m1"); |
|
904 ClassLoader cl1 = new ClassLoader() { }; |
|
905 Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1); |
|
906 assertTrue(layer1.modules().size() == 1); |
|
907 |
|
908 // create layer2 with m2 |
|
909 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
910 .exports("p", Set.of("m3")) |
|
911 .build(); |
|
912 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
913 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
914 ClassLoader cl2 = new ClassLoader() { }; |
|
915 Layer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
916 assertTrue(layer2.modules().size() == 1); |
|
917 |
|
918 Module m1 = layer1.findModule("m1").get(); |
|
919 Module m2 = layer2.findModule("m2").get(); |
|
920 |
|
921 // check m2 does not export p to anyone |
|
922 assertFalse(m2.isExported("p")); |
|
923 assertFalse(m2.isExported("p", m1)); |
|
924 } |
|
925 |
|
926 /** |
|
927 * Attempt to use Layer defineModules to create a layer with a module |
|
928 * defined to a class loader that already has a module of the same name |
|
929 * defined to the class loader. |
|
930 */ |
|
931 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
932 public void testModuleAlreadyDefinedToLoader() { |
|
933 |
|
934 ModuleDescriptor md = newBuilder("m") |
|
935 .requires("java.base") |
|
936 .build(); |
|
937 |
|
938 ModuleFinder finder = ModuleUtils.finderOf(md); |
|
939 |
|
940 Configuration parent = Layer.boot().configuration(); |
|
941 |
|
942 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m")); |
|
943 |
|
944 ClassLoader loader = new ClassLoader() { }; |
|
945 |
|
946 Layer.boot().defineModules(cf, mn -> loader); |
|
947 |
|
948 // should throw LayerInstantiationException as m1 already defined to loader |
|
949 Layer.boot().defineModules(cf, mn -> loader); |
|
950 |
|
951 } |
|
952 |
|
953 |
|
954 /** |
|
955 * Attempt to use Layer defineModules to create a Layer with a module |
|
956 * containing package {@code p} where the class loader already has a module |
|
957 * defined to it containing package {@code p}. |
|
958 */ |
|
959 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
960 public void testPackageAlreadyInNamedModule() { |
|
961 |
|
962 ModuleDescriptor md1 = newBuilder("m1") |
|
963 .packages(Set.of("p")) |
|
964 .requires("java.base") |
|
965 .build(); |
|
966 |
|
967 ModuleDescriptor md2 = newBuilder("m2") |
|
968 .packages(Set.of("p")) |
|
969 .requires("java.base") |
|
970 .build(); |
|
971 |
|
972 ModuleFinder finder = ModuleUtils.finderOf(md1, md2); |
|
973 |
|
974 ClassLoader loader = new ClassLoader() { }; |
|
975 |
|
976 // define m1 containing package p to class loader |
|
977 |
|
978 Configuration parent = Layer.boot().configuration(); |
|
979 |
|
980 Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
981 |
|
982 Layer layer1 = Layer.boot().defineModules(cf1, mn -> loader); |
|
983 |
|
984 // attempt to define m2 containing package p to class loader |
|
985 |
|
986 Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2")); |
|
987 |
|
988 // should throw exception because p already in m1 |
|
989 Layer layer2 = Layer.boot().defineModules(cf2, mn -> loader); |
|
990 |
|
991 } |
|
992 |
|
993 |
|
994 /** |
|
995 * Attempt to use Layer defineModules to create a Layer with a module |
|
996 * containing a package in which a type is already loaded by the class |
|
997 * loader. |
|
998 */ |
|
999 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
1000 public void testPackageAlreadyInUnnamedModule() throws Exception { |
|
1001 |
|
1002 Class<?> c = layertest.Test.class; |
|
1003 assertFalse(c.getModule().isNamed()); // in unnamed module |
|
1004 |
|
1005 ModuleDescriptor md = newBuilder("m") |
|
1006 .packages(Set.of(c.getPackageName())) |
|
1007 .requires("java.base") |
|
1008 .build(); |
|
1009 |
|
1010 ModuleFinder finder = ModuleUtils.finderOf(md); |
|
1011 |
|
1012 Configuration parent = Layer.boot().configuration(); |
|
1013 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m")); |
|
1014 |
|
1015 Layer.boot().defineModules(cf, mn -> c.getClassLoader()); |
|
1016 } |
|
1017 |
|
1018 |
|
1019 /** |
|
1020 * Attempt to create a Layer with a module named "java.base". |
|
1021 */ |
|
1022 public void testLayerWithJavaBase() { |
|
1023 ModuleDescriptor descriptor = newBuilder("java.base") |
|
1024 .exports("java.lang") |
|
1025 .build(); |
|
1026 |
|
1027 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
1028 |
|
1029 Configuration cf = Layer.boot() |
|
1030 .configuration() |
|
1031 .resolve(finder, ModuleFinder.of(), Set.of("java.base")); |
|
1032 assertTrue(cf.modules().size() == 1); |
|
1033 |
|
1034 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1035 |
|
1036 try { |
|
1037 Layer.boot().defineModules(cf, mn -> new ClassLoader() { }); |
|
1038 assertTrue(false); |
|
1039 } catch (LayerInstantiationException e) { } |
|
1040 |
|
1041 try { |
|
1042 Layer.boot().defineModulesWithOneLoader(cf, scl); |
|
1043 assertTrue(false); |
|
1044 } catch (LayerInstantiationException e) { } |
|
1045 |
|
1046 try { |
|
1047 Layer.boot().defineModulesWithManyLoaders(cf, scl); |
|
1048 assertTrue(false); |
|
1049 } catch (LayerInstantiationException e) { } |
|
1050 } |
|
1051 |
|
1052 |
|
1053 @DataProvider(name = "javaPackages") |
|
1054 public Object[][] javaPackages() { |
|
1055 return new Object[][] { { "m1", "java" }, { "m2", "java.x" } }; |
|
1056 } |
|
1057 |
|
1058 /** |
|
1059 * Attempt to create a Layer with a module containing a "java" package. |
|
1060 * This should only be allowed when the module is defined to the platform |
|
1061 * class loader. |
|
1062 */ |
|
1063 @Test(dataProvider = "javaPackages") |
|
1064 public void testLayerWithJavaPackage(String mn, String pn) { |
|
1065 ModuleDescriptor descriptor = newBuilder(mn).packages(Set.of(pn)).build(); |
|
1066 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
1067 |
|
1068 Configuration cf = Layer.boot() |
|
1069 .configuration() |
|
1070 .resolve(finder, ModuleFinder.of(), Set.of(mn)); |
|
1071 assertTrue(cf.modules().size() == 1); |
|
1072 |
|
1073 ClassLoader pcl = ClassLoader.getPlatformClassLoader(); |
|
1074 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1075 |
|
1076 try { |
|
1077 Layer.boot().defineModules(cf, _mn -> new ClassLoader() { }); |
|
1078 assertTrue(false); |
|
1079 } catch (LayerInstantiationException e) { } |
|
1080 |
|
1081 try { |
|
1082 Layer.boot().defineModulesWithOneLoader(cf, scl); |
|
1083 assertTrue(false); |
|
1084 } catch (LayerInstantiationException e) { } |
|
1085 |
|
1086 try { |
|
1087 Layer.boot().defineModulesWithManyLoaders(cf, scl); |
|
1088 assertTrue(false); |
|
1089 } catch (LayerInstantiationException e) { } |
|
1090 |
|
1091 // create layer with module defined to platform class loader |
|
1092 Layer layer = Layer.boot().defineModules(cf, _mn -> pcl); |
|
1093 Optional<Module> om = layer.findModule(mn); |
|
1094 assertTrue(om.isPresent()); |
|
1095 Module foo = om.get(); |
|
1096 assertTrue(foo.getClassLoader() == pcl); |
|
1097 assertTrue(foo.getPackages().length == 1); |
|
1098 assertTrue(foo.getPackages()[0].equals(pn)); |
|
1099 } |
|
1100 |
|
1101 |
|
1102 /** |
|
1103 * Attempt to create a Layer with a module defined to the boot loader |
|
1104 */ |
|
1105 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
1106 public void testLayerWithBootLoader() { |
|
1107 ModuleDescriptor descriptor = newBuilder("m1") |
|
1108 .build(); |
|
1109 |
|
1110 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
1111 |
|
1112 Configuration cf = Layer.boot() |
|
1113 .configuration() |
|
1114 .resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
1115 assertTrue(cf.modules().size() == 1); |
|
1116 |
|
1117 Layer.boot().defineModules(cf, mn -> null ); |
|
1118 } |
|
1119 |
|
1120 |
|
1121 /** |
|
1122 * Parent of configuration != configuration of parent Layer |
|
1123 */ |
|
1124 @Test(expectedExceptions = { IllegalArgumentException.class }) |
|
1125 public void testIncorrectParent1() { |
|
1126 |
|
1127 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
1128 .requires("java.base") |
|
1129 .build(); |
|
1130 |
|
1131 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); |
|
1132 |
|
1133 Configuration parent = Layer.boot().configuration(); |
|
1134 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
1135 |
|
1136 ClassLoader loader = new ClassLoader() { }; |
|
1137 Layer.empty().defineModules(cf, mn -> loader); |
|
1138 } |
|
1139 |
|
1140 |
|
1141 /** |
|
1142 * Parent of configuration != configuration of parent Layer |
|
1143 */ |
|
1144 @Test(expectedExceptions = { IllegalArgumentException.class }) |
|
1145 public void testIncorrectParent2() { |
|
1146 |
|
1147 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
1148 .build(); |
|
1149 |
|
1150 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); |
|
1151 |
|
1152 Configuration cf = resolve(finder, "m1"); |
|
1153 |
|
1154 ClassLoader loader = new ClassLoader() { }; |
|
1155 Layer.boot().defineModules(cf, mn -> loader); |
|
1156 } |
|
1157 |
|
1158 |
|
1159 // null handling |
|
1160 |
|
1161 @Test(expectedExceptions = { NullPointerException.class }) |
|
1162 public void testCreateWithNull1() { |
|
1163 ClassLoader loader = new ClassLoader() { }; |
|
1164 Layer.empty().defineModules(null, mn -> loader); |
|
1165 } |
|
1166 |
|
1167 @Test(expectedExceptions = { NullPointerException.class }) |
|
1168 public void testCreateWithNull2() { |
|
1169 Configuration cf = resolve(Layer.boot().configuration(), ModuleFinder.of()); |
|
1170 Layer.boot().defineModules(cf, null); |
|
1171 } |
|
1172 |
|
1173 @Test(expectedExceptions = { NullPointerException.class }) |
|
1174 public void testCreateWithNull3() { |
|
1175 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1176 Layer.empty().defineModulesWithOneLoader(null, scl); |
|
1177 } |
|
1178 |
|
1179 @Test(expectedExceptions = { NullPointerException.class }) |
|
1180 public void testCreateWithNull4() { |
|
1181 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1182 Layer.empty().defineModulesWithManyLoaders(null, scl); |
|
1183 } |
|
1184 |
|
1185 @Test(expectedExceptions = { NullPointerException.class }) |
|
1186 public void testFindModuleWithNull() { |
|
1187 Layer.boot().findModule(null); |
|
1188 } |
|
1189 |
|
1190 @Test(expectedExceptions = { NullPointerException.class }) |
|
1191 public void testFindLoaderWithNull() { |
|
1192 Layer.boot().findLoader(null); |
|
1193 } |
|
1194 |
|
1195 |
|
1196 // immutable sets |
|
1197 |
|
1198 @Test(expectedExceptions = { UnsupportedOperationException.class }) |
|
1199 public void testImmutableSet() { |
|
1200 Module base = Object.class.getModule(); |
|
1201 Layer.boot().modules().add(base); |
|
1202 } |
|
1203 |
|
1204 |
|
1205 /** |
|
1206 * Resolve the given modules, by name, and returns the resulting |
|
1207 * Configuration. |
|
1208 */ |
|
1209 private static Configuration resolve(Configuration cf, |
|
1210 ModuleFinder finder, |
|
1211 String... roots) { |
|
1212 return cf.resolve(finder, ModuleFinder.of(), Set.of(roots)); |
|
1213 } |
|
1214 |
|
1215 private static Configuration resolve(ModuleFinder finder, |
|
1216 String... roots) { |
|
1217 return resolve(Configuration.empty(), finder, roots); |
|
1218 } |
|
1219 } |
|