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 layer 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 = Map.of();
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 export a package to
249          * module {@code target}. This method is a no-op if {@code source}
250          * already exports 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
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#addExports
266          */

267         public Controller addExports(Module source, String pn, Module target) {
268             ensureInLayer(source);
269             source.implAddExports(pn, target);
270             return this;
271         }
272
273         /**
274          * Updates module {@code source} in the layer to open a package to
275          * module {@code target}. This method is a no-op if {@code source}
276          * already opens the package to at least {@code target}.
277          *
278          * @param  source
279          *         The source module
280          * @param  pn
281          *         The package name
282          * @param  target
283          *         The target module
284          *
285          * @return This controller
286          *
287          * @throws IllegalArgumentException
288          *         If {@code source} is not in the module layer or the package
289          *         is not in the source module
290          *
291          * @see Module#addOpens
292          */

293         public Controller addOpens(Module source, String pn, Module target) {
294             ensureInLayer(source);
295             source.implAddOpens(pn, target);
296             return this;
297         }
298     }
299
300
301     /**
302      * Creates a new module layer, with this layer as its parent, by defining the
303      * modules in the given {@code Configuration} to the Java virtual machine.
304      * This method creates one class loader and defines all modules to that
305      * class loader. The {@link ClassLoader#getParent() parent} of each class
306      * loader is the given parent class loader. This method works exactly as
307      * specified by the static {@link
308      * #defineModulesWithOneLoader(Configuration,List,ClassLoader)
309      * defineModulesWithOneLoader} method when invoked with this layer as the
310      * parent. In other words, if this layer is {@code thisLayer} then this
311      * method is equivalent to invoking:
312      * <pre> {@code
313      *     ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
314      * }</pre>
315      *
316      * @param  cf
317      *         The configuration for the layer
318      * @param  parentLoader
319      *         The parent class loader for the class loader created by this
320      *         method; may be {@code nullfor the bootstrap class loader
321      *
322      * @return The newly created layer
323      *
324      * @throws IllegalArgumentException
325      *         If the given configuration has more than one parent or the parent
326      *         of the configuration is not the configuration for this layer
327      * @throws LayerInstantiationException
328      *         If the layer cannot be created for any of the reasons specified
329      *         by the static {@code defineModulesWithOneLoader} method
330      * @throws SecurityException
331      *         If {@code RuntimePermission("createClassLoader")} or
332      *         {@code RuntimePermission("getClassLoader")} is denied by
333      *         the security manager
334      *
335      * @see #findLoader
336      */

337     public ModuleLayer defineModulesWithOneLoader(Configuration cf,
338                                                   ClassLoader parentLoader) {
339         return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer();
340     }
341
342
343     /**
344      * Creates a new module layer, with this layer as its parent, by defining the
345      * modules in the given {@code Configuration} to the Java virtual machine.
346      * Each module is defined to its own {@link ClassLoader} created by this
347      * method. The {@link ClassLoader#getParent() parent} of each class loader
348      * is the given parent class loader. This method works exactly as specified
349      * by the static {@link
350      * #defineModulesWithManyLoaders(Configuration,List,ClassLoader)
351      * defineModulesWithManyLoaders} method when invoked with this layer as the
352      * parent. In other words, if this layer is {@code thisLayer} then this
353      * method is equivalent to invoking:
354      * <pre> {@code
355      *     ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
356      * }</pre>
357      *
358      * @param  cf
359      *         The configuration for the layer
360      * @param  parentLoader
361      *         The parent class loader for each of the class loaders created by
362      *         this method; may be {@code nullfor the bootstrap class loader
363      *
364      * @return The newly created layer
365      *
366      * @throws IllegalArgumentException
367      *         If the given configuration has more than one parent or the parent
368      *         of the configuration is not the configuration for this layer
369      * @throws LayerInstantiationException
370      *         If the layer cannot be created for any of the reasons specified
371      *         by the static {@code defineModulesWithManyLoaders} method
372      * @throws SecurityException
373      *         If {@code RuntimePermission("createClassLoader")} or
374      *         {@code RuntimePermission("getClassLoader")} is denied by
375      *         the security manager
376      *
377      * @see #findLoader
378      */

