jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java
changeset 44614 a34001e206f9
parent 44613 49a5ced535f6
parent 44609 cf81fa72eb18
child 44617 112ddd6c13b2
equal deleted inserted replaced
44613:49a5ced535f6 44614:a34001e206f9
     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 = resolve("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 = resolve("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 = resolveAndBind("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 = resolveAndBind("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 = resolve("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.newModule("m1").exports("p").build();
       
   271 
       
   272         ModuleDescriptor descriptor2
       
   273             = ModuleDescriptor.newModule("m2").exports("p").build();
       
   274 
       
   275         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
       
   276 
       
   277         Configuration cf = Layer.boot()
       
   278             .configuration()
       
   279             .resolve(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.newModule("m1").exports("p").build();
       
   305 
       
   306         ModuleDescriptor descriptor2
       
   307             = ModuleDescriptor.newModule("m2").exports("p").build();
       
   308 
       
   309         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
       
   310 
       
   311         Configuration cf1 = Layer.boot()
       
   312             .configuration()
       
   313             .resolve(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.newModule("m3").requires("m1").build();
       
   320 
       
   321         ModuleDescriptor descriptor4
       
   322             = ModuleDescriptor.newModule("m4").requires("m2").build();
       
   323 
       
   324         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
       
   325 
       
   326         Configuration cf2 = cf1.resolve(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 = resolve("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.resolve(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 = resolve("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.resolve(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 = resolve("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.resolve(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 = resolve("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.resolve(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 = resolve("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 = resolve("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 resolve(String... roots) {
       
   625         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
       
   626         return Layer.boot()
       
   627             .configuration()
       
   628             .resolve(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 resolveAndBind(String... roots) {
       
   636         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
       
   637         return Layer.boot()
       
   638             .configuration()
       
   639             .resolveAndBind(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 }