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