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