54 |
54 |
55 |
55 |
56 /** |
56 /** |
57 * A layer of modules in the Java virtual machine. |
57 * A layer of modules in the Java virtual machine. |
58 * |
58 * |
59 * <p> A layer is created from a graph of modules that is the {@link |
59 * <p> A layer is created from a graph of modules in a {@link Configuration} |
60 * Configuration} and a function that maps each module to a {@link ClassLoader}. |
60 * and a function that maps each module to a {@link ClassLoader}. |
61 * Creating a layer informs the Java virtual machine about the classes that |
61 * Creating a layer informs the Java virtual machine about the classes that |
62 * may be loaded from modules so that the Java virtual machine knows which |
62 * may be loaded from the modules so that the Java virtual machine knows which |
63 * module that each class is a member of. Each layer, except the {@link |
63 * module that each class is a member of. </p> |
64 * #empty() empty} layer, has at least one {@link #parents() parent}. </p> |
|
65 * |
64 * |
66 * <p> Creating a layer creates a {@link Module} object for each {@link |
65 * <p> Creating a layer creates a {@link Module} object for each {@link |
67 * ResolvedModule} in the configuration. For each resolved module that is |
66 * ResolvedModule} in the configuration. For each resolved module that is |
68 * {@link ResolvedModule#reads() read}, the {@code Module} {@link |
67 * {@link ResolvedModule#reads() read}, the {@code Module} {@link |
69 * Module#canRead reads} the corresponding run-time {@code Module}, which may |
68 * Module#canRead reads} the corresponding run-time {@code Module}, which may |
70 * be in the same layer or a parent layer. The {@code Module} {@link |
69 * be in the same layer or a {@link #parents() parent} layer. The {@code Module} |
71 * Module#isExported(String) exports} the packages described by its {@link |
70 * {@link Module#isExported(String) exports} and {@link Module#isOpen(String) |
72 * ModuleDescriptor}. </p> |
71 * opens} the packages described by its {@link ModuleDescriptor}. </p> |
73 * |
72 * |
74 * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and |
73 * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and |
75 * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods |
74 * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods |
76 * provide convenient ways to create a {@code Layer} where all modules are |
75 * provide convenient ways to create a {@code Layer} where all modules are |
77 * mapped to a single class loader or where each module is mapped to its own |
76 * mapped to a single class loader or where each module is mapped to its own |
78 * class loader. The {@link #defineModules defineModules} method is for more |
77 * class loader. The {@link #defineModules defineModules} method is for more |
79 * advanced cases where modules are mapped to custom class loaders by means of |
78 * advanced cases where modules are mapped to custom class loaders by means of |
80 * a function specified to the method. Each of these methods has an instance |
79 * a function specified to the method. Each of these methods has an instance |
81 * and static variant. The instance methods create a layer with the receiver |
80 * and static variant. The instance methods create a layer with the receiver |
82 * as the parent layer. The static methods are for more advanced cases where |
81 * as the parent layer. The static methods are for more advanced cases where |
83 * there can be more than one parent layer or a {@link Layer.Controller |
82 * there can be more than one parent layer or where a {@link Layer.Controller |
84 * Controller} is needed to control modules in the layer. </p> |
83 * Controller} is needed to control modules in the layer. </p> |
85 * |
84 * |
86 * <p> A Java virtual machine has at least one non-empty layer, the {@link |
85 * <p> A Java virtual machine has at least one non-empty layer, the {@link |
87 * #boot() boot} layer, that is created when the Java virtual machine is |
86 * #boot() boot} layer, that is created when the Java virtual machine is |
88 * started. The boot layer contains module {@code java.base} and is the only |
87 * started. The boot layer contains module {@code java.base} and is the only |
91 * other class loaders that are <a href="../ClassLoader.html#builtinLoaders"> |
90 * other class loaders that are <a href="../ClassLoader.html#builtinLoaders"> |
92 * built-in</a> into the Java virtual machine. The boot layer will often be |
91 * built-in</a> into the Java virtual machine. The boot layer will often be |
93 * the {@link #parents() parent} when creating additional layers. </p> |
92 * the {@link #parents() parent} when creating additional layers. </p> |
94 * |
93 * |
95 * <p> As when creating a {@code Configuration}, |
94 * <p> As when creating a {@code Configuration}, |
96 * {@link ModuleDescriptor#isAutomatic() automatic} modules receive |
95 * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special |
97 * <a href="../module/Configuration.html#automaticmoduleresolution">special |
96 * treatment when creating a layer. An automatic module is created in the |
98 * treatment</a> when creating a layer. An automatic module is created in the |
|
99 * Java virtual machine as a {@code Module} that reads every unnamed {@code |
97 * Java virtual machine as a {@code Module} that reads every unnamed {@code |
100 * Module} in the Java virtual machine. </p> |
98 * Module} in the Java virtual machine. </p> |
101 * |
99 * |
102 * <p> Unless otherwise specified, passing a {@code null} argument to a method |
100 * <p> Unless otherwise specified, passing a {@code null} argument to a method |
103 * in this class causes a {@link NullPointerException NullPointerException} to |
101 * in this class causes a {@link NullPointerException NullPointerException} to |
113 * <pre>{@code |
111 * <pre>{@code |
114 * ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3); |
112 * ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3); |
115 * |
113 * |
116 * Layer parent = Layer.boot(); |
114 * Layer parent = Layer.boot(); |
117 * |
115 * |
118 * Configuration cf = parent.configuration() |
116 * Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp")); |
119 * .resolveRequires(finder, ModuleFinder.of(), Set.of("myapp")); |
|
120 * |
117 * |
121 * ClassLoader scl = ClassLoader.getSystemClassLoader(); |
118 * ClassLoader scl = ClassLoader.getSystemClassLoader(); |
122 * |
119 * |
123 * Layer layer = parent.defineModulesWithOneLoader(cf, scl); |
120 * Layer layer = parent.defineModulesWithOneLoader(cf, scl); |
124 * |
121 * |
125 * Class<?> c = layer.findLoader("myapp").loadClass("app.Main"); |
122 * Class<?> c = layer.findLoader("myapp").loadClass("app.Main"); |
126 * }</pre> |
123 * }</pre> |
127 * |
124 * |
128 * @since 9 |
125 * @since 9 |
|
126 * @spec JPMS |
129 * @see Module#getLayer() |
127 * @see Module#getLayer() |
130 */ |
128 */ |
131 |
129 |
132 public final class Layer { |
130 public final class Layer { |
133 |
131 |
166 /** |
164 /** |
167 * Controls a layer. The static methods defined by {@link Layer} to create |
165 * Controls a layer. The static methods defined by {@link Layer} to create |
168 * module layers return a {@code Controller} that can be used to control |
166 * module layers return a {@code Controller} that can be used to control |
169 * modules in the layer. |
167 * modules in the layer. |
170 * |
168 * |
|
169 * <p> Unless otherwise specified, passing a {@code null} argument to a |
|
170 * method in this class causes a {@link NullPointerException |
|
171 * NullPointerException} to be thrown. </p> |
|
172 * |
171 * @apiNote Care should be taken with {@code Controller} objects, they |
173 * @apiNote Care should be taken with {@code Controller} objects, they |
172 * should never be shared with untrusted code. |
174 * should never be shared with untrusted code. |
173 * |
175 * |
174 * @since 9 |
176 * @since 9 |
|
177 * @spec JPMS |
175 */ |
178 */ |
176 public static final class Controller { |
179 public static final class Controller { |
177 private final Layer layer; |
180 private final Layer layer; |
178 |
181 |
179 Controller(Layer layer) { |
182 Controller(Layer layer) { |
279 * |
282 * |
280 * @throws IllegalArgumentException |
283 * @throws IllegalArgumentException |
281 * If the parent of the given configuration is not the configuration |
284 * If the parent of the given configuration is not the configuration |
282 * for this layer |
285 * for this layer |
283 * @throws LayerInstantiationException |
286 * @throws LayerInstantiationException |
284 * If all modules cannot be defined to the same class loader for any |
287 * If the layer cannot be created for any of the reasons specified |
285 * of the reasons listed above or the layer cannot be created because |
288 * by the static {@code defineModulesWithOneLoader} method |
286 * the configuration contains a module named "{@code java.base}" or |
|
287 * a module with a package name starting with "{@code java.}" |
|
288 * @throws SecurityException |
289 * @throws SecurityException |
289 * If {@code RuntimePermission("createClassLoader")} or |
290 * If {@code RuntimePermission("createClassLoader")} or |
290 * {@code RuntimePermission("getClassLoader")} is denied by |
291 * {@code RuntimePermission("getClassLoader")} is denied by |
291 * the security manager |
292 * the security manager |
292 * |
293 * |
323 * |
324 * |
324 * @throws IllegalArgumentException |
325 * @throws IllegalArgumentException |
325 * If the parent of the given configuration is not the configuration |
326 * If the parent of the given configuration is not the configuration |
326 * for this layer |
327 * for this layer |
327 * @throws LayerInstantiationException |
328 * @throws LayerInstantiationException |
328 * If the layer cannot be created because the configuration contains |
329 * If the layer cannot be created for any of the reasons specified |
329 * a module named "{@code java.base}" or a module with a package |
330 * by the static {@code defineModulesWithManyLoaders} method |
330 * name starting with "{@code java.}" |
|
331 * @throws SecurityException |
331 * @throws SecurityException |
332 * If {@code RuntimePermission("createClassLoader")} or |
332 * If {@code RuntimePermission("createClassLoader")} or |
333 * {@code RuntimePermission("getClassLoader")} is denied by |
333 * {@code RuntimePermission("getClassLoader")} is denied by |
334 * the security manager |
334 * the security manager |
335 * |
335 * |
363 * |
363 * |
364 * @throws IllegalArgumentException |
364 * @throws IllegalArgumentException |
365 * If the parent of the given configuration is not the configuration |
365 * If the parent of the given configuration is not the configuration |
366 * for this layer |
366 * for this layer |
367 * @throws LayerInstantiationException |
367 * @throws LayerInstantiationException |
368 * If creating the {@code Layer} fails for any of the reasons |
368 * If the layer cannot be created for any of the reasons specified |
369 * listed above, the layer cannot be created because the |
369 * by the static {@code defineModules} method |
370 * configuration contains a module named "{@code java.base}", |
|
371 * a module with a package name starting with "{@code java.}" is |
|
372 * mapped to a class loader other than the {@link |
|
373 * ClassLoader#getPlatformClassLoader() platform class loader}, |
|
374 * or the function to map a module name to a class loader returns |
|
375 * {@code null} |
|
376 * @throws SecurityException |
370 * @throws SecurityException |
377 * If {@code RuntimePermission("getClassLoader")} is denied by |
371 * If {@code RuntimePermission("getClassLoader")} is denied by |
378 * the security manager |
372 * the security manager |
379 */ |
373 */ |
380 public Layer defineModules(Configuration cf, |
374 public Layer defineModules(Configuration cf, |
394 * module. This may be a module in this layer and hence defined to the same |
388 * module. This may be a module in this layer and hence defined to the same |
395 * class loader. It may be a package in a module in a parent layer that is |
389 * class loader. It may be a package in a module in a parent layer that is |
396 * exported to one or more of the modules in this layer. The class |
390 * exported to one or more of the modules in this layer. The class |
397 * loader delegates to the class loader of the module, throwing {@code |
391 * loader delegates to the class loader of the module, throwing {@code |
398 * ClassNotFoundException} if not found by that class loader. |
392 * ClassNotFoundException} if not found by that class loader. |
399 * |
|
400 * When {@code loadClass} is invoked to load classes that do not map to a |
393 * When {@code loadClass} is invoked to load classes that do not map to a |
401 * module then it delegates to the parent class loader. </p> |
394 * module then it delegates to the parent class loader. </p> |
402 * |
395 * |
403 * <p> Attempting to create a layer with all modules defined to the same |
396 * <p> Attempting to create a layer with all modules defined to the same |
404 * class loader can fail for the following reasons: |
397 * class loader can fail for the following reasons: |
411 * <li><p> <em>Split delegation</em>: The resulting class loader would |
404 * <li><p> <em>Split delegation</em>: The resulting class loader would |
412 * need to delegate to more than one class loader in order to load types |
405 * need to delegate to more than one class loader in order to load types |
413 * in a specific package. </p></li> |
406 * in a specific package. </p></li> |
414 * |
407 * |
415 * </ul> |
408 * </ul> |
|
409 * |
|
410 * <p> In addition, a layer cannot be created if the configuration contains |
|
411 * a module named "{@code java.base}" or a module with a package name |
|
412 * starting with "{@code java.}". </p> |
416 * |
413 * |
417 * <p> If there is a security manager then the class loader created by |
414 * <p> If there is a security manager then the class loader created by |
418 * this method will load classes and resources with privileges that are |
415 * this method will load classes and resources with privileges that are |
419 * restricted by the calling context of this method. </p> |
416 * restricted by the calling context of this method. </p> |
420 * |
417 * |
431 * @throws IllegalArgumentException |
428 * @throws IllegalArgumentException |
432 * If the parent configurations do not match the configuration of |
429 * If the parent configurations do not match the configuration of |
433 * the parent layers, including order |
430 * the parent layers, including order |
434 * @throws LayerInstantiationException |
431 * @throws LayerInstantiationException |
435 * If all modules cannot be defined to the same class loader for any |
432 * If all modules cannot be defined to the same class loader for any |
436 * of the reasons listed above or the layer cannot be created because |
433 * of the reasons listed above |
437 * the configuration contains a module named "{@code java.base}" or |
|
438 * a module with a package name starting with "{@code java.}" |
|
439 * @throws SecurityException |
434 * @throws SecurityException |
440 * If {@code RuntimePermission("createClassLoader")} or |
435 * If {@code RuntimePermission("createClassLoader")} or |
441 * {@code RuntimePermission("getClassLoader")} is denied by |
436 * {@code RuntimePermission("getClassLoader")} is denied by |
442 * the security manager |
437 * the security manager |
443 * |
438 * |
478 * The package may be exported by another module in this layer to the |
473 * The package may be exported by another module in this layer to the |
479 * module defined to the class loader. It may be in a package exported by a |
474 * module defined to the class loader. It may be in a package exported by a |
480 * module in a parent layer. The class loader delegates to the class loader |
475 * module in a parent layer. The class loader delegates to the class loader |
481 * of the module, throwing {@code ClassNotFoundException} if not found by |
476 * of the module, throwing {@code ClassNotFoundException} if not found by |
482 * that class loader. |
477 * that class loader. |
483 * |
|
484 * When {@code loadClass} is invoked to load classes that do not map to a |
478 * When {@code loadClass} is invoked to load classes that do not map to a |
485 * module then it delegates to the parent class loader. </p> |
479 * module then it delegates to the parent class loader. </p> |
486 * |
480 * |
487 * <p> If there is a security manager then the class loaders created by |
481 * <p> If there is a security manager then the class loaders created by |
488 * this method will load classes and resources with privileges that are |
482 * this method will load classes and resources with privileges that are |
531 } |
525 } |
532 } |
526 } |
533 |
527 |
534 /** |
528 /** |
535 * Creates a new layer by defining the modules in the given {@code |
529 * Creates a new layer by defining the modules in the given {@code |
536 * Configuration} to the Java virtual machine. |
530 * Configuration} to the Java virtual machine. The given function maps each |
537 * Each module is mapped, by name, to its class loader by means of the |
531 * module in the configuration, by name, to a class loader. Creating the |
538 * given function. The class loader delegation implemented by these class |
532 * layer informs the Java virtual machine about the classes that may be |
539 * loaders must respect module readability. The class loaders should be |
533 * loaded so that the Java virtual machine knows which module that each |
|
534 * class is a member of. |
|
535 * |
|
536 * <p> The class loader delegation implemented by the class loaders must |
|
537 * respect module readability. The class loaders should be |
540 * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to |
538 * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to |
541 * avoid deadlocks during class loading. In addition, the entity creating |
539 * avoid deadlocks during class loading. In addition, the entity creating |
542 * a new layer with this method should arrange that the class loaders are |
540 * a new layer with this method should arrange that the class loaders be |
543 * ready to load from these modules before there are any attempts to load |
541 * ready to load from these modules before there are any attempts to load |
544 * classes or resources. |
542 * classes or resources. </p> |
545 * |
543 * |
546 * <p> Creating a {@code Layer} can fail for the following reasons: </p> |
544 * <p> Creating a {@code Layer} can fail for the following reasons: </p> |
547 * |
545 * |
548 * <ul> |
546 * <ul> |
549 * |
547 * |
555 * |
553 * |
556 * <li><p> A module is mapped to a class loader that has already |
554 * <li><p> A module is mapped to a class loader that has already |
557 * defined types in any of the packages in the module. </p></li> |
555 * defined types in any of the packages in the module. </p></li> |
558 * |
556 * |
559 * </ul> |
557 * </ul> |
|
558 * |
|
559 * <p> In addition, a layer cannot be created if the configuration contains |
|
560 * a module named "{@code java.base}", a configuration contains a module |
|
561 * with a package name starting with "{@code java.}" is mapped to a class |
|
562 * loader other than the {@link ClassLoader#getPlatformClassLoader() |
|
563 * platform class loader}, or the function to map a module name to a class |
|
564 * loader returns {@code null}. </p> |
560 * |
565 * |
561 * <p> If the function to map a module name to class loader throws an error |
566 * <p> If the function to map a module name to class loader throws an error |
562 * or runtime exception then it is propagated to the caller of this method. |
567 * or runtime exception then it is propagated to the caller of this method. |
563 * </p> |
568 * </p> |
564 * |
569 * |
565 * @apiNote It is implementation specific as to whether creating a Layer |
570 * @apiNote It is implementation specific as to whether creating a Layer |
566 * with this method is an atomic operation or not. Consequentially it is |
571 * with this method is an atomic operation or not. Consequentially it is |
567 * possible for this method to fail with some modules, but not all, defined |
572 * possible for this method to fail with some modules, but not all, defined |
568 * to Java virtual machine. |
573 * to the Java virtual machine. |
569 * |
574 * |
570 * @param cf |
575 * @param cf |
571 * The configuration for the layer |
576 * The configuration for the layer |
572 * @param parentLayers |
577 * @param parentLayers |
573 * The list parent layers in search order |
578 * The list parent layers in search order |
578 * |
583 * |
579 * @throws IllegalArgumentException |
584 * @throws IllegalArgumentException |
580 * If the parent configurations do not match the configuration of |
585 * If the parent configurations do not match the configuration of |
581 * the parent layers, including order |
586 * the parent layers, including order |
582 * @throws LayerInstantiationException |
587 * @throws LayerInstantiationException |
583 * If creating the {@code Layer} fails for any of the reasons |
588 * If creating the layer fails for any of the reasons listed above |
584 * listed above, the layer cannot be created because the |
|
585 * configuration contains a module named "{@code java.base}", |
|
586 * a module with a package name starting with "{@code java.}" is |
|
587 * mapped to a class loader other than the {@link |
|
588 * ClassLoader#getPlatformClassLoader() platform class loader}, |
|
589 * or the function to map a module name to a class loader returns |
|
590 * {@code null} |
|
591 * @throws SecurityException |
589 * @throws SecurityException |
592 * If {@code RuntimePermission("getClassLoader")} is denied by |
590 * If {@code RuntimePermission("getClassLoader")} is denied by |
593 * the security manager |
591 * the security manager |
594 */ |
592 */ |
595 public static Controller defineModules(Configuration cf, |
593 public static Controller defineModules(Configuration cf, |
761 } |
759 } |
762 |
760 |
763 |
761 |
764 /** |
762 /** |
765 * Returns the module with the given name in this layer, or if not in this |
763 * Returns the module with the given name in this layer, or if not in this |
766 * layer, the {@linkplain #parents parents} layers. Finding a module in |
764 * layer, the {@linkplain #parents parent} layers. Finding a module in |
767 * parent layers is equivalent to invoking {@code findModule} on each |
765 * parent layers is equivalent to invoking {@code findModule} on each |
768 * parent, in search order, until the module is found or all parents have |
766 * parent, in search order, until the module is found or all parents have |
769 * been searched. In a <em>tree of layers</em> then this is equivalent to |
767 * been searched. In a <em>tree of layers</em> then this is equivalent to |
770 * a depth-first search. |
768 * a depth-first search. |
771 * |
769 * |