Interface ModuleFinder


public interfaceModuleFinder
A finder of modules. AModuleFinder is used to find modules duringresolution orservice binding.

AModuleFinder can only find one module with a given name. AModuleFinder that finds modules in a sequence of directories, forexample, will locate the first occurrence of a module of a given name andwill ignore other modules of that name that appear in directories later inthe sequence.

Example usage:

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

Thefind andfindAll methodsdefined here can fail for several reasons. These include I/O errors, errorsdetected parsing a module descriptor (module-info.class), or in thecase ofModuleFinder returned byModuleFinder.of, thattwo or more modules with the same name are found in a directory.When an error is detected then these methods throwFindException with an appropriatecause.The behavior of aModuleFinder after aFindException isthrown is undefined. For example, invokingfind after an exceptionis thrown may or may not scan the same modules that lead to the exception.It is recommended that a module finder be discarded after an exception isthrown.

AModuleFinder is not required to be thread safe.

Since:
9
  • Method Summary

    Modifier and Type
    Method
    Description
    compose(ModuleFinder... finders)
    Returns a module finder that is composed from a sequence of zero or moremodule finders.
    find(String name)
    Finds a reference to a module of a given name.
    Returns the set of all module references that this finder can locate.
    of(Path... entries)
    Returns a module finder that locates modules on the file system bysearching a sequence of directories and/or packaged modules.
    Returns a module finder that locates thesystem modules.
  • Method Details

    • find

      Finds a reference to a module of a given name.

      AModuleFinder provides a consistent view of themodules that it locates. Iffind is invoked several times tolocate the same module (by name) then it will return the same resulteach time. If a module is located then it is guaranteed to be a memberof the set of modules returned by thefindAllmethod.

      Parameters:
      name - The name of the module to find
      Returns:
      A reference to a module with the given name or an emptyOptional if not found
      Throws:
      FindException - If an error occurs finding the module
    • findAll

      Set<ModuleReference> findAll()
      Returns the set of all module references that this finder can locate.

      AModuleFinder provides a consistent view of the modulesthat it locates. IffindAll is invoked several timesthen it will return the same (equals) result each time. For eachModuleReference element in the returned set then it is guaranteed thatfind will locate theModuleReference if invokedto find that module.

      API Note:
      This is important to have for methods such asresolveAndBind that need to scan themodule path to find modules that provide a specific service.
      Returns:
      The set of all module references that this finder locates
      Throws:
      FindException - If an error occurs finding all modules
    • ofSystem

      static ModuleFinder ofSystem()
      Returns a module finder that locates thesystem modules. Thesystem modules are the modules in the Java run-time image.The module finder will always findjava.base.
      Returns:
      AModuleFinder that locates the system modules
    • of

      static ModuleFinder of(Path... entries)
      Returns a module finder that locates modules on the file system bysearching a sequence of directories and/or packaged modules.Each element in the given array is one of:
      1. A path to a directory of modules.

      2. A path to thetop-level directory of anexploded module.

      3. A path to apackaged module.

      The module finder locates modules by searching each directory, explodedmodule, or packaged module in array index order. It finds the firstoccurrence of a module with a given name and ignores other modules ofthat name that appear later in the sequence.

      If an element is a path to a directory of modules then each entry inthe directory is a packaged module or the top-level directory of anexploded module. It is an error if a directory contains more than onemodule with the same name. If an element is a path to a directory, andthat directory contains a file namedmodule-info.class, then thedirectory is treated as an exploded module rather than a directory ofmodules.

      The module finder returned by this methodsupports modules packaged as JAR files. A JAR file with amodule-info.class in its top-level directory, or in a versioned entryin amulti-releaseJAR file, is a modular JAR file and thus defines anexplicitmodule. A JAR file that does not have amodule-info.class in itstop-level directory defines anautomatic module, as follows:

      • If the JAR file has the attribute "Automatic-Module-Name" in its main manifest then its value is themodule name. The module name is otherwise derived from the name of the JAR file.

      • Theversion, and the module name when the attribute "Automatic-Module-Name" is not present, are derived from the file name of the JAR file as follows:

        • The ".jar" suffix is removed.

        • If the name matches the regular expression "-(\\d+(\\.|$))" then the module name will be derived from the subsequence preceding the hyphen of the first occurrence. The subsequence after the hyphen is parsed as aVersion and ignored if it cannot be parsed as aVersion.

        • All non-alphanumeric characters ([^A-Za-z0-9]) in the module name are replaced with a dot ("."), all repeating dots are replaced with one dot, and all leading and trailing dots are removed.

        • As an example, a JAR file named "foo-bar.jar" will derive a module name "foo.bar" and no version. A JAR file named "foo-bar-1.2.3-SNAPSHOT.jar" will derive a module name "foo.bar" and "1.2.3-SNAPSHOT" as the version.

      • The set of packages in the module is derived from the non-directory entries in the JAR file that have names ending in ".class". A candidate package name is derived from the name using the characters up to, but not including, the last forward slash. All remaining forward slashes are replaced with dot ("."). If the resulting string is a legal package name then it is assumed to be a package name. For example, if the JAR file contains the entry "p/q/Foo.class" then the package name derived is "p.q".

      • The contents of entries starting with META-INF/services/ are assumed to be service configuration files (seeServiceLoader). If the name of a file (that followsMETA-INF/services/) is a legal class name then it is assumed to be the fully-qualified class name of a service type. The entries in the file are assumed to be the fully-qualified class names of provider classes.

      • If the JAR file has aMain-Class attribute in its main manifest, its value is a legal class name, and its package is in the set of packages derived for the module, then the value is the modulemain class.

      If aModuleDescriptor cannot be created (by means of theModuleDescriptor.Builder API) for anautomatic module thenFindException is thrown. This can arisewhen the value of the "Automatic-Module-Name" attribute is not alegal module name, a legal module name cannot be derived from the filename of the JAR file, where the JAR file contains a.class inthe top-level directory of the JAR file, where an entry in a serviceconfiguration file is not a legal class name or its package name is notin the set of packages derived for the module.

      In addition to JAR files, an implementation may also support modulesthat are packaged in other implementation specific module formats. Ifan element in the array specified to this method is a path to a directoryof modules then entries in the directory that not recognized as modulesare ignored. If an element in the array is a path to a packaged modulethat is not recognized then aFindException is thrown when thefile is encountered. Paths to files that do not exist are always ignored.

      As with automatic modules, the contents of a packaged or explodedmodule may need to bescanned in order to determine the packagesin the module. Whetherhidden files are ignored or not is implementation specific and thereforenot specified. If a.class file (other thanmodule-info.class) is found in the top-level directory then it isassumed to be a class in the unnamed package and soFindExceptionis thrown.

      Finders created by this method are lazy and do not eagerly checkthat the given file paths are directories or packaged modules.Consequently, thefind orfindAll methods will onlyfail if invoking these methods results in searching a directory orpackaged module and an error is encountered.

      Parameters:
      entries - A possibly-empty array of paths to directories of modules or paths to packaged or exploded modules
      Returns:
      AModuleFinder that locates modules on the file system
    • compose

      static ModuleFinder compose(ModuleFinder... finders)
      Returns a module finder that is composed from a sequence of zero or moremodule finders. Thefind method of the resultingmodule finder will locate a module by invoking thefind methodof each module finder, in array index order, until either the module isfound or all module finders have been searched. ThefindAll method of the resulting module finder will return a set ofmodules that includes all modules located by the first module finder.The set of modules will include all modules located by the second orsubsequent module finder that are not located by previous module findersin the sequence.

      When locating modules then any exceptions or errors thrown by thefind orfindAll methods of the underlying module finderswill be propagated to the caller of the resulting module finder'sfind orfindAll methods.

      Parameters:
      finders - The array of module finders
      Returns:
      AModuleFinder that composes a sequence of module finders