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