|
FlexDoc/Javadoc 2.0 Demo Java Doc |
A layer is created from a graph of modules in a Configuration and a function that maps each module to a ClassLoader. Creating a layer informs the Java virtual machine about the classes that may be loaded from the modules so that the Java virtual machine knows which module that each class is a member of.
Creating a layer creates a Module object for each ResolvedModule in the configuration. For each resolved module that is read, the Module reads the corresponding run-time Module, which may be in the same layer or a parent layer.
The defineModulesWithOneLoader and defineModulesWithManyLoaders methods provide convenient ways to create a module layer where all modules are mapped to a single class loader or where each module is mapped to its own class loader. The defineModules method is for more advanced cases where modules are mapped to custom class loaders by means of a function specified to the method. Each of these methods has an instance and static variant. The instance methods create a layer with the receiver as the parent layer. The static methods are for more advanced cases where there can be more than one parent layer or where a Controller is needed to control modules in the layer
A Java virtual machine has at least one non-empty layer, the boot layer, that is created when the Java virtual machine is started. The boot layer contains module java.base and is the only layer in the Java virtual machine with a module named "java.base". The modules in the boot layer are mapped to the bootstrap class loader and other class loaders that are built-in into the Java virtual machine. The boot layer will often be the parent when creating additional layers.
Each Module in a layer is created so that it exports and opens the packages described by its ModuleDescriptor. Qualified exports (where a package is exported to a set of target modules rather than all modules) are reified when creating the layer as follows:
Qualified opens are handled in same way as qualified exports.
As when creating a Configuration, automatic modules receive special treatment when creating a layer. An automatic module is created in the Java virtual machine as a Module that reads every unnamed Module in the Java virtual machine.
Unless otherwise specified, passing a null argument to a method in this class causes a NullPointerException to be thrown.
This example creates a configuration by resolving a module named "myapp" with the configuration for the boot layer as the parent. It then creates a new layer with the modules in this configuration. All modules are defined to the same class loader.
ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
ModuleLayer parent = ModuleLayer.boot();
Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
Nested Class Summary |
||
static class |
Controls a module layer.
|
Method Summary |
||
static ModuleLayer |
boot()
Returns the boot layer.
|
|
Returns the configuration for this layer.
|
||
Creates a new module layer, with this layer as its parent, by defining the
modules in the given Configuration to the Java virtual machine.
|
||
static ModuleLayer.Controller |
Creates a new module layer by defining the modules in the given
Configuration to the Java virtual machine.
|
|
Creates a new module layer, with this layer as its parent, by defining the
modules in the given Configuration to the Java virtual machine.
|
||
static ModuleLayer.Controller |
defineModulesWithManyLoaders(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
Creates a new module layer by defining the modules in the given
Configuration to the Java virtual machine.
|
|
Creates a new module layer, with this layer as its parent, by defining the
modules in the given Configuration to the Java virtual machine.
|
||
static ModuleLayer.Controller |
defineModulesWithOneLoader(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
Creates a new module layer by defining the modules in the given
Configuration to the Java virtual machine.
|
|
static ModuleLayer |
empty()
Returns the empty layer.
|
|
findLoader(String name)
Returns the ClassLoader for the module with the given name.
|
||
findModule(String name)
Returns the module with the given name in this layer, or if not in this
layer, the parent layers.
|
||
modules()
Returns an unmodifiable set of the modules in this layer.
|
||
parents()
Returns an unmodifiable list of this layer's parents, in search
order.
|
||
toString()
Returns a string describing this module layer.
|
Methods inherited from class java.lang.Object |
public ModuleLayer defineModulesWithOneLoader |
ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
public ModuleLayer defineModulesWithManyLoaders |
ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
public ModuleLayer defineModules |
ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
public static ModuleLayer.Controller defineModulesWithOneLoader |
The class loader created by this method implements direct delegation when loading classes from modules. If the loadClass method is invoked to load a class then it uses the package name of the class to map it to a module. This may be a module in this layer and hence defined to the same class loader. It may be a package in a module in a parent layer that is exported to one or more of the modules in this layer. The class loader delegates to the class loader of the module, throwing ClassNotFoundException if not found by that class loader. When loadClass is invoked to load classes that do not map to a module then it delegates to the parent class loader.
The class loader created by this method locates resources (getResource, getResources, and other resource methods) in all modules in the layer before searching the parent class loader.
Attempting to create a layer with all modules defined to the same class loader can fail for the following reasons:
Overlapping packages: Two or more modules in the configuration have the same package.
Split delegation: The resulting class loader would need to delegate to more than one class loader in order to load classes in a specific package.
In addition, a layer cannot be created if the configuration contains a module named "java.base", or a module contains a package named "java" or a package with a name starting with "java.".
If there is a security manager then the class loader created by this method will load classes and resources with privileges that are restricted by the calling context of this method.
public static ModuleLayer.Controller defineModulesWithManyLoaders |
The class loaders created by this method implement direct delegation when loading classes from modules. If the loadClass method is invoked to load a class then it uses the package name of the class to map it to a module. The package may be in the module defined to the class loader. The package may be exported by another module in this layer to the module defined to the class loader. It may be in a package exported by a module in a parent layer. The class loader delegates to the class loader of the module, throwing ClassNotFoundException if not found by that class loader. When loadClass is invoked to load a class that does not map to a module then it delegates to the parent class loader.
The class loaders created by this method locate resources (getResource, getResources, and other resource methods) in the module defined to the class loader before searching the parent class loader.
If there is a security manager then the class loaders created by this method will load classes and resources with privileges that are restricted by the calling context of this method.
public static ModuleLayer.Controller defineModules |
The class loader delegation implemented by the class loaders must respect module readability. The class loaders should be parallel-capable so as to avoid deadlocks during class loading. In addition, the entity creating a new layer with this method should arrange that the class loaders be ready to load from these modules before there are any attempts to load classes or resources.
Creating a layer can fail for the following reasons:
Two or more modules with the same package are mapped to the same class loader.
A module is mapped to a class loader that already has a module of the same name defined to it.
A module is mapped to a class loader that has already defined types in any of the packages in the module.
In addition, a layer cannot be created if the configuration contains a module named "java.base", a configuration contains a module with a package named "java" or a package name starting with "java.", or the function to map a module name to a class loader returns null or the platform class loader.
If the function to map a module name to class loader throws an error or runtime exception then it is propagated to the caller of this method.
public Configuration configuration |
() |
() |
() |
(String name) |
public ClassLoader findLoader |
(String name) |
If there is a security manager then its checkPermission method is called with a RuntimePermission("getClassLoader") permission to check that the caller is allowed to get access to the class loader.
public String toString |
() |
public static ModuleLayer empty |
() |
public static ModuleLayer boot |
() |
|
FlexDoc/Javadoc 2.0 Demo Java Doc |