Class ModuleLayer
A layer is created from a graph of modules in aConfigurationand a function that maps each module to aClassLoader.Creating a layer informs the Java virtual machine about the classes thatmay be loaded from the modules so that the Java virtual machine knows whichmodule that each class is a member of.
Creating a layer creates aModule object for eachResolvedModule in the configuration. For each resolved module that isread, theModulereads the corresponding run-timeModule, which maybe in the same layer or aparent layer.
ThedefineModulesWithOneLoader anddefineModulesWithManyLoaders methodsprovide convenient ways to create a module layer where all modules aremapped to a single class loader or where each module is mapped to its ownclass loader. ThedefineModules method is for moreadvanced cases where modules are mapped to custom class loaders by means ofa function specified to the method. Each of these methods has an instanceand static variant. The instance methods create a layer with the receiveras the parent layer. The static methods are for more advanced cases wherethere can be more than one parent layer or where aController is needed to control modules in the layer
A Java virtual machine has at least one non-empty layer, theboot layer, that is created when the Java virtual machine isstarted. The boot layer contains modulejava.base and is the onlylayer in the Java virtual machine with a module named "java.base".The modules in the boot layer are mapped to the bootstrap class loader andother class loaders that arebuilt-in into the Java virtual machine. The boot layer will often betheparent when creating additional layers.
EachModule in a layer is created so that itexports andopensthe packages described by itsModuleDescriptor. Qualified exports(where a package is exported to a set of target modules rather than allmodules) are reified when creating the layer as follows:
- If module
Xexports a package toY, and if the runtimeModuleXreadsModuleY, then the package is exported toModuleY(which may be in the same layer asXor a parent layer). - If module
Xexports a package toY, and if the runtimeModuleXdoes not readYthen targetYis located as if by invokingfindModuleto find the module in the layer or its parent layers. IfYis found then the package is exported to the instance ofYthat was found. IfYis not found then the qualified export is ignored.
Qualified opens are handled in same way as qualified exports.
As when creating aConfiguration,automatic modules receive specialtreatment when creating a layer. An automatic module is created in theJava virtual machine as aModule that reads every unnamedModule in the Java virtual machine.
Unless otherwise specified, passing anull argument to a methodin this class causes aNullPointerException tobe thrown.
Example
This example creates a configuration by resolving a module named"myapp" with the configuration for the boot layer as the parent. Itthen creates a new layer with the modules in this configuration. All modulesare 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");- Since:
- 9
- See Also:
Nested Class Summary
Nested ClassesMethod Summary
Modifier and TypeMethodDescriptionstaticModuleLayerboot()Returns the boot layer.Returns the configuration for this layer.defineModules(Configuration cf,Function<String,ClassLoader> clf) Creates a new module layer, with this layer as its parent, by defining themodules in the givenConfigurationto the Java virtual machine.staticModuleLayer.ControllerdefineModules(Configuration cf,List<ModuleLayer> parentLayers,Function<String,ClassLoader> clf) Creates a new module layer by defining the modules in the givenConfigurationto the Java virtual machine.defineModulesWithManyLoaders(Configuration cf,ClassLoader parentLoader) Creates a new module layer, with this layer as its parent, by defining themodules in the givenConfigurationto the Java virtual machine.staticModuleLayer.ControllerdefineModulesWithManyLoaders(Configuration cf,List<ModuleLayer> parentLayers,ClassLoader parentLoader) Creates a new module layer by defining the modules in the givenConfigurationto the Java virtual machine.defineModulesWithOneLoader(Configuration cf,ClassLoader parentLoader) Creates a new module layer, with this layer as its parent, by defining themodules in the givenConfigurationto the Java virtual machine.staticModuleLayer.ControllerdefineModulesWithOneLoader(Configuration cf,List<ModuleLayer> parentLayers,ClassLoader parentLoader) Creates a new module layer by defining the modules in the givenConfigurationto the Java virtual machine.staticModuleLayerempty()Returns theempty layer.findLoader(String name) Returns theClassLoaderfor the module with the given name.findModule(String name) Returns the module with the given name in this layer, or if not in thislayer, theparent layers.modules()Returns an unmodifiable set of the modules in this layer.parents()Returns an unmodifiable list of this layer's parents, in searchorder.toString()Returns a string describing this module layer.
Method Details
defineModulesWithOneLoader
Creates a new module layer, with this layer as its parent, by defining themodules in the givenConfigurationto the Java virtual machine.This method creates one class loader and defines all modules to thatclass loader. Theparentof each classloader is the given parent class loader. This method works exactly asspecified by the staticdefineModulesWithOneLoadermethod when invoked with this layer as theparent. In other words, if this layer isthisLayerthen thismethod is equivalent to invoking:ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();- Parameters:
cf- The configuration for the layerparentLoader- The parent class loader for the class loader created by this method; may benullfor the bootstrap class loader- Returns:
- The newly created layer
- Throws:
IllegalArgumentException- If the given configuration has more than one parent or the parent of the configuration is not the configuration for this layerLayerInstantiationException- If the layer cannot be created for any of the reasons specified by the staticdefineModulesWithOneLoadermethod- See Also:
defineModulesWithManyLoaders
Creates a new module layer, with this layer as its parent, by defining themodules in the givenConfigurationto the Java virtual machine.Each module is defined to its ownClassLoadercreated by thismethod. Theparentof each class loaderis the given parent class loader. This method works exactly as specifiedby the staticdefineModulesWithManyLoadersmethod when invoked with this layer as theparent. In other words, if this layer isthisLayerthen thismethod is equivalent to invoking:ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();- Parameters:
cf- The configuration for the layerparentLoader- The parent class loader for each of the class loaders created by this method; may benullfor the bootstrap class loader- Returns:
- The newly created layer
- Throws:
IllegalArgumentException- If the given configuration has more than one parent or the parent of the configuration is not the configuration for this layerLayerInstantiationException- If the layer cannot be created for any of the reasons specified by the staticdefineModulesWithManyLoadersmethod- See Also:
defineModules
Creates a new module layer, with this layer as its parent, by defining themodules in the givenConfigurationto the Java virtual machine.Each module is mapped, by name, to its class loader by means of thegiven function. This method works exactly as specified by the staticdefineModulesmethod when invoked with this layer as the parent. In other words, ifthis layer isthisLayerthen this method is equivalent toinvoking:ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();- Parameters:
cf- The configuration for the layerclf- The function to map a module name to a class loader- Returns:
- The newly created layer
- Throws:
IllegalArgumentException- If the given configuration has more than one parent or the parent of the configuration is not the configuration for this layerLayerInstantiationException- If the layer cannot be created for any of the reasons specified by the staticdefineModulesmethod
defineModulesWithOneLoader
public static ModuleLayer.Controller defineModulesWithOneLoader(Configuration cf,List<ModuleLayer> parentLayers,ClassLoader parentLoader) Creates a new module layer by defining the modules in the givenConfigurationto the Java virtual machine. This method creates oneclass loader and defines all modules to that class loader.The class loader created by this method implementsdirectdelegation when loading classes from modules. If the
loadClassmethod is invoked toload a class then it uses the package name of the class to map it to amodule. This may be a module in this layer and hence defined to the sameclass loader. It may be a package in a module in a parent layer that isexported to one or more of the modules in this layer. The classloader delegates to the class loader of the module, throwingClassNotFoundExceptionif not found by that class loader.WhenloadClassis invoked to load classes that do not map to amodule then it delegates to the parent class loader.The class loader created by this method locates resources(
getResource,getResources, and other resourcemethods) in all modules in the layer before searching the parent classloader.Attempting to create a layer with all modules defined to the sameclass 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 containsa module named "
java.base", or a module contains a package named"java" or a package with a name starting with "java.".- Parameters:
cf- The configuration for the layerparentLayers- The list of parent layers in search orderparentLoader- The parent class loader for the class loader created by this method; may benullfor the bootstrap class loader- Returns:
- A controller that controls the newly created layer
- Throws:
IllegalArgumentException- If the parent(s) of the given configuration do not match the configuration of the parent layers, including orderLayerInstantiationException- If all modules cannot be defined to the same class loader for any of the reasons listed above- See Also:
defineModulesWithManyLoaders
public static ModuleLayer.Controller defineModulesWithManyLoaders(Configuration cf,List<ModuleLayer> parentLayers,ClassLoader parentLoader) Creates a new module layer by defining the modules in the givenConfigurationto the Java virtual machine. Each module is defined toits ownClassLoadercreated by this method. Theparentof each class loader is the given parentclass loader.The class loaders created by this method implementdirectdelegation when loading classes from modules. If the
loadClassmethod is invoked toload a class then it uses the package name of the class to map it to amodule. The package may be in the module defined to the class loader.The package may be exported by another module in this layer to themodule defined to the class loader. It may be in a package exported by amodule in a parent layer. The class loader delegates to the class loaderof the module, throwingClassNotFoundExceptionif not found bythat class loader. WhenloadClassis invoked to load a classthat does not map to a module then it delegates to the parent classloader.The class loaders created by this method locate resources(
getResource,getResources, and other resourcemethods) in the module defined to the class loader before searchingthe parent class loader.- Parameters:
cf- The configuration for the layerparentLayers- The list of parent layers in search orderparentLoader- The parent class loader for each of the class loaders created by this method; may benullfor the bootstrap class loader- Returns:
- A controller that controls the newly created layer
- Throws:
IllegalArgumentException- If the parent(s) of the given configuration do not match the configuration of the parent layers, including orderLayerInstantiationException- If the layer cannot be created because 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."- See Also:
defineModules
public static ModuleLayer.Controller defineModules(Configuration cf,List<ModuleLayer> parentLayers,Function<String,ClassLoader> clf) Creates a new module layer by defining the modules in the givenConfigurationto the Java virtual machine. The given function maps eachmodule in the configuration, by name, to a class loader. Creating thelayer informs the Java virtual machine about the classes that may beloaded so that the Java virtual machine knows which module that eachclass is a member of.The class loader delegation implemented by the class loaders mustrespect module readability. The class loaders should be
parallel-capableso as toavoid deadlocks during class loading. In addition, the entity creatinga new layer with this method should arrange that the class loaders beready to load from these modules before there are any attempts to loadclasses 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 containsa module named "
java.base", a configuration contains a modulewith a package named "java" or a package name starting with"java.", or the function to map a module name to a class loaderreturnsnullor theplatform class loader.If the function to map a module name to class loader throws an erroror runtime exception then it is propagated to the caller of this method.
- API Note:
- It is implementation specific as to whether creating a layerwith this method is an atomic operation or not. Consequently it ispossible for this method to fail with some modules, but not all, definedto the Java virtual machine.
- Parameters:
cf- The configuration for the layerparentLayers- The list of parent layers in search orderclf- The function to map a module name to a class loader- Returns:
- A controller that controls the newly created layer
- Throws:
IllegalArgumentException- If the parent(s) of the given configuration do not match the configuration of the parent layers, including orderLayerInstantiationException- If creating the layer fails for any of the reasons listed above
configuration
Returns the configuration for this layer.- Returns:
- The configuration for this layer
parents
Returns an unmodifiable list of this layer's parents, in searchorder. If this is theempty layer then anempty list is returned.- Returns:
- A possibly-empty unmodifiable list of this layer's parents
modules
findModule
Returns the module with the given name in this layer, or if not in thislayer, theparent layers. Finding a module inparent layers is equivalent to invokingfindModuleon eachparent, in search order, until the module is found or all parents havebeen searched. In atree of layers then this is equivalent toa depth-first search.- Parameters:
name- The name of the module to find- Returns:
- The module with the given name or an empty
Optionalif there isn't a module with this name in this layer or any parent layer
findLoader
Returns theClassLoaderfor the module with the given name. Ifa module of the given name is not in this layer then theparentlayers are searched in the manner specified byfindModule.- API Note:
- This method does not return an
Optional<ClassLoader>because `null` must be used to represent the bootstrap class loader. - Parameters:
name- The name of the module to find- Returns:
- The ClassLoader that the module is defined to
- Throws:
IllegalArgumentException- if a module of the given name is not defined in this layer or any parent of this layer
toString
empty
Returns theempty layer. There are no modules in the emptylayer. It has no parents.- Returns:
- The empty layer
boot
Returns the boot layer. The boot layer contains at least one module,java.base. Its parent is theemptylayer.- API Note:
- This method returns
nullduring startup and before the boot layer is fully initialized. - Returns:
- The boot layer