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