379     public ModuleLayer defineModulesWithManyLoaders(Configuration cf,
380                                                     ClassLoader parentLoader) {
381         return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer();
382     }
383
384
385     /**
386      * Creates a new module layer, with this layer as its parent, by defining the
387      * modules in the given {@code Configuration} to the Java virtual machine.
388      * Each module is mapped, by name, to its class loader by means of the
389      * given function. This method works exactly as specified by the static
390      * {@link #defineModules(Configuration,List,Function) defineModules}
391      * method when invoked with this layer as the parent. In other words, if
392      * this layer is {@code thisLayer} then this method is equivalent to
393      * invoking:
394      * <pre> {@code
395      *     ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
396      * }</pre>
397      *
398      * @param  cf
399      *         The configuration for the layer
400      * @param  clf
401      *         The function to map a module name to a class loader
402      *
403      * @return The newly created layer
404      *
405      * @throws IllegalArgumentException
406      *         If the given configuration has more than one parent or the parent
407      *         of the configuration is not the configuration for this layer
408      * @throws LayerInstantiationException
409      *         If the layer cannot be created for any of the reasons specified
410      *         by the static {@code defineModules} method
411      * @throws SecurityException
412      *         If {@code RuntimePermission("getClassLoader")} is denied by
413      *         the security manager
414      */

415     public ModuleLayer defineModules(Configuration cf,
416                                      Function<String, ClassLoader> clf) {
417         return defineModules(cf, List.of(this), clf).layer();
418     }
419
420     /**
421      * Creates a new module layer by defining the modules in the given {@code
422      * Configuration} to the Java virtual machine. This method creates one
423      * class loader and defines all modules to that class loader.
424      *
425      * <p> The class loader created by this method implements <em>direct
426      * delegation</em> when loading classes from modules. If the {@link
427      * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
428      * load a class then it uses the package name of the class to map it to a
429      * module. This may be a module in this layer and hence defined to the same
430      * class loader. It may be a package in a module in a parent layer that is
431      * exported to one or more of the modules in this layer. The class
432      * loader delegates to the class loader of the module, throwing {@code
433      * ClassNotFoundException} if not found by that class loader.
434      * When {@code loadClass} is invoked to load classes that do not map to a
435      * module then it delegates to the parent class loader. </p>
436      *
437      * <p> The class loader created by this method locates resources
438      * ({@link ClassLoader#getResource(String) getResource}, {@link
439      * ClassLoader#getResources(String) getResources}, and other resource
440      * methods) in all modules in the layer before searching the parent class
441      * loader. </p>
442      *
443      * <p> Attempting to create a layer with all modules defined to the same
444      * class loader can fail for the following reasons:
445      *
446      * <ul>
447      *
448      *     <li><p> <em>Overlapping packages</em>: Two or more modules in the
449      *     configuration have the same package. </p></li>
450      *
451      *     <li><p> <em>Split delegation</em>: The resulting class loader would
452      *     need to delegate to more than one class loader in order to load
453      *     classes in a specific package. </p></li>
454      *
455      * </ul>
456      *
457      * <p> In addition, a layer cannot be created if the configuration contains
458      * a module named "{@code java.base}", or a module contains a package named
459      * "{@code java}" or a package with a name starting with "{@code java.}". </p>
460      *
461      * <p> If there is a security manager then the class loader created by
462      * this method will load classes and resources with privileges that are
463      * restricted by the calling context of this method. </p>
464      *
465      * @param  cf
466      *         The configuration for the layer
467      * @param  parentLayers
468      *         The list of parent layers in search order
469      * @param  parentLoader
470      *         The parent class loader for the class loader created by this
471      *         method; may be {@code nullfor the bootstrap class loader
472      *
473      * @return A controller that controls the newly created layer
474      *
475      * @throws IllegalArgumentException
476      *         If the parent(s) of the given configuration do not match the
477      *         configuration of the parent layers, including order
478      * @throws LayerInstantiationException
479      *         If all modules cannot be defined to the same class loader for any
480      *         of the reasons listed above
481      * @throws SecurityException
482      *         If {@code RuntimePermission("createClassLoader")} or
483      *         {@code RuntimePermission("getClassLoader")} is denied by
484      *         the security manager
485      *
486      * @see #findLoader
487      */

