1 /* 2 * Copyright (c) 2015, 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 /test/lib 27 * @modules jdk.compiler 28 * @build LayerAndLoadersTest jdk.test.lib.compiler.CompilerUtils ModuleUtils 29 * @run testng LayerAndLoadersTest 30 * @summary Tests for java.lang.ModuleLayer@defineModulesWithXXX methods 31 */ 32 33 import java.io.IOException; 34 import java.io.InputStream; 35 import java.lang.module.Configuration; 36 import java.lang.module.ModuleDescriptor; 37 import java.lang.module.ModuleFinder; 38 import java.lang.module.ModuleReference; 39 import java.lang.reflect.Method; 40 import java.net.URL; 41 import java.nio.file.Path; 42 import java.nio.file.Paths; 43 import java.util.Enumeration; 44 import java.util.HashMap; 45 import java.util.Iterator; 46 import java.util.Map; 47 import java.util.Optional; 48 import java.util.ServiceLoader; 49 import java.util.Set; 50 import java.util.stream.Collectors; 51 import jdk.test.lib.compiler.CompilerUtils; 52 53 import org.testng.annotations.BeforeTest; 54 import org.testng.annotations.Test; 55 import static org.testng.Assert.*; 56 57 @Test 58 public class LayerAndLoadersTest { 59 60 private static final String TEST_SRC = System.getProperty("test.src"); 61 62 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 63 private static final Path MODS_DIR = Paths.get("mods"); 64 65 @BeforeTest 66 public void setup() throws Exception { 67 68 // javac -d mods --module-source-path src src/** 69 assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR, 70 "--module-source-path", SRC_DIR.toString())); 71 } 72 73 74 /** 75 * Basic test of ModuleLayer.defineModulesWithOneLoader 76 * 77 * Test scenario: 78 * m1 requires m2 and m3 79 */ 80 public void testWithOneLoader() throws Exception { 81 82 Configuration cf = resolve("m1"); 83 84 ClassLoader scl = ClassLoader.getSystemClassLoader(); 85 86 ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl); 87 88 checkLayer(layer, "m1", "m2", "m3"); 89 90 ClassLoader cl1 = layer.findLoader("m1"); 91 ClassLoader cl2 = layer.findLoader("m2"); 92 ClassLoader cl3 = layer.findLoader("m3"); 93 94 assertTrue(cl1.getParent() == scl); 95 assertTrue(cl2 == cl1); 96 assertTrue(cl3 == cl1); 97 98 invoke(layer, "m1", "p.Main"); 99 100 } 101 102 103 /** 104 * Basic test of ModuleLayer.defineModulesWithManyLoaders 105 * 106 * Test scenario: 107 * m1 requires m2 and m3 108 */ 109 public void testWithManyLoaders() throws Exception { 110 111 Configuration cf = resolve("m1"); 112 113 ClassLoader scl = ClassLoader.getSystemClassLoader(); 114 115 ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl); 116 117 checkLayer(layer, "m1", "m2", "m3"); 118 119 ClassLoader cl1 = layer.findLoader("m1"); 120 ClassLoader cl2 = layer.findLoader("m2"); 121 ClassLoader cl3 = layer.findLoader("m3"); 122 123 assertTrue(cl1.getParent() == scl); 124 assertTrue(cl2.getParent() == scl); 125 assertTrue(cl3.getParent() == scl); 126 assertTrue(cl2 != cl1); 127 assertTrue(cl3 != cl1); 128 assertTrue(cl3 != cl2); 129 130 invoke(layer, "m1", "p.Main"); 131 132 } 133 134 135 /** 136 * Basic test of ModuleLayer.defineModulesWithOneLoader where one of the 137 * modules is a service provider module. 138 * 139 * Test scenario: 140 * m1 requires m2 and m3 141 * m1 uses S 142 * m4 provides S with ... 143 */ 144 public void testServicesWithOneLoader() throws Exception { 145 146 Configuration cf = resolveAndBind("m1"); 147 148 ClassLoader scl = ClassLoader.getSystemClassLoader(); 149 150 ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl); 151 152 checkLayer(layer, "m1", "m2", "m3", "m4"); 153 154 ClassLoader cl1 = layer.findLoader("m1"); 155 ClassLoader cl2 = layer.findLoader("m2"); 156 ClassLoader cl3 = layer.findLoader("m3"); 157 ClassLoader cl4 = layer.findLoader("m4"); 158 159 assertTrue(cl1.getParent() == scl); 160 assertTrue(cl2 == cl1); 161 assertTrue(cl3 == cl1); 162 assertTrue(cl4 == cl1); 163 164 Class<?> serviceType = cl1.loadClass("p.Service"); 165 assertTrue(serviceType.getClassLoader() == cl1); 166 167 Iterator<?> iter = ServiceLoader.load(serviceType, cl1).iterator(); 168 Object provider = iter.next(); 169 assertTrue(serviceType.isInstance(provider)); 170 assertTrue(provider.getClass().getClassLoader() == cl1); 171 assertFalse(iter.hasNext()); 172 173 } 174 175 176 /** 177 * Basic test of ModuleLayer.defineModulesWithManyLoaders where one of the 178 * modules is a service provider module. 179 * 180 * Test scenario: 181 * m1 requires m2 and m3 182 * m1 uses S 183 * m4 provides S with ... 184 */ 185 public void testServicesWithManyLoaders() throws Exception { 186 187 Configuration cf = resolveAndBind("m1"); 188 189 ClassLoader scl = ClassLoader.getSystemClassLoader(); 190 191 ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl); 192 193 checkLayer(layer, "m1", "m2", "m3", "m4"); 194 195 ClassLoader cl1 = layer.findLoader("m1"); 196 ClassLoader cl2 = layer.findLoader("m2"); 197 ClassLoader cl3 = layer.findLoader("m3"); 198 ClassLoader cl4 = layer.findLoader("m4"); 199 200 assertTrue(cl1.getParent() == scl); 201 assertTrue(cl2.getParent() == scl); 202 assertTrue(cl3.getParent() == scl); 203 assertTrue(cl4.getParent() == scl); 204 assertTrue(cl2 != cl1); 205 assertTrue(cl3 != cl1); 206 assertTrue(cl3 != cl2); 207 assertTrue(cl4 != cl1); 208 assertTrue(cl4 != cl2); 209 assertTrue(cl4 != cl3); 210 211 Class<?> serviceType = cl1.loadClass("p.Service"); 212 assertTrue(serviceType.getClassLoader() == cl1); 213 214 // Test that the service provider can be located via any of 215 // the class loaders in the layer 216 for (Module m : layer.modules()) { 217 ClassLoader loader = m.getClassLoader(); 218 Iterator<?> iter = ServiceLoader.load(serviceType, loader).iterator(); 219 Object provider = iter.next(); 220 assertTrue(serviceType.isInstance(provider)); 221 assertTrue(provider.getClass().getClassLoader() == cl4); 222 assertFalse(iter.hasNext()); 223 } 224 225 } 226 227 228 /** 229 * Tests that the class loaders created by defineModulesWithXXX delegate 230 * to the given parent class loader. 231 */ 232 public void testDelegationToParent() throws Exception { 233 234 Configuration cf = resolve("m1"); 235 236 ClassLoader parent = this.getClass().getClassLoader(); 237 String cn = this.getClass().getName(); 238 239 // one loader 240 ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent); 241 testLoad(layer, cn); 242 243 // one loader with boot loader as parent 244 layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, null); 245 testLoadFail(layer, cn); 246 247 // many loaders 248 layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, parent); 249 testLoad(layer, cn); 250 251 // many loader with boot loader as parent 252 layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null); 253 testLoadFail(layer, cn); 254 255 } 256 257 258 /** 259 * Test defineModulesWithXXX when modules that have overlapping packages. 260 * 261 * Test scenario: 262 * m1 exports p 263 * m2 exports p 264 */ 265 public void testOverlappingPackages() { 266 267 ModuleDescriptor descriptor1 268 = ModuleDescriptor.newModule("m1").exports("p").build(); 269 270 ModuleDescriptor descriptor2 271 = ModuleDescriptor.newModule("m2").exports("p").build(); 272 273 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 274 275 Configuration cf = ModuleLayer.boot() 276 .configuration() 277 .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2")); 278 279 // cannot define both module m1 and m2 to the same class loader 280 try { 281 ModuleLayer.boot().defineModulesWithOneLoader(cf, null); 282 assertTrue(false); 283 } catch (LayerInstantiationException expected) { } 284 285 // should be okay to have one module per class loader 286 ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null); 287 checkLayer(layer, "m1", "m2"); 288 289 } 290 291 292 /** 293 * Test ModuleLayer.defineModulesWithXXX with split delegation. 294 * 295 * Test scenario: 296 * layer1: m1 exports p, m2 exports p 297 * layer2: m3 reads m1, m4 reads m2 298 */ 299 public void testSplitDelegation() { 300 301 ModuleDescriptor descriptor1 302 = ModuleDescriptor.newModule("m1").exports("p").build(); 303 304 ModuleDescriptor descriptor2 305 = ModuleDescriptor.newModule("m2").exports("p").build(); 306 307 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 308 309 Configuration cf1 = ModuleLayer.boot() 310 .configuration() 311 .resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2")); 312 313 ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null); 314 checkLayer(layer1, "m1", "m2"); 315 316 ModuleDescriptor descriptor3 317 = ModuleDescriptor.newModule("m3").requires("m1").build(); 318 319 ModuleDescriptor descriptor4 320 = ModuleDescriptor.newModule("m4").requires("m2").build(); 321 322 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4); 323 324 Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(), 325 Set.of("m3", "m4")); 326 327 // package p cannot be supplied by two class loaders 328 try { 329 layer1.defineModulesWithOneLoader(cf2, null); 330 assertTrue(false); 331 } catch (LayerInstantiationException expected) { } 332 333 // no split delegation when modules have their own class loader 334 ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null); 335 checkLayer(layer2, "m3", "m4"); 336 337 } 338 339 340 /** 341 * Test ModuleLayer.defineModulesWithXXX when the modules that override same 342 * named modules in the parent layer. 343 * 344 * Test scenario: 345 * layer1: m1, m2, m3 => same loader 346 * layer2: m1, m2, m4 => same loader 347 */ 348 public void testOverriding1() throws Exception { 349 350 Configuration cf1 = resolve("m1"); 351 352 ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null); 353 checkLayer(layer1, "m1", "m2", "m3"); 354 355 ModuleFinder finder = ModuleFinder.of(MODS_DIR); 356 Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(), 357 Set.of("m1")); 358 359 ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null); 360 checkLayer(layer2, "m1", "m2", "m3"); 361 invoke(layer1, "m1", "p.Main"); 362 363 ClassLoader loader1 = layer1.findLoader("m1"); 364 ClassLoader loader2 = layer1.findLoader("m2"); 365 ClassLoader loader3 = layer1.findLoader("m3"); 366 367 ClassLoader loader4 = layer2.findLoader("m1"); 368 ClassLoader loader5 = layer2.findLoader("m2"); 369 ClassLoader loader6 = layer2.findLoader("m3"); 370 371 assertTrue(loader1 == loader2); 372 assertTrue(loader1 == loader3); 373 374 assertTrue(loader4 == loader5); 375 assertTrue(loader4 == loader6); 376 assertTrue(loader4 != loader1); 377 378 assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1); 379 assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1); 380 assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1); 381 382 assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4); 383 assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4); 384 assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4); 385 386 } 387 388 389 /** 390 * Test Layer defineModulesWithXXX when the modules that override same 391 * named modules in the parent layer. 392 * 393 * Test scenario: 394 * layer1: m1, m2, m3 => loader pool 395 * layer2: m1, m2, m3 => loader pool 396 */ 397 public void testOverriding2() throws Exception { 398 399 Configuration cf1 = resolve("m1"); 400 401 ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null); 402 checkLayer(layer1, "m1", "m2", "m3"); 403 404 ModuleFinder finder = ModuleFinder.of(MODS_DIR); 405 Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(), 406 Set.of("m1")); 407 408 ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null); 409 checkLayer(layer2, "m1", "m2", "m3"); 410 invoke(layer1, "m1", "p.Main"); 411 412 ClassLoader loader1 = layer1.findLoader("m1"); 413 ClassLoader loader2 = layer1.findLoader("m2"); 414 ClassLoader loader3 = layer1.findLoader("m3"); 415 416 ClassLoader loader4 = layer2.findLoader("m1"); 417 ClassLoader loader5 = layer2.findLoader("m2"); 418 ClassLoader loader6 = layer2.findLoader("m3"); 419 420 assertTrue(loader4 != loader1); 421 assertTrue(loader5 != loader2); 422 assertTrue(loader6 != loader3); 423 424 assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1); 425 assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2); 426 assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3); 427 428 // p.Main is not visible via loader2 429 try { 430 loader2.loadClass("p.Main"); 431 assertTrue(false); 432 } catch (ClassNotFoundException expected) { } 433 434 // w.Hello is not visible via loader2 435 try { 436 loader2.loadClass("w.Hello"); 437 assertTrue(false); 438 } catch (ClassNotFoundException expected) { } 439 440 // p.Main is not visible via loader3 441 try { 442 loader3.loadClass("p.Main"); 443 assertTrue(false); 444 } catch (ClassNotFoundException expected) { } 445 446 // q.Hello is not visible via loader3 447 try { 448 loader3.loadClass("q.Hello"); 449 assertTrue(false); 450 } catch (ClassNotFoundException expected) { } 451 452 453 assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4); 454 assertTrue(loader5.loadClass("q.Hello").getClassLoader() == loader5); 455 assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6); 456 457 // p.Main is not visible via loader5 458 try { 459 loader5.loadClass("p.Main"); 460 assertTrue(false); 461 } catch (ClassNotFoundException expected) { } 462 463 // w.Hello is not visible via loader5 464 try { 465 loader5.loadClass("w.Hello"); 466 assertTrue(false); 467 } catch (ClassNotFoundException expected) { } 468 469 // p.Main is not visible via loader6 470 try { 471 loader6.loadClass("p.Main"); 472 assertTrue(false); 473 } catch (ClassNotFoundException expected) { } 474 475 // q.Hello is not visible via loader6 476 try { 477 loader6.loadClass("q.Hello"); 478 assertTrue(false); 479 } catch (ClassNotFoundException expected) { } 480 481 } 482 483 484 /** 485 * Test ModuleLayer.defineModulesWithXXX when the modules that override same 486 * named modules in the parent layer. 487 * 488 * layer1: m1, m2, m3 => same loader 489 * layer2: m1, m3 => same loader 490 */ 491 public void testOverriding3() throws Exception { 492 493 Configuration cf1 = resolve("m1"); 494 495 ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null); 496 checkLayer(layer1, "m1", "m2", "m3"); 497 498 ModuleFinder finder = finderFor("m1", "m3"); 499 500 Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(), 501 Set.of("m1")); 502 503 ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null); 504 checkLayer(layer2, "m1", "m3"); 505 invoke(layer1, "m1", "p.Main"); 506 507 ClassLoader loader1 = layer1.findLoader("m1"); 508 ClassLoader loader2 = layer2.findLoader("m1"); 509 510 assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1); 511 assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1); 512 assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1); 513 514 assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2); 515 assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1); 516 assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2); 517 518 } 519 520 521 /** 522 * Test Layer defineModulesWithXXX when the modules that override same 523 * named modules in the parent layer. 524 * 525 * layer1: m1, m2, m3 => loader pool 526 * layer2: m1, m3 => loader pool 527 */ 528 public void testOverriding4() throws Exception { 529 530 Configuration cf1 = resolve("m1"); 531 532 ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null); 533 checkLayer(layer1, "m1", "m2", "m3"); 534 535 ModuleFinder finder = finderFor("m1", "m3"); 536 537 Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(), 538 Set.of("m1")); 539 540 ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null); 541 checkLayer(layer2, "m1", "m3"); 542 invoke(layer1, "m1", "p.Main"); 543 544 ClassLoader loader1 = layer1.findLoader("m1"); 545 ClassLoader loader2 = layer1.findLoader("m2"); 546 ClassLoader loader3 = layer1.findLoader("m3"); 547 548 ClassLoader loader4 = layer2.findLoader("m1"); 549 ClassLoader loader5 = layer2.findLoader("m2"); 550 ClassLoader loader6 = layer2.findLoader("m3"); 551 552 assertTrue(loader4 != loader1); 553 assertTrue(loader5 == loader2); // m2 not overridden 554 assertTrue(loader6 != loader3); 555 556 assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1); 557 assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2); 558 assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3); 559 560 assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader2); 561 562 assertTrue(loader3.loadClass("w.Hello").getClassLoader() == loader3); 563 564 assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4); 565 assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader2); 566 assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader6); 567 568 assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6); 569 570 } 571 572 573 /** 574 * Basic test of resource loading with a class loader created by 575 * Layer.defineModulesWithOneLoader. 576 */ 577 public void testResourcesOneLoader() throws Exception { 578 Configuration cf = resolve("m1"); 579 ClassLoader scl = ClassLoader.getSystemClassLoader(); 580 ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl); 581 ClassLoader loader = layer.findLoader("m1"); 582 testResourceLoading(loader, "p/Main.class"); 583 } 584 585 /** 586 * Basic test of resource loading with a class loader created by 587 * Layer.defineModulesWithOneLoader. 588 */ 589 public void testResourcesManyLoaders() throws Exception { 590 Configuration cf = resolve("m1"); 591 ClassLoader scl = ClassLoader.getSystemClassLoader(); 592 ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl); 593 ClassLoader loader = layer.findLoader("m1"); 594 testResourceLoading(loader, "p/Main.class"); 595 } 596 597 /** 598 * Test that a resource is located by a class loader. 599 */ 600 private void testResourceLoading(ClassLoader loader, String name) 601 throws IOException 602 { 603 URL url = loader.getResource(name); 604 assertNotNull(url); 605 606 try (InputStream in = loader.getResourceAsStream(name)) { 607 assertNotNull(in); 608 } 609 610 Enumeration<URL> urls = loader.getResources(name); 611 assertTrue(urls.hasMoreElements()); 612 } 613 614 615 // -- supporting methods -- 616 617 618 /** 619 * Resolve the given modules, by name, and returns the resulting 620 * Configuration. 621 */ 622 private static Configuration resolve(String... roots) { 623 ModuleFinder finder = ModuleFinder.of(MODS_DIR); 624 return ModuleLayer.boot() 625 .configuration() 626 .resolve(finder, ModuleFinder.of(), Set.of(roots)); 627 } 628 629 /** 630 * Resolve the given modules, by name, and returns the resulting 631 * Configuration. 632 */ 633 private static Configuration resolveAndBind(String... roots) { 634 ModuleFinder finder = ModuleFinder.of(MODS_DIR); 635 return ModuleLayer.boot() 636 .configuration() 637 .resolveAndBind(finder, ModuleFinder.of(), Set.of(roots)); 638 } 639 640 641 /** 642 * Invokes the static void main(String[]) method on the given class 643 * in the given module. 644 */ 645 private static void invoke(ModuleLayer layer, String mn, String mc) throws Exception { 646 ClassLoader loader = layer.findLoader(mn); 647 Class<?> c = loader.loadClass(mc); 648 Method mainMethod = c.getMethod("main", String[].class); 649 mainMethod.invoke(null, (Object)new String[0]); 650 } 651 652 653 /** 654 * Checks that the given layer contains exactly the expected modules 655 * (by name). 656 */ 657 private void checkLayer(ModuleLayer layer, String ... expected) { 658 Set<String> names = layer.modules().stream() 659 .map(Module::getName) 660 .collect(Collectors.toSet()); 661 assertTrue(names.size() == expected.length); 662 for (String name : expected) { 663 assertTrue(names.contains(name)); 664 } 665 } 666 667 668 /** 669 * Test that a class can be loaded via the class loader of all modules 670 * in the given layer. 671 */ 672 static void testLoad(ModuleLayer layer, String cn) throws Exception { 673 for (Module m : layer.modules()) { 674 ClassLoader l = m.getClassLoader(); 675 l.loadClass(cn); 676 } 677 } 678 679 680 /** 681 * Test that a class cannot be loaded via any of the class loaders of 682 * the modules in the given layer. 683 */ 684 static void testLoadFail(ModuleLayer layer, String cn) throws Exception { 685 for (Module m : layer.modules()) { 686 ClassLoader l = m.getClassLoader(); 687 try { 688 l.loadClass(cn); 689 assertTrue(false); 690 } catch (ClassNotFoundException expected) { } 691 } 692 } 693 694 695 /** 696 * Returns a ModuleFinder that only finds the given test modules 697 */ 698 static ModuleFinder finderFor(String... names) { 699 700 ModuleFinder finder = ModuleFinder.of(MODS_DIR); 701 702 Map<String, ModuleReference> mrefs = new HashMap<>(); 703 for (String name : names) { 704 Optional<ModuleReference> omref = finder.find(name); 705 assert omref.isPresent(); 706 mrefs.put(name, omref.get()); 707 } 708 709 return new ModuleFinder() { 710 @Override 711 public Optional<ModuleReference> find(String name) { 712 ModuleReference mref = mrefs.get(name); 713 return Optional.ofNullable(mref); 714 } 715 @Override 716 public Set<ModuleReference> findAll() { 717 return mrefs.values().stream().collect(Collectors.toSet()); 718 } 719 }; 720 } 721 722 }