- java.lang.Object
-
- java.lang.ModuleLayer
-
public final class ModuleLayer extends Object
Java虚拟机中的一层模块。从
Configuration
中的模块图形创建一个图层,并将每个模块映射到一个ClassLoader
。 创建一个层可以向Java虚拟机通知可能从模块加载的类,以便Java虚拟机知道每个类是哪一个模块。创建图层将为配置中的每个
ResolvedModule
创建一个Module
对象。 对于每个解决模块是read
时,Module
reads
相应的运行时Module
,其可以是在同一层或parent
层。defineModulesWithOneLoader
和defineModulesWithManyLoaders
方法提供了创建模块层的方便方法,其中所有模块都映射到单个类加载器或每个模块映射到其自己的类加载器。defineModules
方法用于通过对该方法指定的函数将模块映射到自定义类加载器的更高级情况。 这些方法中的每一个都有一个实例和静态变体。 实例方法创建一个层,接收方作为父层。 静态方法适用于可能有多于一个父层或需要Controller
来控制层中的模块的更高级情况Java虚拟机至少有一个非空层,即在启动Java虚拟机时创建的
boot
层。 引导层包含模块java.base
,是Java虚拟机中唯一一个名为“java.base
”模块的层。 引导层中的模块映射到引导类加载器和其他类型加载器,它们是built-in到Java虚拟机中。 创建附加图层时,引导层通常将为parent
。每个
Module
中的一个图层是创建的,因此它的exports
和opens
由其描述的包装ModuleDescriptor
。 在创建图层时,合格的导出(其中将软件包导出到一组目标模块而不是所有模块)被归纳如下:- 如果模块
X
将软件包导出到Y
,如果运行时Module
X
读取Module
Y
,则软件包将导出为Module
Y
(可能与X
或父层相同)。 - 如果模块
X
将包导出到Y
,并且如果运行时Module
X
未读取Y
则目标Y
位于仿佛通过调用findModule
以查找该层或其父层中的模块。 如果找到了Y
,那么包将被导出到找到的Y
的实例。 如果Y
那么合格的导出将被忽略。
合格的打开以与合格出口相同的方式处理。
当创建
Configuration
,automatic
模块在创建图层时会受到特殊处理。 自动模块在Java虚拟机中创建为Module
,它读取Java虚拟机中的每个未命名的Module
。除非另有说明,否则将
null
参数传递给null
中的方法将导致抛出NullPointerException
。使用示例
此示例通过解析名为“
myapp
”的模块来创建配置,引导层的配置为父级。 然后在此配置中使用模块创建一个新层。 所有模块都定义为同一个类加载器。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");
- 从以下版本开始:
- 9
- 另请参见:
-
Module.getLayer()
- 如果模块
-
-
Nested Class Summary
Nested Classes Modifier and Type Class 描述 static class
ModuleLayer.Controller
控制模块层。
-
方法摘要
所有方法 静态方法 接口方法 具体的方法 Modifier and Type 方法 描述 static ModuleLayer
boot()
返回引导层。Configuration
configuration()
返回此图层的配置。ModuleLayer
defineModules(Configuration cf, Function<String,ClassLoader> clf)
通过将给定的Configuration
的模块定义到Java虚拟机,创建一个新的模块层,将该层作为其父层。static ModuleLayer.Controller
defineModules(Configuration cf, List<ModuleLayer> parentLayers, Function<String,ClassLoader> clf)
通过将给定的Configuration
的模块定义到Java虚拟机来创建新的模块层。ModuleLayer
defineModulesWithManyLoaders(Configuration cf, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机,创建一个新的模块层,将该层作为其父层。static ModuleLayer.Controller
defineModulesWithManyLoaders(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
通过在给定的Java虚拟机的Configuration
定义模块来创建新的模块层。ModuleLayer
defineModulesWithOneLoader(Configuration cf, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机,创建一个新的模块层,将该层作为其父层。static ModuleLayer.Controller
defineModulesWithOneLoader(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机来创建新的模块层。static ModuleLayer
empty()
返回 空层。ClassLoader
findLoader(String name)
返回具有给定名称的模块的ClassLoader
。Optional<Module>
findModule(String name)
在此层中返回具有给定名称的模块,或者如果不在此层中,则 返回parent层。Set<Module>
modules()
返回此图层中的模块集。List<ModuleLayer>
parents()
返回此图层的父母的列表,除非是 empty layer ,它没有父母,因此返回空列表。String
toString()
返回描述此模块层的字符串。
-
-
-
方法详细信息
-
defineModulesWithOneLoader
public ModuleLayer defineModulesWithOneLoader(Configuration cf, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机,创建一个新的模块层,将该层作为其父层。 该方法创建一个类加载器并将所有模块定义到该类加载器。 每个类加载器的parent
是给定的父类加载器。 当该层作为父级调用时,此方法的工作原理与静态的defineModulesWithOneLoader
方法所指定。 换句话说,如果这个层是thisLayer
那么这个方法就等于调用:ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
- 参数
-
cf
- 图层的配置 -
parentLoader
- 通过此方法创建的类加载器的父类加载器; 可以是引导类加载器的null
- 结果
- 新创建的图层
- 异常
-
IllegalArgumentException
- 如果给定配置的父IllegalArgumentException
不是此层的配置 -
LayerInstantiationException
- 如果由静态defineModulesWithOneLoader
方法指定的任何原因无法创建defineModulesWithOneLoader
-
SecurityException
- 如果RuntimePermission("createClassLoader")
或RuntimePermission("getClassLoader")
被安全管理员拒绝 - 另请参见:
-
findLoader(java.lang.String)
-
defineModulesWithManyLoaders
public ModuleLayer defineModulesWithManyLoaders(Configuration cf, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机,创建一个新的模块层,将该层作为其父层。 每个模块都被定义为它自己的ClassLoader
创建的这种方法。 每个类加载器的parent
是给定的父类加载器。 当以此层作为父类调用时,此方法与静态的defineModulesWithManyLoaders
方法一样工作。 换句话说,如果这个层是thisLayer
那么这个方法就等于调用:ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
- 参数
-
cf
- 层的配置 -
parentLoader
- 通过此方法创建的每个类加载器的父类加载器; 可以是引导类加载器的null
- 结果
- 新创建的图层
- 异常
-
IllegalArgumentException
- 如果给定配置的父级不是此层的配置 -
LayerInstantiationException
- 如果由静态defineModulesWithManyLoaders
方法指定的任何原因无法创建defineModulesWithManyLoaders
-
SecurityException
- 如果RuntimePermission("createClassLoader")
或RuntimePermission("getClassLoader")
被安全管理员拒绝 - 另请参见:
-
findLoader(java.lang.String)
-
defineModules
public ModuleLayer defineModules(Configuration cf, Function<String,ClassLoader> clf)
通过将给定的Configuration
的模块定义到Java虚拟机,创建一个新的模块层,将该层作为其父层。 每个模块通过给定的功能按名称映射到其类加载器。 当以此层作为父级调用时,此方法的工作原理与静态的defineModules
方法一样。 换句话说,如果这个层是thisLayer
那么这个方法相当于调用:ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
- 参数
-
cf
- 图层的配置 -
clf
- 将模块名称映射到类加载器的功能 - 结果
- 新创建的图层
- 异常
-
IllegalArgumentException
- 如果给定配置的父IllegalArgumentException
不是此层的配置 -
LayerInstantiationException
- 如果由静态defineModules
方法指定的任何原因无法创建defineModules
-
SecurityException
- 如果安全管理员拒绝了RuntimePermission("getClassLoader")
-
defineModulesWithOneLoader
public static ModuleLayer.Controller defineModulesWithOneLoader(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机来创建新的模块层。 该方法创建一个类加载器并将所有模块定义到该类加载器。通过此方法创建的类加载器在从模块加载类时实现直接委派 。 如果调用了
loadClass
方法来加载类,那么它将使用该类的包名将其映射到一个模块。 这可能是此层中的一个模块,因此定义为同一类加载器。 它可能是父层中的模块中的一个包,该包将导出到该层中的一个或多个模块。 类加载器委托给模块的类加载器,如果该类加载器找不到,则抛出ClassNotFoundException
。 当调用loadClass
加载不映射到模块的类时,它将委托给父类加载器。通过这种方法创建的类加载器定位资源(
getResource
,getResources
搜索父类加载器之前在层中的所有模块和其它资源的方法)。尝试创建具有定义到同一类加载器的所有模块的图层可能会失败,原因如下:
重叠包 :配置中的两个或多个模块具有相同的包。
拆分委托 :生成的类加载器需要委托给多个类加载器才能加载特定包中的类。
另外,如果配置包含名为“
java.base
”的模块,或模块包含名为“java
”的软件包或名称以“java.
”开头的软件包,则无法创建java.
。如果有一个安全管理器,那么这个方法创建的类加载器将加载受该方法调用上下文限制的权限的类和资源。
- 参数
-
cf
- 图层的配置 -
parentLayers
- 搜索顺序中的父层列表 -
parentLoader
- 通过此方法创建的类加载器的父类加载器; 可以是引导类加载器的null
- 结果
- 控制新创建的图层的控制器
- 异常
-
IllegalArgumentException
- 如果父配置与父层的配置不匹配,包括顺序 -
LayerInstantiationException
- 如果由于上述任何原因,所有模块都不能被定义到同一个类加载器 -
SecurityException
- 如果RuntimePermission("createClassLoader")
或RuntimePermission("getClassLoader")
被安全管理员拒绝 - 另请参见:
-
findLoader(java.lang.String)
-
defineModulesWithManyLoaders
public static ModuleLayer.Controller defineModulesWithManyLoaders(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
通过将给定的Configuration
的模块定义到Java虚拟机来创建新的模块层。 每个模块都被定义为自己创建的这个方法的ClassLoader
。 每个类加载器的parent
是给定的父类加载器。通过此方法创建的类加载器在从模块加载类时实现直接委派 。 如果调用了
loadClass
方法来加载类,那么它将使用该类的包名将其映射到一个模块。 该包可能在定义为类加载器的模块中。 该包可以由此层中的另一个模块导出到定义到类加载器的模块。 它可能在由父层中的模块导出的包中。 类加载器委托给模块的类加载器,如果该类加载器找不到,则抛出ClassNotFoundException
。 当调用loadClass
加载不映射到模块的类时,它将委托给父类加载器。通过这种方法创建的类加载器定位资源(
getResource
,getResources
搜索父类加载器之前定义的类加载器模块中,和其他资源的方法)。如果有一个安全管理器,那么这个方法创建的类加载器将加载受该方法调用上下文限制的权限的类和资源。
- 参数
-
cf
- 图层的配置 -
parentLayers
- 搜索顺序中的父层列表 -
parentLoader
- 通过此方法创建的每个类加载器的父类加载器; 可以是引导类加载器的null
- 结果
- 控制新创建的图层的控制器
- 异常
-
IllegalArgumentException
- 如果父配置与父层的配置不匹配,包括顺序 -
LayerInstantiationException
- 如果由于配置包含名为“java.base
”的模块或模块包含名为“java
”的软件包或名称以“java.
”开头的软件包,则无法创建该图层 -
SecurityException
- 如果RuntimePermission("createClassLoader")
或RuntimePermission("getClassLoader")
被安全管理员拒绝 - 另请参见:
-
findLoader(java.lang.String)
-
defineModules
public static ModuleLayer.Controller defineModules(Configuration cf, List<ModuleLayer> parentLayers, Function<String,ClassLoader> clf)
通过将给定的Configuration
的模块定义到Java虚拟机来创建新的模块层。 给定的功能将配置中的每个模块按名称映射到类加载器。 创建图层通知Java虚拟机有关可能加载的类,以便Java虚拟机知道每个类是其成员的哪个模块。类加载器实现的类装载器委派必须遵守模块的可读性。 类加载器应为
parallel-capable
,以避免在加载类时出现死锁。 此外,使用此方法创建新层的实体应该安排在加载类或资源的任何尝试之前,类加载器都可以从这些模块加载。创建图层可能会失败,原因如下:
具有相同包的两个或多个模块映射到相同的类加载器。
一个模块被映射到已经具有与其定义的相同名称的模块的类加载器。
模块被映射到在模块中的任何包中已经定义了类型的类加载器。
此外,一个层不能如果配置包含一个名为模块创建“
java.base
”时,配置包含与命名封装的模块“java
”或包名称开头“java.
”,或功能的模块名称映射到一个类加载器返回null
或platform class loader 。如果将模块名称映射到类加载器的功能会引发错误或运行时异常,则将其传播给此方法的调用者。
- API Note:
- 关于使用此方法创建图层是否为原子操作的具体实现方式。 因此,这种方法有可能失败,并为Java虚拟机定义了一些模块,但不是全部。
- 参数
-
cf
- 图层的配置 -
parentLayers
- 搜索顺序中的父层列表 -
clf
- 将模块名称映射到类加载器的功能 - 结果
- 控制新创建的图层的控制器
- 异常
-
IllegalArgumentException
- 如果父配置与父层的配置不匹配,包括顺序 -
LayerInstantiationException
- 如果由于上述任何原因创建图层失败 -
SecurityException
- 如果安全管理员拒绝了RuntimePermission("getClassLoader")
-
configuration
public Configuration configuration()
返回此图层的配置。- 结果
- 该层的配置
-
parents
public List<ModuleLayer> parents()
返回此图层的父母的列表,除非是 empty layer ,它没有父母,因此返回空列表。- 结果
- 这一层的父母的名单
-
findModule
public Optional<Module> findModule(String name)
在此层中返回具有给定名称的模块,或者如果不在此层中,则返回parent层。 在父层中查找模块等同于以搜索顺序为每个父项调用findModule
,直到找到该模块或者已经搜索了所有父母。 在一层树中,这相当于深度优先搜索。- 参数
-
name
- 要查找的模块的名称 - 结果
-
具有给定名称的模块或空的
Optional
如果在该层或任何父层中没有此名称的模块
-
findLoader
public ClassLoader findLoader(String name)
返回具有给定名称的模块的ClassLoader
。 如果给定的名字的一个模块是不是在该层则parent
层中搜索在由指定的方式findModule
。如果有一个安全管理员,那么它的
checkPermission
方法被调用一个RuntimePermission("getClassLoader")
权限来检查调用者是否被允许访问类加载器。- API Note:
-
此方法不返回
Optional<ClassLoader>
因为`null`必须用于表示引导类加载器。 - 参数
-
name
- 要查找的模块的名称 - 结果
- 该模块被定义为的ClassLoader
- 异常
-
IllegalArgumentException
- 如果该层或该层的任何父层没有定义给定名称的模块 -
SecurityException
- 如果安全管理员否认
-
empty
public static ModuleLayer empty()
返回空层。 空层中没有模块。 没有父母- 结果
- 空层
-
boot
public static ModuleLayer boot()
- API Note:
-
此方法在启动期间和引导层完全初始化之前返回
null
。 - 结果
- The boot layer
-
-