488     public static Controller defineModulesWithOneLoader(Configuration cf,
489                                                         List<ModuleLayer> parentLayers,
490                                                         ClassLoader parentLoader)
491     {
492         List<ModuleLayer> parents = new ArrayList<>(parentLayers);
493         checkConfiguration(cf, parents);
494
495         checkCreateClassLoaderPermission();
496         checkGetClassLoaderPermission();
497
498         try {
499             Loader loader = new Loader(cf.modules(), parentLoader);
500             loader.initRemotePackageMap(cf, parents);
501             ModuleLayer layer = new ModuleLayer(cf, parents, mn -> loader);
502             return new Controller(layer);
503         } catch (IllegalArgumentException | IllegalStateException e) {
504             throw new LayerInstantiationException(e.getMessage());
505         }
506     }
507
508     /**
509      * Creates a new module layer by defining the modules in the given {@code
510      * Configuration} to the Java virtual machine. Each module is defined to
511      * its own {@link ClassLoader} created by this method. The {@link
512      * ClassLoader#getParent() parent} of each class loader is the given parent
513      * class loader.
514      *
515      * <p> The class loaders created by this method implement <em>direct
516      * delegation</em> when loading classes from modules. If the {@link
517      * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
518      * load a class then it uses the package name of the class to map it to a
519      * module. The package may be in the module defined to the class loader.
520      * The package may be exported by another module in this layer to the
521      * module defined to the class loader. It may be in a package exported by a
522      * module in a parent layer. The class loader delegates to the class loader
523      * of the module, throwing {@code ClassNotFoundException} if not found by
524      * that class loader. When {@code loadClass} is invoked to load a class
525      * that does not map to a module then it delegates to the parent class
526      * loader. </p>
527      *
528      * <p> The class loaders created by this method locate resources
529      * ({@link ClassLoader#getResource(String) getResource}, {@link
530      * ClassLoader#getResources(String) getResources}, and other resource
531      * methods) in the module defined to the class loader before searching
532      * the parent class loader. </p>
533      *
534      * <p> If there is a security manager then the class loaders created by
535      * this method will load classes and resources with privileges that are
536      * restricted by the calling context of this method. </p>
537      *
538      * @param  cf
539      *         The configuration for the layer
540      * @param  parentLayers
541      *         The list of parent layers in search order
542      * @param  parentLoader
543      *         The parent class loader for each of the class loaders created by
544      *         this method; may be {@code nullfor the bootstrap class loader
545      *
546      * @return A controller that controls the newly created layer
547      *
548      * @throws IllegalArgumentException
549      *         If the parent(s) of the given configuration do not match the
550      *         configuration of the parent layers, including order
551      * @throws LayerInstantiationException
552      *         If the layer cannot be created because the configuration contains
553      *         a module named "{@code java.base}" or a module contains a package
554      *         named "{@code java}" or a package with a name starting with
555      *         "{@code java.}"
556      *
557      * @throws SecurityException
558      *         If {@code RuntimePermission("createClassLoader")} or
559      *         {@code RuntimePermission("getClassLoader")} is denied by
560      *         the security manager
561      *
562      * @see #findLoader
563      */

