public final class Layer extends Object
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 Module
exports
and opens
the packages described by its ModuleDescriptor
.
The defineModulesWithOneLoader
and
defineModulesWithManyLoaders
methods
provide convenient ways to create a 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.
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);
Layer parent = Layer.boot();
Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = parent.defineModulesWithOneLoader(cf, scl);
Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
Module.getLayer()
Modifier and Type | Class | Description |
---|---|---|
static class |
Layer.Controller |
Controls a layer.
|
Modifier and Type | Method | Description |
---|---|---|
static Layer |
boot() |
Returns the boot layer.
|
Configuration |
configuration() |
Returns the configuration for this layer.
|
Layer |
defineModules(Configuration cf,
Function<String,ClassLoader> clf) |
Creates a new layer, with this layer as its parent, by defining the
modules in the given
Configuration to the Java virtual machine. |
static Layer.Controller |
defineModules(Configuration cf,
List<Layer> parentLayers,
Function<String,ClassLoader> clf) |
Creates a new layer by defining the modules in the given
Configuration to the Java virtual machine. |
Layer |
defineModulesWithManyLoaders(Configuration cf,
ClassLoader parentLoader) |
Creates a new layer, with this layer as its parent, by defining the
modules in the given
Configuration to the Java virtual machine. |
static Layer.Controller |
defineModulesWithManyLoaders(Configuration cf,
List<Layer> parentLayers,
ClassLoader parentLoader) |
Creates a new layer by defining the modules in the given
Configuration to the Java virtual machine. |
Layer |
defineModulesWithOneLoader(Configuration cf,
ClassLoader parentLoader) |
Creates a new layer, with this layer as its parent, by defining the
modules in the given
Configuration to the Java virtual machine. |
static Layer.Controller |
defineModulesWithOneLoader(Configuration cf,
List<Layer> parentLayers,
ClassLoader parentLoader) |
Creates a new layer by defining the modules in the given
Configuration to the Java virtual machine. |
static Layer |
empty() |
Returns the empty layer.
|
ClassLoader |
findLoader(String name) |
Returns the
ClassLoader for the module with the given name. |
Optional<Module> |
findModule(String name) |
Returns the module with the given name in this layer, or if not in this
layer, the parent layers.
|
Set<Module> |
modules() |
Returns the set of the modules in this layer.
|
List<Layer> |
parents() |
Returns the list of this layer's parents unless this is the
empty layer, which has no parents and so an
empty list is returned.
|
String |
toString() |
Returns a string describing this layer.
|
public Layer defineModulesWithOneLoader(Configuration cf, ClassLoader parentLoader)
Configuration
to the Java virtual machine.
This method creates one class loader and defines all modules to that
class loader. The parent
of each class
loader is the given parent class loader. This method works exactly as
specified by the static defineModulesWithOneLoader
method when invoked with this layer as the
parent. In other words, if this layer is thisLayer
then this
method is equivalent to invoking:
Layer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
cf
- The configuration for the layerparentLoader
- The parent class loader for the class loader created by this
method; may be null
for the bootstrap class loaderIllegalArgumentException
- If the parent of the given configuration is not the configuration
for this layerLayerInstantiationException
- If the layer cannot be created for any of the reasons specified
by the static defineModulesWithOneLoader
methodSecurityException
- If RuntimePermission("createClassLoader")
or
RuntimePermission("getClassLoader")
is denied by
the security managerfindLoader(java.lang.String)
public Layer defineModulesWithManyLoaders(Configuration cf, ClassLoader parentLoader)
Configuration
to the Java virtual machine.
Each module is defined to its own ClassLoader
created by this
method. The parent
of each class loader
is the given parent class loader. This method works exactly as specified
by the static defineModulesWithManyLoaders
method when invoked with this layer as the
parent. In other words, if this layer is thisLayer
then this
method is equivalent to invoking:
Layer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
cf
- The configuration for the layerparentLoader
- The parent class loader for each of the class loaders created by
this method; may be null
for the bootstrap class loaderIllegalArgumentException
- If the parent of the given configuration is not the configuration
for this layerLayerInstantiationException
- If the layer cannot be created for any of the reasons specified
by the static defineModulesWithManyLoaders
methodSecurityException
- If RuntimePermission("createClassLoader")
or
RuntimePermission("getClassLoader")
is denied by
the security managerfindLoader(java.lang.String)
public Layer defineModules(Configuration cf, Function<String,ClassLoader> clf)
Configuration
to the Java virtual machine.
Each module is mapped, by name, to its class loader by means of the
given function. This method works exactly as specified by the static
defineModules
method when invoked with this layer as the parent. In other words, if
this layer is thisLayer
then this method is equivalent to
invoking:
Layer.defineModules(cf, List.of(thisLayer), clf).layer();
cf
- The configuration for the layerclf
- The function to map a module name to a class loaderIllegalArgumentException
- If the parent of the given configuration is not the configuration
for this layerLayerInstantiationException
- If the layer cannot be created for any of the reasons specified
by the static defineModules
methodSecurityException
- If RuntimePermission("getClassLoader")
is denied by
the security managerpublic static Layer.Controller defineModulesWithOneLoader(Configuration cf, List<Layer> parentLayers, ClassLoader parentLoader)
Configuration
to the Java virtual machine. This method creates one
class loader and defines all modules to that class loader.
The class loader created by this method implements direct
delegation when loading types from modules. When its 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.
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 types in a specific package.
In addition, a layer cannot be created if the configuration contains
a module named "java.base
" or a module with a package 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.
cf
- The configuration for the layerparentLayers
- The list parent layers in search orderparentLoader
- The parent class loader for the class loader created by this
method; may be null
for the bootstrap class loaderIllegalArgumentException
- If the parent configurations 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 aboveSecurityException
- If RuntimePermission("createClassLoader")
or
RuntimePermission("getClassLoader")
is denied by
the security managerfindLoader(java.lang.String)
public static Layer.Controller defineModulesWithManyLoaders(Configuration cf, List<Layer> parentLayers, ClassLoader parentLoader)
Configuration
to the Java virtual machine. Each module is defined to
its own ClassLoader
created by this method. The parent
of each class loader is the given parent
class loader.
The class loaders created by this method implement direct
delegation when loading types from modules. When 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 classes that do not map to a
module then it delegates to 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.
cf
- The configuration for the layerparentLayers
- The list parent layers in search orderparentLoader
- The parent class loader for each of the class loaders created by
this method; may be null
for the bootstrap class loaderIllegalArgumentException
- If the parent configurations 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 with a package
name starting with "java.
"SecurityException
- If RuntimePermission("createClassLoader")
or
RuntimePermission("getClassLoader")
is denied by
the security managerfindLoader(java.lang.String)
public static Layer.Controller defineModules(Configuration cf, List<Layer> parentLayers, Function<String,ClassLoader> clf)
Configuration
to the Java virtual machine. The given function maps each
module in the configuration, by name, to a class loader. Creating the
layer informs the Java virtual machine about the classes that may be
loaded so that the Java virtual machine knows which module that each
class is a member of.
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 name starting with "java.
" is mapped to a class
loader other than the platform class loader
, or the function to map a module name to a class
loader returns null
.
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.
cf
- The configuration for the layerparentLayers
- The list parent layers in search orderclf
- The function to map a module name to a class loaderIllegalArgumentException
- If the parent configurations do not match the configuration of
the parent layers, including orderLayerInstantiationException
- If creating the layer fails for any of the reasons listed aboveSecurityException
- If RuntimePermission("getClassLoader")
is denied by
the security managerpublic Configuration configuration()
public List<Layer> parents()
public Set<Module> modules()
public Optional<Module> findModule(String name)
findModule
on each
parent, in search order, until the module is found or all parents have
been searched. In a tree of layers then this is equivalent to
a depth-first search.name
- The name of the module to findOptional
if there isn't a module with this name in this layer or any
parent layerpublic ClassLoader findLoader(String name)
ClassLoader
for the module with the given name. If
a module of the given name is not in this layer then the parent
layers are searched in the manner specified by findModule
.
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.
Optional<ClassLoader>
because `null` must be used to represent the bootstrap class loader.name
- The name of the module to findIllegalArgumentException
- if a module of the given name is not
defined in this layer or any parent of this layerSecurityException
- if denied by the security managerpublic String toString()
public static Layer empty()
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2017, Oracle and/or its affiliates. 500 Oracle Parkway
Redwood Shores, CA 94065 USA. All rights reserved.
DRAFT 9-internal+0-adhoc.mlchung.jdk9-jdeps