配置封装了readability graph,即分辨率的输出。可读性图是一个有向图,其顶点类型为ResolvedModule ,边表示模块之间的可读性。 Configuration 定义了 modules() 方法来获取图中已解析的模块集。 ResolvedModule 定义了 reads() 方法来获取解析模块读取的模块集。读取的模块可能处于相同配置中,也可能处于 parent 配置中。
配置定义了 resolve 方法来解析根模块的集合,以及 resolveAndBind 方法来解析服务绑定。这两种方法都有实例和静态变体。实例方法创建一个以接收者为父配置的配置。静态方法适用于可以有多个父配置的更高级的情况。
Java 虚拟机中的每个layer 模块都是根据配置创建的。 boot 层的配置是通过调用 ModuleLayer.boot().configuration() 获得的。在创建新配置时,引导层的配置通常是父级。
示例
以下示例使用 resolve 方法解析名为 myapp 的模块,并将引导层的配置作为父配置。它打印每个已解析模块的名称以及每个模块读取的模块的名称。
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
- 参见:
-
方法总结
修饰符和类型方法描述static Configurationempty()返回 empty 配置。findModule(String name) 在此配置中查找已解析的模块,如果不在此配置中,则查找 parent 配置。modules()返回此配置中一组不可修改的已解析模块。parents()按搜索顺序返回此配置父项的不可修改列表。resolve(ModuleFinder before, ModuleFinder after, Collection<String> roots) 解析根模块的集合,以此配置作为其父级,以创建新配置。static Configurationresolve(ModuleFinder before, List<Configuration> parents, ModuleFinder after, Collection<String> roots) 解析一组根模块以创建配置。resolveAndBind(ModuleFinder before, ModuleFinder after, Collection<String> roots) 使用服务绑定解析根模块的集合,并将此配置作为其父级,以创建新配置。static ConfigurationresolveAndBind(ModuleFinder before, List<Configuration> parents, ModuleFinder after, Collection<String> roots) 使用服务绑定解析根模块的集合以创建配置。toString()返回描述此配置的字符串。
-
方法详情
-
resolve
解析根模块的集合,以此配置作为其父级,以创建新配置。当使用此配置作为父级调用时,此方法的工作方式与静态resolve方法的指定完全相同。换句话说,如果这个配置是cf那么这个方法相当于调用:Configuration.resolve(before, List.of(cf), after, roots);- 参数:
before- 用于查找模块的 before 模块查找器after- after 模块查找器用于在before模块查找器或父配置未定位时定位模块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- after 模块查找器用于在before模块查找器或父配置未定位时定位模块roots- 要解析的模块的模块名称的可能为空的集合- 返回:
- 配置是通过服务绑定解析给定根模块的结果
- 抛出:
FindException- 如果由于静态resolve方法指定的任何与可观察性相关的原因导致解析失败ResolutionException- 如果解析未通过静态resolve方法指定的任何一致性检查SecurityException- 如果定位模块被安全管理器拒绝
-
resolve
public static Configuration resolve(ModuleFinder before, List <Configuration > parents, ModuleFinder after, Collection <String > roots) 解析一组根模块以创建配置。每个根模块都使用给定的
before模块查找器定位。如果未找到模块,则它位于父配置中,就好像通过按迭代顺序在每个父级上调用findModule方法一样。如果未找到,则使用给定的after模块查找器定位模块。相同的搜索顺序用于定位传递依赖。位于父配置中的根模块或依赖项不再解析,也不包含在生成的配置中。枚举所有模块后,将计算可读性图,并结合模块导出和服务使用,检查一致性。
由于以下 observability-related 原因,解析可能会失败并显示
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读取的任何模块导出到M。
- 实现注意事项:
- 在实现中,模块的可观察性可能取决于引用完整性或其他检查,以确保不同构建的紧密耦合模块或特定操作系统或体系结构的模块不会组合在同一配置中。
- 参数:
before- 用于查找模块的 before 模块查找器parents- 按搜索顺序列出父配置after- after 模块查找器用于在before模块查找器或父配置未定位时定位模块roots- 要解析的模块的模块名称的可能为空的集合- 返回:
- 作为解析给定根模块的结果的配置
- 抛出:
FindException- 如果由于上述任何与可观察性相关的原因导致解析失败ResolutionException- 如果上述任何一致性检查的解析失败IllegalArgumentException- 如果父项列表为空,或者列表中有两个或多个父项具有针对不同目标操作系统、体系结构或版本的模块SecurityException- 如果定位模块被安全管理器拒绝
-
resolveAndBind
public static Configuration resolveAndBind(ModuleFinder before, List <Configuration > parents, ModuleFinder after, Collection <String > roots) 使用服务绑定解析根模块的集合以创建配置。此方法完全按照
resolve指定的方式工作,除了已解析模块的图形增加了由服务使用依赖关系引起的模块。更具体地说,根模块的解析就像调用
resolve一样。然后检查已解析的模块以及父配置中的所有模块,带有service dependences。给定模块查找器找到的所有模块provide一种或多种服务类型的实现被添加到模块图中,然后像调用resolve方法一样解析。将模块添加到模块图中可能会引入新的服务使用依赖关系,因此该过程会迭代进行,直到不再添加模块为止。由于服务绑定涉及解析,因此它可能因
FindException或ResolutionException而失败,原因与resolve中指定的原因完全相同。- 参数:
before- 用于查找模块的 before 模块查找器parents- 按搜索顺序列出父配置after- after 模块查找器用于在before模块查找器或父配置未定位时定位模块roots- 要解析的模块的模块名称的可能为空的集合- 返回:
- 配置是通过服务绑定解析给定根模块的结果
- 抛出:
FindException- 如果由于静态resolve方法指定的任何与可观察性相关的原因导致解析失败ResolutionException- 如果解析未通过静态resolve方法指定的任何一致性检查IllegalArgumentException- 如果父项列表为空,或者列表中有两个或多个父项具有针对不同目标操作系统、体系结构或版本的模块SecurityException- 如果定位模块被安全管理器拒绝
-
empty
返回 empty 配置。空配置中没有模块。它没有父母。- 返回:
- 空配置
-
parents
按搜索顺序返回此配置父项的不可修改列表。如果这是 空配置,则返回一个空列表。- 返回:
- 此父配置的可能为空的不可修改列表
-
modules
返回此配置中一组不可修改的已解析模块。- 返回:
- 此配置中已解析模块的可能为空的不可修改集
-
findModule
在此配置中查找已解析的模块,如果不在此配置中,则查找 parent 配置。在父配置中查找模块等同于按搜索顺序在每个父级上调用findModule,直到找到模块或搜索到所有父级。在 tree of configurations 中,这相当于深度优先搜索。- 参数:
name- 要查找的已解析模块的模块名称- 返回:
-
具有给定名称的已解析模块,如果此配置或任何父配置中没有具有此名称的模块,则为空
Optional
-
toString
返回描述此配置的字符串。
-