564     public static Controller defineModulesWithManyLoaders(Configuration cf,
565                                                           List<ModuleLayer> parentLayers,
566                                                           ClassLoader parentLoader)
567     {
568         List<ModuleLayer> parents = new ArrayList<>(parentLayers);
569         checkConfiguration(cf, parents);
570
571         checkCreateClassLoaderPermission();
572         checkGetClassLoaderPermission();
573
574         LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
575         try {
576             ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
577             return new Controller(layer);
578         } catch (IllegalArgumentException | IllegalStateException e) {
579             throw new LayerInstantiationException(e.getMessage());
580         }
581     }
582
583     /**
584      * Creates a new module layer by defining the modules in the given {@code
585      * Configuration} to the Java virtual machine. The given function maps each
586      * module in the configuration, by name, to a class loader. Creating the
587      * layer informs the Java virtual machine about the classes that may be
588      * loaded so that the Java virtual machine knows which module that each
589      * class is a member of.
590      *
591      * <p> The class loader delegation implemented by the class loaders must
592      * respect module readability. The class loaders should be
593      * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
594      * avoid deadlocks during class loading. In addition, the entity creating
595      * a new layer with this method should arrange that the class loaders be
596      * ready to load from these modules before there are any attempts to load
597      * classes or resources. </p>
598      *
599      * <p> Creating a layer can fail for the following reasons: </p>
600      *
601      * <ul>
602      *
603      *     <li><p> Two or more modules with the same package are mapped to the
604      *     same class loader. </p></li>
605      *
606      *     <li><p> A module is mapped to a class loader that already has a
607      *     module of the same name defined to it. </p></li>
608      *
609      *     <li><p> A module is mapped to a class loader that has already
610      *     defined types in any of the packages in the module. </p></li>
611      *
612      * </ul>
613      *
614      * <p> In addition, a layer cannot be created if the configuration contains
615      * a module named "{@code java.base}", a configuration contains a module
616      * with a package named "{@code java}" or a package name starting with
617      * "{@code java.}", or the function to map a module name to a class loader
618      * returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
619      * platform class loader}. </p>
620      *
621      * <p> If the function to map a module name to class loader throws an error
622      * or runtime exception then it is propagated to the caller of this method.
623      * </p>
624      *
625      * @apiNote It is implementation specific as to whether creating a layer
626      * with this method is an atomic operation or not. Consequentially it is
627      * possible for this method to fail with some modules, but not all, defined
628      * to the Java virtual machine.
629      *
630      * @param  cf
631      *         The configuration for the layer
632      * @param  parentLayers
633      *         The list of parent layers in search order
634      * @param  clf
635      *         The function to map a module name to a class loader
636      *
637      * @return A controller that controls the newly created layer
638      *
639      * @throws IllegalArgumentException
640      *         If the parent(s) of the given configuration do not match the
641      *         configuration of the parent layers, including order
642      * @throws LayerInstantiationException
643      *         If creating the layer fails for any of the reasons listed above
644      * @throws SecurityException
645      *         If {@code RuntimePermission("getClassLoader")} is denied by
646      *         the security manager
647      */

648     public static Controller defineModules(Configuration cf,
649                                            List<ModuleLayer> parentLayers,
650                                            Function<String, ClassLoader> clf)
651     {
652         List<ModuleLayer> parents = new ArrayList<>(parentLayers);
653         checkConfiguration(cf, parents);
654         Objects.requireNonNull(clf);
655
656         checkGetClassLoaderPermission();
657
658         // The boot layer is checked during module system initialization
659         if (boot() != null) {
660             checkForDuplicatePkgs(cf, clf);
661         }
662
663         try {
664             ModuleLayer layer = new ModuleLayer(cf, parents, clf);
665             return new Controller(layer);
666         } catch (IllegalArgumentException | IllegalStateException e) {
667             throw new LayerInstantiationException(e.getMessage());
668         }
669     }
670
671
672     /**
673      * Checks that the parent configurations match the configuration of
674      * the parent layers.
675      */

676     private static void checkConfiguration(Configuration cf,
677                                            List<ModuleLayer> parentLayers)
678     {
679         Objects.requireNonNull(cf);
680
681         List<Configuration> parentConfigurations = cf.parents();
682         if (parentLayers.size() != parentConfigurations.size())
683             throw new IllegalArgumentException("wrong number of parents");
684
685         int index = 0;
686         for (ModuleLayer parent : parentLayers) {
687             if (parent.configuration() != parentConfigurations.get(index)) {
688                 throw new IllegalArgumentException(
689                         "Parent of configuration != configuration of this Layer");
690             }
691             index++;
692         }
693     }
694
695     private static void checkCreateClassLoaderPermission() {
696         SecurityManager sm = System.getSecurityManager();
697         if (sm != null)
698             sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
699     }
700
701     private static void checkGetClassLoaderPermission() {
702         SecurityManager sm = System.getSecurityManager();
703         if (sm != null)
704             sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
705     }
706
707     /**
708      * Checks a configuration and the module-to-loader mapping to ensure that
709      * no two modules mapped to the same class loader have the same package.
710      * It also checks that no two automatic modules have the same package.
711      *
712      * @throws LayerInstantiationException
713      */

