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 }