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