Returns a module finder that locates modules on the file system by searching a sequence of directories and/or packaged modules. Each element in the given array is one of:
-
A path to a directory of modules.
-
A path to the top-level directory of an exploded module .
-
A path to a packaged module .
The module finder locates modules by searching each directory, exploded module, or packaged module in array index order. It finds the first occurrence of a module with a given name and ignores other modules of that name that appear later in the sequence.
If an element is a path to a directory of modules then each entry in the directory is a packaged module or the top-level directory of an exploded module. The module finder's find
or findAll
methods throw FindException
if a directory containing more than one module with the same name is encountered.
If an element in the array is a path to a directory, and that directory contains a file named module-info.class
, then the directory is treated as an exploded module rather than a directory of modules.
The module finder returned by this method supports modules that are packaged as JAR files. A JAR file with a module-info.class
in the top-level directory of the JAR file (or overridden by a versioned entry in a multi-release
JAR file) is a modular JAR and is an explicit module . A JAR file that does not have a module-info.class
in the top-level directory is an automatic
module. The ModuleDescriptor
for an automatic module is created as follows:
-
The module name
, and version
if applicable, is 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 proceeding the hyphen of the first occurrence. The subsequence after the hyphen is parsed as a ModuleDescriptor.Version
and ignored if it cannot be parsed as a Version
.
-
For the module name, then all non-alphanumeric characters ([^A-Za-z0-9])
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-1.2.3-SNAPSHOT.jar
will derive a module name foo
and 1.2.3-SNAPSHOT
as the version.
-
It requires
java.base
.
-
All entries in the JAR file with names ending with .class
are assumed to be class files where the name corresponds to the fully qualified name of the class. The packages of all classes are exported
.
-
The contents of all entries starting with META-INF/services/
are assumed to be service configuration files (see ServiceLoader
). The name of the file (that follows META-INF/services/
) is assumed to be the fully-qualified binary name of a service type. The entries in the file are assumed to be the fully-qualified binary names of provider classes.
-
If the JAR file has a Main-Class
attribute in its main manifest then its value is the main class
.
In addition to JAR files, an implementation may also support modules that are packaged in other implementation specific module formats. When a file is encountered that is not recognized as a packaged module then FindException
is thrown. An implementation may choose to ignore some files, hidden
files for example. Paths to files that do not exist are always ignored.
As with automatic modules, the contents of a packaged or exploded module may need to be scanned in order to determine the packages in the module. If a .class
file that corresponds to a class in an unnamed package is encountered then FindException
is thrown.
Finders created by this method are lazy and do not eagerly check that the given file paths are directories or packaged modules. Consequently, the find
or findAll
methods will only fail if invoking these methods results in searching a directory or packaged module and an error is encountered. Paths to files that do not exist are ignored.