Module java.base
Package java.lang.module

Class Configuration

java.lang.Object
java.lang.module.Configuration

public final class Configuration extends Object
一个配置,是解析或带有服务绑定的结果。

配置封装了解析输出的可读性图。可读性图是一个有向图,其顶点是ResolvedModule类型的模块,边表示模块之间的可读性关系。 Configuration定义了modules()方法,用于获取图中已解析模块的集合。 ResolvedModule定义了reads()方法,用于获取已解析模块读取的模块集合。被读取的模块可能在同一配置中,也可能在配置中。

配置定义了resolve方法,用于解析一组根模块,并且定义了resolveAndBind方法,用于进行带有服务绑定的解析。这两种方法都有实例方法和静态方法。实例方法创建一个以接收器为父配置的配置。静态方法用于更复杂的情况,其中可能有多个父配置。

Java虚拟机中的每个模块层都是从一个配置创建的。获取boot层的配置是通过调用 ModuleLayer.boot().configuration()来实现的。创建新配置时,通常会使用boot层的配置作为父配置。

示例

以下示例使用resolve方法来解析名为myapp的模块,以boot层的配置作为父配置。它会打印每个已解析模块的名称以及每个模块读取的模块的名称。

   Path dir1 = ..., dir2 = ..., dir3 = ...;
   ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
   Configuration parent = ModuleLayer.boot().configuration();
   Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("myapp"));
   cf.modules().forEach(m -> {
       System.out.format("%s -> %s%n",
           m.name(),
           m.reads().stream()
               .map(ResolvedModule::name)
               .collect(Collectors.joining(", ")));
   });