714     private static void checkForDuplicatePkgs(Configuration cf,
715                                               Function<String, ClassLoader> clf)
716     {
717         // HashMap allows null keys
718         Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>();
719         for (ResolvedModule resolvedModule : cf.modules()) {
720             ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
721             ClassLoader loader = clf.apply(descriptor.name());
722
723             Set<String> loaderPackages
724                 = loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>());
725
726             for (String pkg : descriptor.packages()) {
727                 boolean added = loaderPackages.add(pkg);
728                 if (!added) {
729                     throw fail("More than one module with package %s mapped" +
730                                " to the same class loader", pkg);
731                 }
732             }
733         }
734     }
735
736     /**
737      * Creates a LayerInstantiationException with the a message formatted from
738      * the given format string and arguments.
739      */

740     private static LayerInstantiationException fail(String fmt, Object ... args) {
741         String msg = String.format(fmt, args);
742         return new LayerInstantiationException(msg);
743     }
744
745
746     /**
747      * Returns the configuration for this layer.
748      *
749      * @return The configuration for this layer
750      */

751     public Configuration configuration() {
752         return cf;
753     }
754
755
756     /**
757      * Returns the list of this layer's parents unless this is the
758      * {@linkplain #empty empty layer}, which has no parents and so an
759      * empty list is returned.
760      *
761      * @return The list of this layer's parents
762      */

763     public List<ModuleLayer> parents() {
764         return parents;
765     }
766
767
768     /**
769      * Returns an ordered stream of layers. The first element is this layer,
770      * the remaining elements are the parent layers in DFS order.
771      *
772      * @implNote For now, the assumption is that the number of elements will
773      * be very low and so this method does not use a specialized spliterator.
774      */

775     Stream<ModuleLayer> layers() {
776         List<ModuleLayer> allLayers = this.allLayers;
777         if (allLayers != null)
778             return allLayers.stream();
779
780         allLayers = new ArrayList<>();
781         Set<ModuleLayer> visited = new HashSet<>();
782         Deque<ModuleLayer> stack = new ArrayDeque<>();
783         visited.add(this);
784         stack.push(this);
785
786         while (!stack.isEmpty()) {
787             ModuleLayer layer = stack.pop();
788             allLayers.add(layer);
789
790             // push in reverse order
791             for (int i = layer.parents.size() - 1; i >= 0; i--) {
792                 ModuleLayer parent = layer.parents.get(i);
793                 if (!visited.contains(parent)) {
794                     visited.add(parent);
795                     stack.push(parent);
796                 }
797             }
798         }
799
800         this.allLayers = allLayers = Collections.unmodifiableList(allLayers);
801         return allLayers.stream();
802     }
803
804     private volatile List<ModuleLayer> allLayers;
805
806     /**
807      * Returns the set of the modules in this layer.
808      *
809      * @return A possibly-empty unmodifiable set of the modules in this layer
810      */

811     public Set<Module> modules() {
812         Set<Module> modules = this.modules;
813         if (modules == null) {
814             this.modules = modules = Set.copyOf(nameToModule.values());
815         }
816         return modules;
817     }
818
819     private volatile Set<Module> modules;
820
821
822     /**
823      * Returns the module with the given name in this layer, or if not in this
824      * layer, the {@linkplain #parents() parent} layers. Finding a module in
825      * parent layers is equivalent to invoking {@code findModule} on each
826      * parent, in search order, until the module is found or all parents have
827      * been searched. In a <em>tree of layers</em>  then this is equivalent to
828      * a depth-first search.
829      *
830      * @param  name
831      *         The name of the module to find
832      *
833      * @return The module with the given name or an empty {@code Optional}
834      *         if there isn't a module with this name in this layer or any
835      *         parent layer
836      */

