模块  java.base
软件包  java.lang

Class ModuleLayer


  • public final class ModuleLayer
    extends Object
    Java虚拟机中的一层模块。

    Configuration的模块图创建图层,并将每个模块映射到ClassLoader 创建图层会通知Java虚拟机有关可从模块加载的类,以便Java虚拟机知道每个类所属的模块。

    创建图层会为配置中的每个ResolvedModule创建一个模块对象。 对于每个解决模块是read ,所述模块 reads相应的运行时模块 ,其可以是在同一层或parent层。

    defineModulesWithOneLoaderdefineModulesWithManyLoaders方法提供了创建模块层的便捷方法,其中所有模块都映射到单个类加载器或每个模块映射到其自己的类加载器。 defineModules方法适用于更高级的情况,其中模块通过为方法指定的函数映射到自定义类加载器。 这些方法中的每一个都具有实例和静态变体。 实例方法创建一个以接收者作为父层的图层。 静态方法适用于更高级的情况,其中可以有多个父层,或者需要Controller来控制层中的模块

    Java虚拟机至少有一个非空层,即boot层,它是在启动Java虚拟机时创建的。 引导层包含模块java.base并且是Java虚拟机中唯一具有名为“ java.base ”的模块的层。 引导层中的模块映射到Java虚拟机中的引导类加载器和其他类加载器built-in 创建其他图层时,引导层通常为parent

    创建一个层中的每个模块 ,使其输出opens由其ModuleDescriptor描述的包。 在创建图层时,将按照以下条件确定合格的导出(将包导出到一组目标模块而不是所有模块):

    • 如果模块X将包导出到Y ,并且如果运行时模块 X读取模块 Y ,则将包导出到模块 Y (其可以与X在同一层中或父层)。
    • 如果模块X将包导出到Y ,并且如果运行时模块 X未读取Y则定位目标Y就好像通过调用findModule来查找层或其父层中的模块一样。 如果找到Y ,则将包导出到找到的Y实例。 如果未找到Y则忽略限定导出。

    合格的开仓的处理方式与合格的出口相同。

    与创建ConfigurationConfigurationautomatic模块在创建图层时会受到特殊处理。 在Java虚拟机中创建一个自动模块,作为模块 ,读取Java虚拟机中的每个未命名的模块

    除非另行指定,否则将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()
    • 方法详细信息

      • defineModulesWithOneLoader

        public ModuleLayer defineModulesWithOneLoader​(Configuration cf,
                                                      ClassLoader parentLoader)
        通过将给定Configuration的模块定义到Java虚拟机,创建一个新模块层,将该层作为其父层。 此方法创建一个类加载器并定义该类加载器的所有模块。 每个类加载器的parent是给定的父类加载器。 当使用此层作为父级调用时,此方法与静态defineModulesWithOneLoader方法指定的方法完全相同。 换句话说,如果此图层是thisLayer则此方法等效于调用:
           ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();  
        参数
        cf - 图层的配置
        parentLoader - 此方法创建的类加载器的父类加载器; 对于bootstrap类加载器,可能是null
        结果
        新创建的图层
        异常
        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 - 此方法创建的每个类加载器的父类加载器; 对于bootstrap类加载器,可能是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 - 如果给定配置具有多个父级,或者配置的父级不是此层的配置
        LayerInstantiationException - 如果由于静态 defineModules方法指定的任何原因而无法创建 defineModules
        SecurityException - 如果安全管理器拒绝 RuntimePermission("getClassLoader")
      • defineModulesWithOneLoader

        public static ModuleLayer.Controller defineModulesWithOneLoader​(Configuration cf,
                                                                        List<ModuleLayer> parentLayers,
                                                                        ClassLoader parentLoader)
        通过将给定Configuration的模块定义到Java虚拟机来创建新模块层。 此方法创建一个类加载器并定义该类加载器的所有模块。

        从模块加载类时,此方法创建的类加载器实现直接委派 如果调用loadClass方法来加载类,则它使用类的包名将其映射到模块。 这可能是该层中的模块,因此定义为相同的类加载器。 它可以是父层中模块中的包,该模块将导出到此层中的一个或多个模块。 类加载器委托给模块的类加载器,如果该类加载器ClassNotFoundException则抛出ClassNotFoundException 当调用loadClass来加载未映射到模块的类时,它会委托给父类加载器。

        通过这种方法创建的类加载器定位资源( getResourcegetResources搜索父类加载器之前在层中的所有模块和其它资源的方法)。

        尝试创建一个层,其中所有模块都定义到同一个类加载器可能会失败,原因如下:

        • 重叠包 :配置中的两个或多个模块具有相同的包。

        • 拆分委托 :生成的类加载器需要委托给多个类加载器,以便在特定包中加载类。

        此外,如果配置包含名为“ 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则抛出ClassNotFoundException 当调用loadClass来加载未映射到模块的类时,它将委托给父类加载器。

        通过这种方法创建的类加载器定位资源( getResourcegetResources搜索父类加载器之前定义的类加载器模块中,和其他资源的方法)。

        如果有安全管理器,则此方法创建的类加载器将加载具有此方法的调用上下文限制的特权的类和资源。

        参数
        cf - 图层的配置
        parentLayers - 搜索顺序中的父图层列表
        parentLoader - 此方法创建的每个类加载器的父类加载器; 对于引导类加载器,可能是null
        结果
        控制新创建的图层的控制器
        异常
        IllegalArgumentException - 如果给定配置的父级与父级层的配置不匹配,包括顺序
        LayerInstantiationException - 如果由于配置包含名为“ java.base ”的模块或模块包含名为“ java ”的程序包或名称以“ 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. ”,或功能的模块名称映射到类加载器返回nullplatform class loader

        如果将模块名称映射到类加载器的函数抛出错误或运行时异常,则将其传播到此方法的调用方。

        API Note:
        具体实现是否使用此方法创建图层是否为原子操作。 因此,对于Java虚拟机定义的某些模块(但不是全部),此方法可能会失败。
        参数
        cf - 图层的配置
        parentLayers - 搜索顺序中的父图层列表
        clf - 将模块名称映射到类加载器的函数
        结果
        控制新创建的图层的控制器
        异常
        IllegalArgumentException - 如果给定配置的父级与父级层的配置不匹配,包括顺序
        LayerInstantiationException - 如果由于上面列出的任何原因而创建图层失败
        SecurityException - 如果安全管理器拒绝 RuntimePermission("getClassLoader")
      • configuration

        public Configuration configuration()
        返回此图层的配置。
        结果
        此图层的配置
      • parents

        public List<ModuleLayer> parents()
        返回此图层父项的列表,除非这是 empty layer ,它没有父项,因此返回一个空列表。
        结果
        此图层的父级列表
      • modules

        public Set<模块> modules()
        返回此图层中的模块集。
        结果
        此层中可能为空的不可修改的模块集
      • findModule

        public Optional<模块> findModule​(String name)
        返回此图层中具有给定名称的模块,如果不在此图层中,则返回parent图层。 在父层中查找模块相当于按搜索顺序在每个父findModule上调用findModule ,直到找到模块或搜索了所有父项。 层树中,这相当于深度优先搜索。
        参数
        name - 要查找的模块的名称
        结果
        具有给定名称的模块或如果在此层或任何父层中没有具有此名称的模块,则为空 Optional
      • findLoader

        public ClassLoader findLoader​(String name)
        返回具有给定名称的模块的ClassLoader 如果给定的名字的一个模块是不是在该层则parent层中搜索在由指定的方式findModule

        如果有安全管理器,则调用其checkPermission方法,并且具有RuntimePermission("getClassLoader")权限,以检查是否允许调用者访问类加载器。

        API Note:
        此方法不返回 Optional<ClassLoader>因为必须使用“null”来表示引导类加载器。
        参数
        name - 要查找的模块的名称
        结果
        定义模块的ClassLoader
        异常
        IllegalArgumentException - 如果未在此图层或此图层的任何父图层中定义给定名称的模块
        SecurityException - 如果安全经理拒绝
      • toString

        public String toString()
        返回描述此模块层的字符串。
        重写:
        toString在类 Object
        结果
        描述此模块层的可能为空的字符串
      • empty

        public static ModuleLayer empty()
        返回图层。 空层中没有模块。 它没有父母。
        结果
        空层
      • boot

        public static ModuleLayer boot()
        返回引导层。 引导层包含至少一个模块java.base 它的父级是empty层。
        API Note:
        此方法在启动期间和引导层完全初始化之前返回 null
        结果
        The boot layer