自:
9
参见:
  • Method Details

    • resolve

      public Configuration resolve(ModuleFinder before, ModuleFinder after, Collection<String> roots)
      解析一组根模块,以此配置为父配置,创建一个新配置。当以此配置为父配置调用静态resolve方法时,此方法的工作方式与指定的静态方法完全相同。换句话说,如果此配置是cf,则此方法等效于调用:
       
           Configuration.resolve(before, List.of(cf), after, roots);
       
      参数:
      before - 用于查找模块的before模块查找器
      after - 当before模块查找器或父配置未找到模块时,用于定位模块的after模块查找器
      roots - 要解析的模块名称的可能为空的集合
      返回:
      解析给定根模块后的配置
      抛出:
      FindException - 如果解析失败,原因是静态resolve方法指定的与可观察性相关的原因之一
      ResolutionException - 如果解析失败,原因是静态resolve方法指定的一致性检查之一
      SecurityException - 如果安全管理器拒绝定位模块
    • resolveAndBind

      public Configuration resolveAndBind(ModuleFinder before, ModuleFinder after, Collection<String> roots)
      解析一组根模块,带有服务绑定,并以此配置为父配置,创建一个新配置。当以此配置为父配置调用静态resolveAndBind方法时,此方法的工作方式与指定的静态方法完全相同。换句话说,如果此配置是cf,则此方法等效于调用:
       
           Configuration.resolveAndBind(before, List.of(cf), after, roots);
       
      参数:
      before - 用于查找模块的before模块查找器
      after - 当before模块查找器或父配置未找到模块时,用于定位模块的after模块查找器
      roots - 要解析的模块名称的可能为空的集合
      返回:
      解析给定根模块后的配置,带有服务绑定
      抛出:
      FindException - 如果解析失败,原因是静态resolve方法指定的与可观察性相关的原因之一
      ResolutionException - 如果解析失败,原因是静态resolve方法指定的一致性检查之一
      SecurityException - 如果安全管理器拒绝定位模块
    • resolve

      public static Configuration resolve(ModuleFinder before, List<Configuration> parents, ModuleFinder after, Collection<String> roots)
      解析一组根模块,创建一个配置。

      使用给定的before模块查找器定位每个根模块。如果未找到模块,则按照迭代顺序在父配置中定位模块,就好像在每个父模块上调用findModule方法一样。如果仍未找到,则使用给定的after模块查找器定位模块。相同的搜索顺序用于定位传递依赖关系。在父配置中定位的根模块或依赖关系不会进一步解析,并且不包含在生成的配置中。

      当所有模块都已枚举时,将计算可读性图,并结合模块导出和服务使用检查一致性。

      解析可能因以下FindException可观察性相关原因而失败:

      • 未找到根模块或直接或传递依赖项。

      • 尝试查找模块时发生错误。可能的错误包括I/O错误、检测到解析模块描述符(module-info.class)的错误或在同一目录中找到两个相同模块的版本。

      解析可能因以下ResolutionException的一致性检查失败而失败:

      • 检测到循环,例如模块m1需要模块m2,而模块m2需要m1

      • 一个模块读取两个或更多具有相同名称的模块。这包括一个模块读取另一个具有与自身相同名称的模块的情况。

      • 配置中的两个或更多模块将相同的包导出给读取两者的模块。这包括一个包含包p的模块M读取另一个将p导出给M的模块的情况。

      • 一个模块M声明它"uses p.S"或"provides p.S with ...",但包p既不在模块M中,也不被任何模块读取M导出。

      实现注意事项:
      在实现中,模块的可观察性可能取决于引用完整性或其他检查,以确保紧密耦合模块的不同构建或特定操作系统或架构的模块不会在同一配置中组合。
      参数:
      before - 用于查找模块的before模块查找器
      parents - 搜索顺序中的父配置列表
      after - 用于在before模块查找器或父配置中未找到模块时定位模块的after模块查找器
      roots - 要解析的模块名称的可能为空的集合
      返回:
      解析给定根模块的结果配置
      抛出:
      FindException - 如果由上述与可观察性相关的原因之一导致解析失败
      ResolutionException - 如果由上述一致性检查之一导致解析失败
      IllegalArgumentException - 如果父级列表为空,或列表具有两个或更多具有不同目标操作系统、架构或版本的模块的父级
      SecurityException - 如果安全管理器拒绝定位模块
    • resolveAndBind

      public static Configuration resolveAndBind(ModuleFinder before, List<Configuration> parents, ModuleFinder after, Collection<String> roots)
      解析一组根模块,带有服务绑定,以创建配置。

      此方法的工作方式与resolve指定的完全相同,只是解析的模块图通过由服务使用依赖关系引起的模块进行了扩展。

      更具体地说,根模块被解析,就好像调用resolve一样。然后检查已解析的模块以及所有父配置中的所有模块,具有服务依赖。所有由给定模块查找器找到的提供一个或多个服务类型实现的模块都将添加到模块图中,然后通过调用resolve方法解析。将模块添加到模块图可能会引入新的服务使用依赖关系,因此该过程会迭代进行,直到不再添加模块为止。

      由于服务绑定涉及解析,因此它可能因与resolve指定的完全相同的原因而失败,导致FindExceptionResolutionException

      参数:
      before - 用于查找模块的before模块查找器
      parents - 搜索顺序中的父配置列表
      after - 用于在before模块查找器或父配置中未找到模块时定位模块的after模块查找器
      roots - 要解析的模块名称的可能为空的集合
      返回:
      解析给定根模块,带有服务绑定的结果配置
      抛出:
      FindException - 如果由静态resolve方法指定的与可观察性相关的原因之一导致解析失败
      ResolutionException - 如果由静态resolve方法指定的一致性检查之一导致解析失败
      IllegalArgumentException - 如果父级列表为空,或列表具有两个或更多具有不同目标操作系统、架构或版本的模块的父级
      SecurityException - 如果安全管理器拒绝定位模块
    • empty

      public static Configuration empty()
      返回配置。空配置中没有模块。它没有父级。
      返回:
      空配置
    • parents

      public List<Configuration> parents()
      返回此配置的父级的不可修改列表,按搜索顺序排列。如果这是空配置,则返回一个空列表。
      返回:
      可能为空的此父级配置的不可修改列表
    • modules

      public Set<ResolvedModule> modules()
      返回此配置中已解析模块的不可修改集合。
      返回:
      可能为空的此配置中已解析模块的不可修改集合
    • findModule

      public Optional<ResolvedModule> findModule(String name)
      在此配置中查找已解析的模块,或者如果不在此配置中,则在父级配置中查找。在配置树中,这相当于深度优先搜索。
      参数:
      name - 要查找的已解析模块的模块名称
      返回:
      具有给定名称的已解析模块,如果在此配置或任何父配置中没有具有此名称的模块,则返回空的 Optional
    • toString

      public String toString()
      返回描述此配置的字符串。
      覆盖:
      toString 在类 Object
      返回:
      描述此配置的可能为空的字符串