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 73 /** 74 * Exercise Layer.boot() 75 */ 76 public void testBoot() { 77 Layer bootLayer = Layer.boot(); 78 79 // configuration 80 Configuration cf = bootLayer.configuration(); 81 assertTrue(cf.findModule("java.base").get() 82 .reference() 83 .descriptor() 84 .exports() 85 .stream().anyMatch(e -> (e.source().equals("java.lang") 86 && !e.isQualified()))); 87 88 // modules 89 Set<Module> modules = bootLayer.modules(); 90 assertTrue(modules.contains(Object.class.getModule())); 91 int count = (int) modules.stream().map(Module::getName).count(); 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() 151 .map(Module::getName) 152 .collect(Collectors.toSet()); 153 assertTrue(names.contains("m1")); 154 assertTrue(names.contains("m2")); 155 assertTrue(names.contains("m3")); 156 157 // findModule 158 Module m1 = layer.findModule("m1").get(); 159 Module m2 = layer.findModule("m2").get(); 160 Module m3 = layer.findModule("m3").get(); 161 assertEquals(m1.getName(), "m1"); 162 assertEquals(m2.getName(), "m2"); 163 assertEquals(m3.getName(), "m3"); 164 assertTrue(m1.getDescriptor() == descriptor1); 165 assertTrue(m2.getDescriptor() == descriptor2); 166 assertTrue(m3.getDescriptor() == descriptor3); 167 assertTrue(m1.getLayer() == layer); 168 assertTrue(m2.getLayer() == layer); 169 assertTrue(m3.getLayer() == layer); 170 assertTrue(modules.contains(m1)); 171 assertTrue(modules.contains(m2)); 172 assertTrue(modules.contains(m3)); 173 assertFalse(layer.findModule("godot").isPresent()); 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(); 231 Module m2 = layer.findModule("m2").get(); 232 assertEquals(m1.getName(), "m1"); 233 assertEquals(m2.getName(), "m2"); 234 assertTrue(m1.getDescriptor() == descriptor1); 235 assertTrue(m2.getDescriptor() == descriptor2); 236 assertTrue(m1.getLayer() == layer); 237 assertTrue(m2.getLayer() == layer); 238 assertTrue(modules.contains(m1)); 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); 432 assertTrue(m3.getClassLoader() == cl2); 433 434 assertTrue(m1.canRead(m1)); 435 assertFalse(m1.canRead(m2)); 436 assertFalse(m1.canRead(m3)); 437 438 assertTrue(m2.canRead(m1)); 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)); 506 assertFalse(m1.canRead(m3)); 507 508 assertTrue(m2.canRead(m1)); 509 assertTrue(m2.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); 587 588 assertTrue(m1.canRead(m1)); 589 assertFalse(m1.canRead(m2)); 590 assertFalse(m1.canRead(m3)); 591 592 assertTrue(m2.canRead(m1)); 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 666 assertTrue(m1.canRead(m1)); 667 assertFalse(m1.canRead(m2)); 668 assertFalse(m1.canRead(m3)); 669 assertFalse(m1.canRead(m4)); 670 671 assertTrue(m2.canRead(m1)); 672 assertTrue(m2.canRead(m2)); 673 assertFalse(m1.canRead(m3)); 674 assertFalse(m1.canRead(m4)); 675 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 }