837     public Optional<Module> findModule(String name) {
838         Objects.requireNonNull(name);
839         if (this == EMPTY_LAYER)
840             return Optional.empty();
841         Module m = nameToModule.get(name);
842         if (m != null)
843             return Optional.of(m);
844
845         return layers()
846                 .skip(1)  // skip this layer
847                 .map(l -> l.nameToModule.get(name))
848                 .filter(Objects::nonNull)
849                 .findAny();
850     }
851
852
853     /**
854      * Returns the {@code ClassLoader} for the module with the given name. If
855      * a module of the given name is not in this layer then the {@link #parents()
856      * parent} layers are searched in the manner specified by {@link
857      * #findModule(String) findModule}.
858      *
859      * <p> If there is a security manager then its {@code checkPermission}
860      * method is called with a {@code RuntimePermission("getClassLoader")}
861      * permission to check that the caller is allowed to get access to the
862      * class loader. </p>
863      *
864      * @apiNote This method does not return an {@code Optional<ClassLoader>}
865      * because `null` must be used to represent the bootstrap class loader.
866      *
867      * @param  name
868      *         The name of the module to find
869      *
870      * @return The ClassLoader that the module is defined to
871      *
872      * @throws IllegalArgumentException if a module of the given name is not
873      *         defined in this layer or any parent of this layer
874      *
875      * @throws SecurityException if denied by the security manager
876      */

877     public ClassLoader findLoader(String name) {
878         Optional<Module> om = findModule(name);
879
880         // can't use map(Module::getClassLoader) as class loader can be null
881         if (om.isPresent()) {
882             return om.get().getClassLoader();
883         } else {
884             throw new IllegalArgumentException("Module " + name
885                                                + " not known to this layer");
886         }
887     }
888
889     /**
890      * Returns a string describing this module layer.
891      *
892      * @return A possibly empty string describing this module layer
893      */

894     @Override
895     public String toString() {
896         return modules().stream()
897                 .map(Module::getName)
898                 .collect(Collectors.joining(", "));
899     }
900
901     /**
902      * Returns the <em>empty</em> layer. There are no modules in the empty
903      * layer. It has no parents.
904      *
905      * @return The empty layer
906      */

907     public static ModuleLayer empty() {
908         return EMPTY_LAYER;
909     }
910
911
912     /**
913      * Returns the boot layer. The boot layer contains at least one module,
914      * {@code java.base}. Its parent is the {@link #empty() empty} layer.
915      *
916      * @apiNote This method returns {@code null} during startup and before
917      *          the boot layer is fully initialized.
918      *
919      * @return The boot layer
920      */

921     public static ModuleLayer boot() {
922         return System.bootLayer;
923     }
924
925     /**
926      * Returns the ServicesCatalog for this Layer, creating it if not
927      * already created.
928      */

929     ServicesCatalog getServicesCatalog() {
930         ServicesCatalog servicesCatalog = this.servicesCatalog;
931         if (servicesCatalog != null)
932             return servicesCatalog;
933
934         synchronized (this) {
935             servicesCatalog = this.servicesCatalog;
936             if (servicesCatalog == null) {
937                 servicesCatalog = ServicesCatalog.create();
938                 nameToModule.values().forEach(servicesCatalog::register);
939                 this.servicesCatalog = servicesCatalog;
940             }
941         }
942
943         return servicesCatalog;
944     }
945
946     private volatile ServicesCatalog servicesCatalog;
947
948
949     /**
950      * Record that this layer has at least one module defined to the given
951      * class loader.
952      */

953     void bindToLoader(ClassLoader loader) {
954         // CLV.computeIfAbsent(loader, (cl, clv) -> new CopyOnWriteArrayList<>())
955         List<ModuleLayer> list = CLV.get(loader);
956         if (list == null) {
957             list = new CopyOnWriteArrayList<>();
958             List<ModuleLayer> previous = CLV.putIfAbsent(loader, list);
959             if (previous != null) list = previous;
960         }
961         list.add(this);
962     }
963
964     /**
965      * Returns a stream of the layers that have at least one module defined to
966      * the given class loader.
967      */

968     static Stream<ModuleLayer> layers(ClassLoader loader) {
969         List<ModuleLayer> list = CLV.get(loader);
970         if (list != null) {
971             return list.stream();
972         } else {
973             return Stream.empty();
974         }
975     }
976
977     // the list of layers with modules defined to a class loader
978     private static final ClassLoaderValue<List<ModuleLayer>> CLV = new ClassLoaderValue<>();
979 }
980