模块 java.base

接口 ModuleFinder


public interface ModuleFinder
模块的查找器。 ModuleFinder 用于在 resolution服务绑定 期间查找模块。

ModuleFinder 只能找到一个具有给定名称的模块。例如,在一系列目录中查找模块的 ModuleFinder 将定位给定名称的模块的第一次出现,并将忽略出现在该序列后面的目录中的具有该名称的其他模块。

用法示例:

  Path dir1 = ..., dir2 = ..., dir3 = ...;
  ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
  Optional<ModuleReference> omref = finder.find("jdk.foo");
  omref.ifPresent(mref -> ... );
 

此处定义的 find findAll 方法可能因多种原因而失败。这些包括 I/O 错误、在解析模块描述符 (module-info.class) 时检测到的错误,或者在 ModuleFinder.of 返回的 ModuleFinder 的情况下,在目录中找到两个或更多同名模块。当检测到错误时,这些方法会抛出 FindException 和适当的 cause 。抛出 FindExceptionModuleFinder 的行为未定义。例如,在抛出异常后调用 find 可能会也可能不会扫描导致异常的相同模块。建议在抛出异常后丢弃模块查找器。

ModuleFinder 不需要是线程安全的。

自从:
9
  • 方法总结

    修饰符和类型
    方法
    描述
    static ModuleFinder
    compose(ModuleFinder... finders)
    返回由零个或多个模块查找器序列组成的模块查找器。
    find(String name)
    查找对给定名称的模块的引用。
    返回此查找器可以定位的所有模块引用的集合。
    static ModuleFinder
    of(Path... entries)
    返回一个模块查找器,它通过搜索一系列目录和/或打包模块在文件系统上定位模块。
    static ModuleFinder
    返回定位 system modules 的模块查找器。
  • 方法详情

    • find

      Optional <ModuleReference > find(String  name)
      查找对给定名称的模块的引用。

      ModuleFinder 提供了它所定位的模块的一致视图。如果多次调用 find 来定位同一个模块(按名称),那么它每次都会返回相同的结果。如果找到一个模块,那么它保证是 findAll 方法返回的模块集的成员。

      参数:
      name - 要查找的模块的名称
      返回:
      对具有给定名称的模块的引用,如果未找到则为空 Optional
      抛出:
      FindException - 如果查找模块时出错
      SecurityException - 如果安全经理拒绝
    • findAll

      Set <ModuleReference > findAll()
      返回此查找器可以定位的所有模块引用的集合。

      ModuleFinder 提供了它所定位的模块的一致视图。如果多次调用 findAll ,则每次都会返回相同(等于)的结果。对于返回集合中的每个 ModuleReference 元素,如果调用以查找该模块,则保证 find 将定位 ModuleReference

      API 注意:
      这对于需要扫描模块路径以查找提供特定服务的模块的 resolveAndBind 等方法来说很重要。
      返回:
      此查找器定位的所有模块引用的集合
      抛出:
      FindException - 如果查找所有模块时出错
      SecurityException - 如果安全经理拒绝
    • ofSystem

      static ModuleFinder  ofSystem()
      返回定位 system modules 的模块查找器。系统模块是 Java 运行时映像中的模块。模块查找器将始终找到 java.base

      如果设置了安全管理器,则调用其 checkPermission 方法来检查调用者是否已被授予 RuntimePermission("accessSystemModules") 访问系统模块的权限。

      返回:
      定位系统模块的ModuleFinder
      抛出:
      SecurityException - 如果安全经理拒绝
    • of

      static ModuleFinder  of(Path ... entries)
      返回一个模块查找器,它通过搜索一系列目录和/或打包模块在文件系统上定位模块。给定数组中的每个元素都是以下之一:
      1. 模块目录的路径。

      2. exploded moduletop-level 目录的路径。

      3. packaged module 的路径。

      模块查找器通过按数组索引顺序搜索每个目录、展开的模块或打包的模块来定位模块。它查找第一次出现的具有给定名称的模块,并忽略序列中稍后出现的具有该名称的其他模块。

      如果元素是模块目录的路径,则目录中的每个条目都是打包模块或分解模块的顶级目录。如果目录包含多个具有相同名称的模块,则会出错。如果元素是目录的路径,并且该目录包含名为 module-info.class 的文件,则该目录将被视为展开的模块而不是模块目录。

      此方法返回的模块查找器支持打包为 JAR 文件的模块。在其顶级目录中或在 多版本 JAR 文件中的版本化条目中具有 module-info.class 的 JAR 文件是模块化 JAR 文件,因此定义了一个 explicit 模块。在其顶级目录中没有 module-info.class 的 JAR 文件定义了一个 automatic module ,如下所示:

      • 如果 JAR 文件在其主清单中具有属性“Automatic-Module-Name”,则其值为 模块名称。模块名称是从 JAR 文件的名称派生的。

      • version 和属性“Automatic-Module-Name”不存在时的模块名称源自 JAR 文件的文件名,如下所示:

        • .jar”后缀已删除。

        • 如果名称与正则表达式 "-(\\d+(\\.|$))" 匹配,则模块名称将从第一次出现的连字符之前的子序列派生。连字符后的子序列被解析为 Version 并且如果不能被解析为 Version 则被忽略。

        • 模块名称中的所有非字母数字字符 ([^A-Za-z0-9]) 都替换为一个点 ("."),所有重复的点都替换为一个点,并删除所有前导和尾随的点。

        • 例如,一个名为“foo-bar.jar”的 JAR 文件将派生一个模块名称“foo.bar”并且没有版本。名为“foo-bar-1.2.3-SNAPSHOT.jar”的 JAR 文件将导出模块名称“foo.bar”和“1.2.3-SNAPSHOT”作为版本。

      • 模块中的包集派生自 JAR 文件中名称以“.class”结尾的非目录条目。候选包名称是从名称派生而来的,使用的字符最多但不包括最后一个正斜杠。所有剩余的正斜杠都替换为点 (".")。如果生成的字符串是合法的包名,则假定它是包名。例如,如果 JAR 文件包含条目“p/q/Foo.class”,则派生的包名称为“p.q”。

      • META-INF/services/ 开头的条目的内容被假定为服务配置文件(请参阅 ServiceLoader )。如果文件名(跟在 META-INF/services/ 之后)是合法的类名,则假定它是服务类型的完全限定类名。假定文件中的条目是提供程序类的完全限定类名。

      • 如果 JAR 文件在其主清单中有一个 Main-Class 属性,它的值是一个合法的类名,并且它的包在为模块派生的包集中,那么该值就是模块 主类

      如果无法为自动模块创建 ModuleDescriptor(通过 ModuleDescriptor.Builder API),则抛出 FindException。当“Automatic-Module-Name”属性的值不是合法的模块名称时,可能会出现这种情况,无法从 JAR 文件的文件名派生出合法的模块名称,其中 JAR 文件的顶级目录中包含一个 .class JAR 文件,其中服务配置文件中的条目不是合法的类名或其包名不在为模块派生的包集中。

      除了 JAR 文件之外,实现还可以支持以其他实现特定模块格式打包的模块。如果为此方法指定的数组中的元素是模块目录的路径,则目录中未被识别为模块的条目将被忽略。如果数组中的元素是无法识别的打包模块的路径,则在遇到该文件时抛出 FindException。始终忽略不存在的文件路径。

      与自动模块一样,打包或分解模块的内容可能需要 scanned 才能确定模块中的包。 隐藏文件 是否被忽略是特定于实现的,因此未指定。如果在顶级目录中找到 .class 文件( module-info.class 除外),则假定它是未命名包中的类,因此抛出 FindException

      通过这种方法创建的查找器是惰性的,不会急切地检查给定的文件路径是目录还是打包模块。因此,findfindAll 方法只有在调用这些方法导致搜索目录或打包模块并遇到错误时才会失败。

      参数:
      entries - 一个可能为空的模块目录路径数组或打包或分解模块的路径
      返回:
      在文件系统上定位模块的 ModuleFinder
    • compose

      static ModuleFinder  compose(ModuleFinder ... finders)
      返回由零个或多个模块查找器序列组成的模块查找器。生成的模块查找器的 find 方法将通过调用每个模块查找器的 find 方法来定位模块,按照数组索引顺序,直到找到模块或搜索到所有模块查找器。结果模块查找器的 findAll 方法将返回一组模块,其中包括第一个模块查找器找到的所有模块。模块集将包括序列中先前模块查找器未找到的第二个或后续模块查找器找到的所有模块。

      当定位模块时,底层模块查找器的 findfindAll 方法抛出的任何异常或错误都将传播到结果模块查找器的 findfindAll 方法的调用者。

      参数:
      finders - 模块查找器数组
      返回:
      一个 ModuleFinder 组成了一系列模块查找器