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