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