1 /*
   2  * Copyright (c) 2014, 2022, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import java.lang.module.Configuration;
  29 import java.lang.module.ModuleDescriptor;
  30 import java.lang.module.ResolvedModule;
  31 import java.util.ArrayDeque;
  32 import java.util.ArrayList;
  33 import java.util.Collections;
  34 import java.util.Deque;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.List;
  38 import java.util.Map;
  39 import java.util.Objects;
  40 import java.util.Optional;
  41 import java.util.Set;
  42 import java.util.concurrent.CopyOnWriteArrayList;
  43 import java.util.function.Function;
  44 import java.util.stream.Collectors;
  45 import java.util.stream.Stream;
  46 
  47 import jdk.internal.javac.PreviewFeature;
  48 import jdk.internal.javac.Restricted;
  49 import jdk.internal.loader.ClassLoaderValue;
  50 import jdk.internal.loader.Loader;
  51 import jdk.internal.loader.LoaderPool;
  52 import jdk.internal.module.ServicesCatalog;
  53 import jdk.internal.misc.CDS;
  54 import jdk.internal.reflect.CallerSensitive;
  55 import jdk.internal.reflect.Reflection;
  56 import jdk.internal.vm.annotation.Stable;
  57 import sun.security.util.SecurityConstants;
  58 
  59 /**
  60  * A layer of modules in the Java virtual machine.
  61  *
  62  * <p> A layer is created from a graph of modules in a {@link Configuration}
  63  * and a function that maps each module to a {@link ClassLoader}.
  64  * Creating a layer informs the Java virtual machine about the classes that
  65  * may be loaded from the modules so that the Java virtual machine knows which
  66  * module that each class is a member of. </p>
  67  *
  68  * <p> Creating a layer creates a {@link Module} object for each {@link
  69  * ResolvedModule} in the configuration. For each resolved module that is
  70  * {@link ResolvedModule#reads() read}, the {@code Module} {@link
  71  * Module#canRead reads} the corresponding run-time {@code Module}, which may
  72  * be in the same layer or a {@link #parents() parent} layer. </p>
  73  *
  74  * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
  75  * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
  76  * provide convenient ways to create a module layer where all modules are
  77  * mapped to a single class loader or where each module is mapped to its own
  78  * class loader. The {@link #defineModules defineModules} method is for more
  79  * advanced cases where modules are mapped to custom class loaders by means of
  80  * a function specified to the method. Each of these methods has an instance
  81  * and static variant. The instance methods create a layer with the receiver
  82  * as the parent layer. The static methods are for more advanced cases where
  83  * there can be more than one parent layer or where a {@link
  84  * ModuleLayer.Controller Controller} is needed to control modules in the layer
  85  * </p>
  86  *
  87  * <p> A Java virtual machine has at least one non-empty layer, the {@link
  88  * #boot() boot} layer, that is created when the Java virtual machine is
  89  * started. The boot layer contains module {@code java.base} and is the only
  90  * layer in the Java virtual machine with a module named "{@code java.base}".
  91  * The modules in the boot layer are mapped to the bootstrap class loader and
  92  * other class loaders that are <a href="ClassLoader.html#builtinLoaders">
  93  * built-in</a> into the Java virtual machine. The boot layer will often be
  94  * the {@link #parents() parent} when creating additional layers. </p>
  95  *
  96  * <p> Each {@code Module} in a layer is created so that it {@link
  97  * Module#isExported(String) exports} and {@link Module#isOpen(String) opens}
  98  * the packages described by its {@link ModuleDescriptor}. Qualified exports
  99  * (where a package is exported to a set of target modules rather than all
 100  * modules) are reified when creating the layer as follows: </p>
 101  * <ul>
 102  *     <li> If module {@code X} exports a package to {@code Y}, and if the
 103  *     runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then
 104  *     the package is exported to {@code Module} {@code Y} (which may be in
 105  *     the same layer as {@code X} or a parent layer). </li>
 106  *
 107  *     <li> If module {@code X} exports a package to {@code Y}, and if the
 108  *     runtime {@code Module} {@code X} does not read {@code Y} then target
 109  *     {@code Y} is located as if by invoking {@link #findModule(String)
 110  *     findModule} to find the module in the layer or its parent layers. If
 111  *     {@code Y} is found then the package is exported to the instance of
 112  *     {@code Y} that was found. If {@code Y} is not found then the qualified
 113  *     export is ignored. </li>
 114  * </ul>
 115  *
 116  * <p> Qualified opens are handled in same way as qualified exports. </p>
 117  *
 118  * <p> As when creating a {@code Configuration},
 119  * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
 120  * treatment when creating a layer. An automatic module is created in the
 121  * Java virtual machine as a {@code Module} that reads every unnamed {@code
 122  * Module} in the Java virtual machine. </p>
 123  *
 124  * <p> Unless otherwise specified, passing a {@code null} argument to a method
 125  * in this class causes a {@link NullPointerException NullPointerException} to
 126  * be thrown. </p>
 127  *
 128  * <h2> Example </h2>
 129  *
 130  * <p> This example creates a configuration by resolving a module named
 131  * "{@code myapp}" with the configuration for the boot layer as the parent. It
 132  * then creates a new layer with the modules in this configuration. All modules
 133  * are defined to the same class loader. </p>
 134  *
 135  * {@snippet :
 136  *     ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
 137  *     ModuleLayer parent = ModuleLayer.boot();
 138  *     Configuration cf = parent.configuration()
 139  *                              .resolve(finder, ModuleFinder.of(), Set.of("myapp"));
 140  *     ClassLoader scl = ClassLoader.getSystemClassLoader();
 141  *     ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
 142  *     Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
 143  * }
 144  *
 145  * @since 9
 146  * @see Module#getLayer()
 147  */
 148 
 149 public final class ModuleLayer {
 150 
 151     // the empty layer (may be initialized from the CDS archive)
 152     private static @Stable ModuleLayer EMPTY_LAYER;
 153     static {
 154         CDS.initializeFromArchive(ModuleLayer.class);
 155         if (EMPTY_LAYER == null) {
 156             // create a new empty layer if there is no archived version.
 157             EMPTY_LAYER = new ModuleLayer(Configuration.empty(), List.of(), null);
 158         }
 159     }
 160 
 161     // the configuration from which this layer was created
 162     private final Configuration cf;
 163 
 164     // parent layers, empty in the case of the empty layer
 165     private final List<ModuleLayer> parents;
 166 
 167     // maps module name to jlr.Module
 168     private final Map<String, Module> nameToModule;
 169 
 170     /**
 171      * Creates a new module layer from the modules in the given configuration.
 172      */
 173     private ModuleLayer(Configuration cf,
 174                         List<ModuleLayer> parents,
 175                         Function<String, ClassLoader> clf)
 176     {
 177         this.cf = cf;
 178         this.parents = parents; // no need to do defensive copy
 179 
 180         Map<String, Module> map;
 181         if (parents.isEmpty()) {
 182             map = Map.of();
 183         } else {
 184             map = Module.defineModules(cf, clf, this);
 185         }
 186         this.nameToModule = map; // no need to do defensive copy
 187     }
 188 
 189     /**
 190      * Controls a module layer. The static methods defined by {@link ModuleLayer}
 191      * to create module layers return a {@code Controller} that can be used to
 192      * control modules in the layer.
 193      *
 194      * <p> Unless otherwise specified, passing a {@code null} argument to a
 195      * method in this class causes a {@link NullPointerException
 196      * NullPointerException} to be thrown. </p>
 197      *
 198      * @apiNote Care should be taken with {@code Controller} objects, they
 199      * should never be shared with untrusted code.
 200      *
 201      * @since 9
 202      */
 203     public static final class Controller {
 204         private final ModuleLayer layer;
 205 
 206         Controller(ModuleLayer layer) {
 207             this.layer = layer;
 208         }
 209 
 210         /**
 211          * Returns the layer that this object controls.
 212          *
 213          * @return the module layer
 214          */
 215         public ModuleLayer layer() {
 216             return layer;
 217         }
 218 
 219         private void ensureInLayer(Module source) {
 220             if (source.getLayer() != layer)
 221                 throw new IllegalArgumentException(source + " not in layer");
 222         }
 223 
 224 
 225         /**
 226          * Updates module {@code source} in the layer to read module
 227          * {@code target}. This method is a no-op if {@code source} already
 228          * reads {@code target}.
 229          *
 230          * @implNote <em>Read edges</em> added by this method are <em>weak</em>
 231          * and do not prevent {@code target} from being GC'ed when {@code source}
 232          * is strongly reachable.
 233          *
 234          * @param  source
 235          *         The source module
 236          * @param  target
 237          *         The target module to read
 238          *
 239          * @return This controller
 240          *
 241          * @throws IllegalArgumentException
 242          *         If {@code source} is not in the module layer
 243          *
 244          * @see Module#addReads
 245          */
 246         public Controller addReads(Module source, Module target) {
 247             ensureInLayer(source);
 248             source.implAddReads(target);
 249             return this;
 250         }
 251 
 252         /**
 253          * Updates module {@code source} in the layer to export a package to
 254          * module {@code target}. This method is a no-op if {@code source}
 255          * already exports the package to at least {@code target}.
 256          *
 257          * @param  source
 258          *         The source module
 259          * @param  pn
 260          *         The package name
 261          * @param  target
 262          *         The target module
 263          *
 264          * @return This controller
 265          *
 266          * @throws IllegalArgumentException
 267          *         If {@code source} is not in the module layer or the package
 268          *         is not in the source module
 269          *
 270          * @see Module#addExports
 271          */
 272         public Controller addExports(Module source, String pn, Module target) {
 273             ensureInLayer(source);
 274             source.implAddExports(pn, target);
 275             return this;
 276         }
 277 
 278         /**
 279          * Updates module {@code source} in the layer to open a package to
 280          * module {@code target}. This method is a no-op if {@code source}
 281          * already opens the package to at least {@code target}.
 282          *
 283          * @param  source
 284          *         The source module
 285          * @param  pn
 286          *         The package name
 287          * @param  target
 288          *         The target module
 289          *
 290          * @return This controller
 291          *
 292          * @throws IllegalArgumentException
 293          *         If {@code source} is not in the module layer or the package
 294          *         is not in the source module
 295          *
 296          * @see Module#addOpens
 297          */
 298         public Controller addOpens(Module source, String pn, Module target) {
 299             ensureInLayer(source);
 300             source.implAddOpens(pn, target);
 301             return this;
 302         }
 303 
 304         /**
 305          * Enables native access for a module in the layer if the caller's module
 306          * has native access.
 307          *
 308          * <p> This method is <a href="foreign/package-summary.html#restricted"><em>restricted</em></a>.
 309          * Restricted methods are unsafe, and, if used incorrectly, their use might crash
 310          * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain
 311          * from depending on restricted methods, and use safe and supported functionalities,
 312          * where possible.
 313          *
 314          * @param  target
 315          *         The module to update
 316          *
 317          * @return This controller
 318          *
 319          * @throws IllegalArgumentException
 320          *         If {@code target} is not in the module layer
 321          *
 322          * @throws IllegalCallerException
 323          *         If the caller is in a module that does not have native access enabled
 324          *
 325          * @since 20
 326          */
 327         @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
 328         @CallerSensitive
 329         @Restricted
 330         public Controller enableNativeAccess(Module target) {
 331             ensureInLayer(target);
 332             Reflection.ensureNativeAccess(Reflection.getCallerClass(), Module.class,
 333                 "enableNativeAccess");
 334             target.implAddEnableNativeAccess();
 335             return this;
 336         }
 337     }
 338 
 339 
 340     /**
 341      * Creates a new module layer, with this layer as its parent, by defining the
 342      * modules in the given {@code Configuration} to the Java virtual machine.
 343      * This method creates one class loader and defines all modules to that
 344      * class loader. The {@link ClassLoader#getParent() parent} of each class
 345      * loader is the given parent class loader. This method works exactly as
 346      * specified by the static {@link
 347      * #defineModulesWithOneLoader(Configuration,List,ClassLoader)
 348      * defineModulesWithOneLoader} method when invoked with this layer as the
 349      * parent. In other words, if this layer is {@code thisLayer} then this
 350      * method is equivalent to invoking:
 351      * <pre> {@code
 352      *     ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
 353      * }</pre>
 354      *
 355      * @param  cf
 356      *         The configuration for the layer
 357      * @param  parentLoader
 358      *         The parent class loader for the class loader created by this
 359      *         method; may be {@code null} for the bootstrap class loader
 360      *
 361      * @return The newly created layer
 362      *
 363      * @throws IllegalArgumentException
 364      *         If the given configuration has more than one parent or the parent
 365      *         of the configuration is not the configuration for this layer
 366      * @throws LayerInstantiationException
 367      *         If the layer cannot be created for any of the reasons specified
 368      *         by the static {@code defineModulesWithOneLoader} method
 369      * @throws SecurityException
 370      *         If {@code RuntimePermission("createClassLoader")} or
 371      *         {@code RuntimePermission("getClassLoader")} is denied by
 372      *         the security manager
 373      *
 374      * @see #findLoader
 375      */
 376     public ModuleLayer defineModulesWithOneLoader(Configuration cf,
 377                                                   ClassLoader parentLoader) {
 378         return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer();
 379     }
 380 
 381 
 382     /**
 383      * Creates a new module layer, with this layer as its parent, by defining the
 384      * modules in the given {@code Configuration} to the Java virtual machine.
 385      * Each module is defined to its own {@link ClassLoader} created by this
 386      * method. The {@link ClassLoader#getParent() parent} of each class loader
 387      * is the given parent class loader. This method works exactly as specified
 388      * by the static {@link
 389      * #defineModulesWithManyLoaders(Configuration,List,ClassLoader)
 390      * defineModulesWithManyLoaders} method when invoked with this layer as the
 391      * parent. In other words, if this layer is {@code thisLayer} then this
 392      * method is equivalent to invoking:
 393      * <pre> {@code
 394      *     ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
 395      * }</pre>
 396      *
 397      * @param  cf
 398      *         The configuration for the layer
 399      * @param  parentLoader
 400      *         The parent class loader for each of the class loaders created by
 401      *         this method; may be {@code null} for the bootstrap class loader
 402      *
 403      * @return The newly created layer
 404      *
 405      * @throws IllegalArgumentException
 406      *         If the given configuration has more than one parent or the parent
 407      *         of the configuration is not the configuration for this layer
 408      * @throws LayerInstantiationException
 409      *         If the layer cannot be created for any of the reasons specified
 410      *         by the static {@code defineModulesWithManyLoaders} method
 411      * @throws SecurityException
 412      *         If {@code RuntimePermission("createClassLoader")} or
 413      *         {@code RuntimePermission("getClassLoader")} is denied by
 414      *         the security manager
 415      *
 416      * @see #findLoader
 417      */
 418     public ModuleLayer defineModulesWithManyLoaders(Configuration cf,
 419                                                     ClassLoader parentLoader) {
 420         return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer();
 421     }
 422 
 423 
 424     /**
 425      * Creates a new module layer, with this layer as its parent, by defining the
 426      * modules in the given {@code Configuration} to the Java virtual machine.
 427      * Each module is mapped, by name, to its class loader by means of the
 428      * given function. This method works exactly as specified by the static
 429      * {@link #defineModules(Configuration,List,Function) defineModules}
 430      * method when invoked with this layer as the parent. In other words, if
 431      * this layer is {@code thisLayer} then this method is equivalent to
 432      * invoking:
 433      * <pre> {@code
 434      *     ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
 435      * }</pre>
 436      *
 437      * @param  cf
 438      *         The configuration for the layer
 439      * @param  clf
 440      *         The function to map a module name to a class loader
 441      *
 442      * @return The newly created layer
 443      *
 444      * @throws IllegalArgumentException
 445      *         If the given configuration has more than one parent or the parent
 446      *         of the configuration is not the configuration for this layer
 447      * @throws LayerInstantiationException
 448      *         If the layer cannot be created for any of the reasons specified
 449      *         by the static {@code defineModules} method
 450      * @throws SecurityException
 451      *         If {@code RuntimePermission("getClassLoader")} is denied by
 452      *         the security manager
 453      */
 454     public ModuleLayer defineModules(Configuration cf,
 455                                      Function<String, ClassLoader> clf) {
 456         return defineModules(cf, List.of(this), clf).layer();
 457     }
 458 
 459     /**
 460      * Creates a new module layer by defining the modules in the given {@code
 461      * Configuration} to the Java virtual machine. This method creates one
 462      * class loader and defines all modules to that class loader.
 463      *
 464      * <p> The class loader created by this method implements <em>direct
 465      * delegation</em> when loading classes from modules. If the {@link
 466      * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
 467      * load a class then it uses the package name of the class to map it to a
 468      * module. This may be a module in this layer and hence defined to the same
 469      * class loader. It may be a package in a module in a parent layer that is
 470      * exported to one or more of the modules in this layer. The class
 471      * loader delegates to the class loader of the module, throwing {@code
 472      * ClassNotFoundException} if not found by that class loader.
 473      * When {@code loadClass} is invoked to load classes that do not map to a
 474      * module then it delegates to the parent class loader. </p>
 475      *
 476      * <p> The class loader created by this method locates resources
 477      * ({@link ClassLoader#getResource(String) getResource}, {@link
 478      * ClassLoader#getResources(String) getResources}, and other resource
 479      * methods) in all modules in the layer before searching the parent class
 480      * loader. </p>
 481      *
 482      * <p> Attempting to create a layer with all modules defined to the same
 483      * class loader can fail for the following reasons:
 484      *
 485      * <ul>
 486      *
 487      *     <li><p> <em>Overlapping packages</em>: Two or more modules in the
 488      *     configuration have the same package. </p></li>
 489      *
 490      *     <li><p> <em>Split delegation</em>: The resulting class loader would
 491      *     need to delegate to more than one class loader in order to load
 492      *     classes in a specific package. </p></li>
 493      *
 494      * </ul>
 495      *
 496      * <p> In addition, a layer cannot be created if the configuration contains
 497      * a module named "{@code java.base}", or a module contains a package named
 498      * "{@code java}" or a package with a name starting with "{@code java.}". </p>
 499      *
 500      * <p> If there is a security manager then the class loader created by
 501      * this method will load classes and resources with privileges that are
 502      * restricted by the calling context of this method. </p>
 503      *
 504      * @param  cf
 505      *         The configuration for the layer
 506      * @param  parentLayers
 507      *         The list of parent layers in search order
 508      * @param  parentLoader
 509      *         The parent class loader for the class loader created by this
 510      *         method; may be {@code null} for the bootstrap class loader
 511      *
 512      * @return A controller that controls the newly created layer
 513      *
 514      * @throws IllegalArgumentException
 515      *         If the parent(s) of the given configuration do not match the
 516      *         configuration of the parent layers, including order
 517      * @throws LayerInstantiationException
 518      *         If all modules cannot be defined to the same class loader for any
 519      *         of the reasons listed above
 520      * @throws SecurityException
 521      *         If {@code RuntimePermission("createClassLoader")} or
 522      *         {@code RuntimePermission("getClassLoader")} is denied by
 523      *         the security manager
 524      *
 525      * @see #findLoader
 526      */
 527     public static Controller defineModulesWithOneLoader(Configuration cf,
 528                                                         List<ModuleLayer> parentLayers,
 529                                                         ClassLoader parentLoader)
 530     {
 531         List<ModuleLayer> parents = List.copyOf(parentLayers);
 532         checkConfiguration(cf, parents);
 533 
 534         checkCreateClassLoaderPermission();
 535         checkGetClassLoaderPermission();
 536 
 537         try {
 538             Loader loader = new Loader(cf.modules(), parentLoader);
 539             loader.initRemotePackageMap(cf, parents);
 540             ModuleLayer layer = new ModuleLayer(cf, parents, mn -> loader);
 541             return new Controller(layer);
 542         } catch (IllegalArgumentException | IllegalStateException e) {
 543             throw new LayerInstantiationException(e.getMessage());
 544         }
 545     }
 546 
 547     /**
 548      * Creates a new module layer by defining the modules in the given {@code
 549      * Configuration} to the Java virtual machine. Each module is defined to
 550      * its own {@link ClassLoader} created by this method. The {@link
 551      * ClassLoader#getParent() parent} of each class loader is the given parent
 552      * class loader.
 553      *
 554      * <p> The class loaders created by this method implement <em>direct
 555      * delegation</em> when loading classes from modules. If the {@link
 556      * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
 557      * load a class then it uses the package name of the class to map it to a
 558      * module. The package may be in the module defined to the class loader.
 559      * The package may be exported by another module in this layer to the
 560      * module defined to the class loader. It may be in a package exported by a
 561      * module in a parent layer. The class loader delegates to the class loader
 562      * of the module, throwing {@code ClassNotFoundException} if not found by
 563      * that class loader. When {@code loadClass} is invoked to load a class
 564      * that does not map to a module then it delegates to the parent class
 565      * loader. </p>
 566      *
 567      * <p> The class loaders created by this method locate resources
 568      * ({@link ClassLoader#getResource(String) getResource}, {@link
 569      * ClassLoader#getResources(String) getResources}, and other resource
 570      * methods) in the module defined to the class loader before searching
 571      * the parent class loader. </p>
 572      *
 573      * <p> If there is a security manager then the class loaders created by
 574      * this method will load classes and resources with privileges that are
 575      * restricted by the calling context of this method. </p>
 576      *
 577      * @param  cf
 578      *         The configuration for the layer
 579      * @param  parentLayers
 580      *         The list of parent layers in search order
 581      * @param  parentLoader
 582      *         The parent class loader for each of the class loaders created by
 583      *         this method; may be {@code null} for the bootstrap class loader
 584      *
 585      * @return A controller that controls the newly created layer
 586      *
 587      * @throws IllegalArgumentException
 588      *         If the parent(s) of the given configuration do not match the
 589      *         configuration of the parent layers, including order
 590      * @throws LayerInstantiationException
 591      *         If the layer cannot be created because the configuration contains
 592      *         a module named "{@code java.base}" or a module contains a package
 593      *         named "{@code java}" or a package with a name starting with
 594      *         "{@code java.}"
 595      *
 596      * @throws SecurityException
 597      *         If {@code RuntimePermission("createClassLoader")} or
 598      *         {@code RuntimePermission("getClassLoader")} is denied by
 599      *         the security manager
 600      *
 601      * @see #findLoader
 602      */
 603     public static Controller defineModulesWithManyLoaders(Configuration cf,
 604                                                           List<ModuleLayer> parentLayers,
 605                                                           ClassLoader parentLoader)
 606     {
 607         List<ModuleLayer> parents = List.copyOf(parentLayers);
 608         checkConfiguration(cf, parents);
 609 
 610         checkCreateClassLoaderPermission();
 611         checkGetClassLoaderPermission();
 612 
 613         LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
 614         try {
 615             ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
 616             return new Controller(layer);
 617         } catch (IllegalArgumentException | IllegalStateException e) {
 618             throw new LayerInstantiationException(e.getMessage());
 619         }
 620     }
 621 
 622     /**
 623      * Creates a new module layer by defining the modules in the given {@code
 624      * Configuration} to the Java virtual machine. The given function maps each
 625      * module in the configuration, by name, to a class loader. Creating the
 626      * layer informs the Java virtual machine about the classes that may be
 627      * loaded so that the Java virtual machine knows which module that each
 628      * class is a member of.
 629      *
 630      * <p> The class loader delegation implemented by the class loaders must
 631      * respect module readability. The class loaders should be
 632      * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
 633      * avoid deadlocks during class loading. In addition, the entity creating
 634      * a new layer with this method should arrange that the class loaders be
 635      * ready to load from these modules before there are any attempts to load
 636      * classes or resources. </p>
 637      *
 638      * <p> Creating a layer can fail for the following reasons: </p>
 639      *
 640      * <ul>
 641      *
 642      *     <li><p> Two or more modules with the same package are mapped to the
 643      *     same class loader. </p></li>
 644      *
 645      *     <li><p> A module is mapped to a class loader that already has a
 646      *     module of the same name defined to it. </p></li>
 647      *
 648      *     <li><p> A module is mapped to a class loader that has already
 649      *     defined types in any of the packages in the module. </p></li>
 650      *
 651      * </ul>
 652      *
 653      * <p> In addition, a layer cannot be created if the configuration contains
 654      * a module named "{@code java.base}", a configuration contains a module
 655      * with a package named "{@code java}" or a package name starting with
 656      * "{@code java.}", or the function to map a module name to a class loader
 657      * returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
 658      * platform class loader}. </p>
 659      *
 660      * <p> If the function to map a module name to class loader throws an error
 661      * or runtime exception then it is propagated to the caller of this method.
 662      * </p>
 663      *
 664      * @apiNote It is implementation specific as to whether creating a layer
 665      * with this method is an atomic operation or not. Consequently it is
 666      * possible for this method to fail with some modules, but not all, defined
 667      * to the Java virtual machine.
 668      *
 669      * @param  cf
 670      *         The configuration for the layer
 671      * @param  parentLayers
 672      *         The list of parent layers in search order
 673      * @param  clf
 674      *         The function to map a module name to a class loader
 675      *
 676      * @return A controller that controls the newly created layer
 677      *
 678      * @throws IllegalArgumentException
 679      *         If the parent(s) of the given configuration do not match the
 680      *         configuration of the parent layers, including order
 681      * @throws LayerInstantiationException
 682      *         If creating the layer fails for any of the reasons listed above
 683      * @throws SecurityException
 684      *         If {@code RuntimePermission("getClassLoader")} is denied by
 685      *         the security manager
 686      */
 687     public static Controller defineModules(Configuration cf,
 688                                            List<ModuleLayer> parentLayers,
 689                                            Function<String, ClassLoader> clf)
 690     {
 691         List<ModuleLayer> parents = List.copyOf(parentLayers);
 692         checkConfiguration(cf, parents);
 693         Objects.requireNonNull(clf);
 694 
 695         checkGetClassLoaderPermission();
 696 
 697         // The boot layer is checked during module system initialization
 698         if (boot() != null) {
 699             checkForDuplicatePkgs(cf, clf);
 700         }
 701 
 702         try {
 703             ModuleLayer layer = new ModuleLayer(cf, parents, clf);
 704             return new Controller(layer);
 705         } catch (IllegalArgumentException | IllegalStateException e) {
 706             throw new LayerInstantiationException(e.getMessage());
 707         }
 708     }
 709 
 710 
 711     /**
 712      * Checks that the parent configurations match the configuration of
 713      * the parent layers.
 714      */
 715     private static void checkConfiguration(Configuration cf,
 716                                            List<ModuleLayer> parentLayers)
 717     {
 718         Objects.requireNonNull(cf);
 719 
 720         List<Configuration> parentConfigurations = cf.parents();
 721         if (parentLayers.size() != parentConfigurations.size())
 722             throw new IllegalArgumentException("wrong number of parents");
 723 
 724         int index = 0;
 725         for (ModuleLayer parent : parentLayers) {
 726             if (parent.configuration() != parentConfigurations.get(index)) {
 727                 throw new IllegalArgumentException(
 728                         "Parent of configuration != configuration of this Layer");
 729             }
 730             index++;
 731         }
 732     }
 733 
 734     private static void checkCreateClassLoaderPermission() {
 735         @SuppressWarnings("removal")
 736         SecurityManager sm = System.getSecurityManager();
 737         if (sm != null)
 738             sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
 739     }
 740 
 741     private static void checkGetClassLoaderPermission() {
 742         @SuppressWarnings("removal")
 743         SecurityManager sm = System.getSecurityManager();
 744         if (sm != null)
 745             sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 746     }
 747 
 748     /**
 749      * Checks a configuration and the module-to-loader mapping to ensure that
 750      * no two modules mapped to the same class loader have the same package.
 751      * It also checks that no two automatic modules have the same package.
 752      *
 753      * @throws LayerInstantiationException
 754      */
 755     private static void checkForDuplicatePkgs(Configuration cf,
 756                                               Function<String, ClassLoader> clf)
 757     {
 758         // HashMap allows null keys
 759         Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>();
 760         for (ResolvedModule resolvedModule : cf.modules()) {
 761             ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
 762             ClassLoader loader = clf.apply(descriptor.name());
 763 
 764             Set<String> loaderPackages
 765                 = loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>());
 766 
 767             for (String pkg : descriptor.packages()) {
 768                 boolean added = loaderPackages.add(pkg);
 769                 if (!added) {
 770                     throw fail("More than one module with package %s mapped" +
 771                                " to the same class loader", pkg);
 772                 }
 773             }
 774         }
 775     }
 776 
 777     /**
 778      * Creates a LayerInstantiationException with the message formatted from
 779      * the given format string and arguments.
 780      */
 781     private static LayerInstantiationException fail(String fmt, Object ... args) {
 782         String msg = String.format(fmt, args);
 783         return new LayerInstantiationException(msg);
 784     }
 785 
 786 
 787     /**
 788      * Returns the configuration for this layer.
 789      *
 790      * @return The configuration for this layer
 791      */
 792     public Configuration configuration() {
 793         return cf;
 794     }
 795 
 796     /**
 797      * Returns an unmodifiable list of this layer's parents, in search
 798      * order. If this is the {@linkplain #empty() empty layer} then an
 799      * empty list is returned.
 800      *
 801      * @return A possibly-empty unmodifiable list of this layer's parents
 802      */
 803     public List<ModuleLayer> parents() {
 804         return parents;
 805     }
 806 
 807 
 808     /**
 809      * Returns an ordered stream of layers. The first element is this layer,
 810      * the remaining elements are the parent layers in DFS order.
 811      *
 812      * @implNote For now, the assumption is that the number of elements will
 813      * be very low and so this method does not use a specialized spliterator.
 814      */
 815     Stream<ModuleLayer> layers() {
 816         List<ModuleLayer> allLayers = this.allLayers;
 817         if (allLayers != null)
 818             return allLayers.stream();
 819 
 820         allLayers = new ArrayList<>();
 821         Set<ModuleLayer> visited = new HashSet<>();
 822         Deque<ModuleLayer> stack = new ArrayDeque<>();
 823         visited.add(this);
 824         stack.push(this);
 825 
 826         while (!stack.isEmpty()) {
 827             ModuleLayer layer = stack.pop();
 828             allLayers.add(layer);
 829 
 830             // push in reverse order
 831             for (int i = layer.parents.size() - 1; i >= 0; i--) {
 832                 ModuleLayer parent = layer.parents.get(i);
 833                 if (visited.add(parent)) {
 834                     stack.push(parent);
 835                 }
 836             }
 837         }
 838 
 839         this.allLayers = allLayers = Collections.unmodifiableList(allLayers);
 840         return allLayers.stream();
 841     }
 842 
 843     private volatile List<ModuleLayer> allLayers;
 844 
 845     /**
 846      * Returns an unmodifiable set of the modules in this layer.
 847      *
 848      * @return A possibly-empty unmodifiable set of the modules in this layer
 849      */
 850     public Set<Module> modules() {
 851         Set<Module> modules = this.modules;
 852         if (modules == null) {
 853             this.modules = modules = Set.copyOf(nameToModule.values());
 854         }
 855         return modules;
 856     }
 857 
 858     private volatile Set<Module> modules;
 859 
 860 
 861     /**
 862      * Returns the module with the given name in this layer, or if not in this
 863      * layer, the {@linkplain #parents() parent} layers. Finding a module in
 864      * parent layers is equivalent to invoking {@code findModule} on each
 865      * parent, in search order, until the module is found or all parents have
 866      * been searched. In a <em>tree of layers</em>  then this is equivalent to
 867      * a depth-first search.
 868      *
 869      * @param  name
 870      *         The name of the module to find
 871      *
 872      * @return The module with the given name or an empty {@code Optional}
 873      *         if there isn't a module with this name in this layer or any
 874      *         parent layer
 875      */
 876     public Optional<Module> findModule(String name) {
 877         Objects.requireNonNull(name);
 878         if (this == EMPTY_LAYER)
 879             return Optional.empty();
 880         Module m = nameToModule.get(name);
 881         if (m != null)
 882             return Optional.of(m);
 883 
 884         return layers()
 885                 .skip(1)  // skip this layer
 886                 .map(l -> l.nameToModule.get(name))
 887                 .filter(Objects::nonNull)
 888                 .findAny();
 889     }
 890 
 891 
 892     /**
 893      * Returns the {@code ClassLoader} for the module with the given name. If
 894      * a module of the given name is not in this layer then the {@link #parents()
 895      * parent} layers are searched in the manner specified by {@link
 896      * #findModule(String) findModule}.
 897      *
 898      * <p> If there is a security manager then its {@code checkPermission}
 899      * method is called with a {@code RuntimePermission("getClassLoader")}
 900      * permission to check that the caller is allowed to get access to the
 901      * class loader. </p>
 902      *
 903      * @apiNote This method does not return an {@code Optional<ClassLoader>}
 904      * because `null` must be used to represent the bootstrap class loader.
 905      *
 906      * @param  name
 907      *         The name of the module to find
 908      *
 909      * @return The ClassLoader that the module is defined to
 910      *
 911      * @throws IllegalArgumentException if a module of the given name is not
 912      *         defined in this layer or any parent of this layer
 913      *
 914      * @throws SecurityException if denied by the security manager
 915      */
 916     public ClassLoader findLoader(String name) {
 917         Optional<Module> om = findModule(name);
 918 
 919         // can't use map(Module::getClassLoader) as class loader can be null
 920         if (om.isPresent()) {
 921             return om.get().getClassLoader();
 922         } else {
 923             throw new IllegalArgumentException("Module " + name
 924                                                + " not known to this layer");
 925         }
 926     }
 927 
 928     /**
 929      * Returns a string describing this module layer.
 930      *
 931      * @return A possibly empty string describing this module layer
 932      */
 933     @Override
 934     public String toString() {
 935         return modules().stream()
 936                 .map(Module::getName)
 937                 .collect(Collectors.joining(", "));
 938     }
 939 
 940     /**
 941      * Returns the <em>empty</em> layer. There are no modules in the empty
 942      * layer. It has no parents.
 943      *
 944      * @return The empty layer
 945      */
 946     public static ModuleLayer empty() {
 947         return EMPTY_LAYER;
 948     }
 949 
 950 
 951     /**
 952      * Returns the boot layer. The boot layer contains at least one module,
 953      * {@code java.base}. Its parent is the {@link #empty() empty} layer.
 954      *
 955      * @apiNote This method returns {@code null} during startup and before
 956      *          the boot layer is fully initialized.
 957      *
 958      * @return The boot layer
 959      */
 960     public static ModuleLayer boot() {
 961         return System.bootLayer;
 962     }
 963 
 964     /**
 965      * Returns the ServicesCatalog for this Layer, creating it if not
 966      * already created.
 967      */
 968     ServicesCatalog getServicesCatalog() {
 969         ServicesCatalog servicesCatalog = this.servicesCatalog;
 970         if (servicesCatalog != null)
 971             return servicesCatalog;
 972 
 973         synchronized (this) {
 974             servicesCatalog = this.servicesCatalog;
 975             if (servicesCatalog == null) {
 976                 servicesCatalog = ServicesCatalog.create();
 977                 for (Module m : nameToModule.values()) {
 978                     servicesCatalog.register(m);
 979                 }
 980                 this.servicesCatalog = servicesCatalog;
 981             }
 982         }
 983 
 984         return servicesCatalog;
 985     }
 986 
 987     private volatile ServicesCatalog servicesCatalog;
 988 
 989 
 990     /**
 991      * Record that this layer has at least one module defined to the given
 992      * class loader.
 993      */
 994     void bindToLoader(ClassLoader loader) {
 995         // CLV.computeIfAbsent(loader, (cl, clv) -> new CopyOnWriteArrayList<>())
 996         List<ModuleLayer> list = CLV.get(loader);
 997         if (list == null) {
 998             list = new CopyOnWriteArrayList<>();
 999             List<ModuleLayer> previous = CLV.putIfAbsent(loader, list);
1000             if (previous != null) list = previous;
1001         }
1002         list.add(this);
1003     }
1004 
1005     /**
1006      * Returns a stream of the layers that have at least one module defined to
1007      * the given class loader.
1008      */
1009     static Stream<ModuleLayer> layers(ClassLoader loader) {
1010         List<ModuleLayer> list = CLV.get(loader);
1011         if (list != null) {
1012             return list.stream();
1013         } else {
1014             return Stream.empty();
1015         }
1016     }
1017 
1018     // the list of layers with modules defined to a class loader
1019     private static final ClassLoaderValue<List<ModuleLayer>> CLV = new ClassLoaderValue<>();
1020 }