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