下面列出了怎么用java.lang.module.FindException的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Scan a JAR file or exploded module.
*/
private Optional<ModuleReference> scanModule(Path entry) {
ModuleFinder finder = ModuleFinder.of(entry);
try {
return finder.findAll().stream().findFirst();
} catch (FindException e) {
out.println(entry);
out.println(INDENT + e.getMessage());
Throwable cause = e.getCause();
if (cause != null) {
out.println(INDENT + cause);
}
errorCount++;
return Optional.empty();
}
}
/**
* Scan a JAR file or exploded module.
*/
private Optional<ModuleReference> scanModule(Path entry) {
ModuleFinder finder = ModuleFinder.of(entry);
try {
return finder.findAll().stream().findFirst();
} catch (FindException e) {
ostream.println(entry);
ostream.println(INDENT + e.getMessage());
Throwable cause = e.getCause();
if (cause != null) {
ostream.println(INDENT + cause);
}
errorFound = true;
return Optional.empty();
}
}
/**
* Service provider dependency not found
*/
@Test(expectedExceptions = { FindException.class })
public void testServiceProviderDependencyNotFound() {
// service provider dependency (on m3) not found
ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.requires("m3")
.provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
// should throw ResolutionException because m3 is not found
Configuration cf = resolveAndBind(finder, "m1");
}
/**
* Test JAR file with META-INF/services configuration file with bad
* values or names.
*/
@Test(dataProvider = "badproviders", expectedExceptions = FindException.class)
public void testBadProviderNames(String service, String provider)
throws IOException
{
Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
// provider class
Path providerClass = tmpdir.resolve(provider.replace('.', '/') + ".class");
Files.createDirectories(providerClass.getParent());
Files.createFile(providerClass);
// services configuration file
Path services = tmpdir.resolve("META-INF").resolve("services");
Files.createDirectories(services);
Files.write(services.resolve(service), Set.of(provider));
Path dir = Files.createTempDirectory(USER_DIR, "mods");
JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
// should throw FindException
ModuleFinder.of(dir).findAll();
}
/**
* Test JAR file with META-INF/services configuration file listing a
* provider that is not in the module.
*/
@Test(expectedExceptions = FindException.class)
public void testMissingProviderPackage() throws IOException {
Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
// services configuration file
Path services = tmpdir.resolve("META-INF").resolve("services");
Files.createDirectories(services);
Files.write(services.resolve("p.S"), Set.of("q.P"));
Path dir = Files.createTempDirectory(USER_DIR, "mods");
JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
// should throw FindException
ModuleFinder.of(dir).findAll();
}
private static Optional<ModuleReference> validateModuleReferenceFromArtifact(Log log, ArtifactDescriptor resolvedArtifact) {
var finder = ModuleFinder.of(resolvedArtifact.getPath());
Set<ModuleReference> moduleReferences;
try {
moduleReferences = finder.findAll();
} catch (FindException e) {
log.info(null, __ -> "WARNING! finding " + resolvedArtifact + " failed: " + e);
return Optional.empty();
}
var referenceOpt = moduleReferences.stream().findFirst();
if (!referenceOpt.isPresent()) {
log.info(null, __ -> "WARNING! artifact " + resolvedArtifact + " is not a valid jar");
return Optional.empty();
}
return referenceOpt;
}
/**
* Scans the given directory for packaged or exploded modules.
*
* @return a map of module name to ModuleReference for the modules found
* in the directory
*
* @throws IOException if an I/O error occurs
* @throws FindException if an error occurs scanning the entry or the
* directory contains two or more modules with the same name
*/
private Map<String, ModuleReference> scanDirectory(Path dir)
throws IOException
{
// The map of name -> mref of modules found in this directory.
Map<String, ModuleReference> nameToReference = new HashMap<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry : stream) {
BasicFileAttributes attrs;
try {
attrs = Files.readAttributes(entry, BasicFileAttributes.class);
} catch (NoSuchFileException ignore) {
// file has been removed or moved, ignore for now
continue;
}
ModuleReference mref = readModule(entry, attrs);
// module found
if (mref != null) {
// can have at most one version of a module in the directory
String name = mref.descriptor().name();
ModuleReference previous = nameToReference.put(name, mref);
if (previous != null) {
String fn1 = fileName(mref);
String fn2 = fileName(previous);
throw new FindException("Two versions of module "
+ name + " found in " + dir
+ " (" + fn1 + " and " + fn2 + ")");
}
}
}
}
return nameToReference;
}
/**
* Scans the given directory for packaged or exploded modules.
*
* @return a map of module name to ModuleReference for the modules found
* in the directory
*
* @throws IOException if an I/O error occurs
* @throws FindException if an error occurs scanning the entry or the
* directory contains two or more modules with the same name
*/
private Map<String, ModuleReference> scanDirectory(Path dir)
throws IOException
{
// The map of name -> mref of modules found in this directory.
Map<String, ModuleReference> nameToReference = new HashMap<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry : stream) {
BasicFileAttributes attrs;
try {
attrs = Files.readAttributes(entry, BasicFileAttributes.class);
} catch (NoSuchFileException ignore) {
// file has been removed or moved, ignore for now
continue;
}
ModuleReference mref = readModule(entry, attrs);
// module found
if (mref != null) {
// can have at most one version of a module in the directory
String name = mref.descriptor().name();
ModuleReference previous = nameToReference.put(name, mref);
if (previous != null) {
String fn1 = fileName(mref);
String fn2 = fileName(previous);
throw new FindException("Two versions of module "
+ name + " found in " + dir
+ " (" + fn1 + " and " + fn2 + ")");
}
}
}
}
return nameToReference;
}
/**
* Constructs a Hasher to compute hashes.
*
* If a module name `M` is specified, it will compute the hashes of
* modules that depend upon M directly or indirectly matching the
* specified --hash-modules pattern and record in the ModuleHashes
* attribute in M's module-info.class.
*
* @param name name of the module to record hashes
* @param finder module finder for the specified --module-path
*/
Hasher(String name, ModuleFinder finder) {
// Determine the modules that matches the pattern {@code modulesToHash}
Set<String> roots = finder.findAll().stream()
.map(mref -> mref.descriptor().name())
.filter(mn -> options.modulesToHash.matcher(mn).find())
.collect(Collectors.toSet());
// use system module path unless it creates a JMOD file for
// a module that is present in the system image e.g. upgradeable
// module
ModuleFinder system;
if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) {
system = ModuleFinder.of();
} else {
system = ModuleFinder.ofSystem();
}
// get a resolved module graph
Configuration config = null;
try {
config = Configuration.empty().resolve(system, finder, roots);
} catch (FindException | ResolutionException e) {
throw new CommandException("err.module.resolution.fail", e.getMessage());
}
this.moduleName = name;
this.configuration = config;
// filter modules resolved from the system module finder
this.modules = config.modules().stream()
.map(ResolvedModule::name)
.filter(mn -> roots.contains(mn) && !system.find(mn).isPresent())
.collect(Collectors.toSet());
this.hashesBuilder = new ModuleHashesBuilder(config, modules);
}
/**
* Direct dependency not found
*/
@Test(expectedExceptions = { FindException.class })
public void testDirectDependencyNotFound() {
ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
resolve(finder, "m1");
}
/**
* Transitive dependency not found
*/
@Test(expectedExceptions = { FindException.class })
public void testTransitiveDependencyNotFound() {
ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
resolve(finder, "m1");
}
/**
* Test impossible mapping of JAR files to modules names
*/
@Test(dataProvider = "badjarnames", expectedExceptions = FindException.class)
public void testBadNames(String fn, String ignore) throws IOException {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Path jf = dir.resolve(fn);
// create empty JAR file
createDummyJarFile(jf);
// should throw FindException
ModuleFinder.of(dir).findAll();
}
/**
* Test JAR files with the Automatic-Module-Name attribute with a value
* that is not a legal module name.
*/
@Test(dataProvider = "badmodulenames", expectedExceptions = FindException.class)
public void testBadAutomaticModuleNameAttribute(String name, String ignore)
throws IOException
{
// should throw FindException
testAutomaticModuleNameAttribute(name, null);
}
/**
* Test .class file in unnamed package (top-level directory)
*/
@Test(expectedExceptions = FindException.class)
public void testClassInUnnamedPackage() throws IOException {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
createDummyJarFile(dir.resolve("m.jar"), "Mojo.class");
ModuleFinder finder = ModuleFinder.of(dir);
finder.findAll();
}
private static void checkBootConflicts(FileMetadata file, Path download) throws IOException {
String filename = file.getPath().getFileName().toString();
if (!FileUtils.isZipFile(download)) {
Warning.nonZip(filename);
throw new IllegalStateException(
"File '" + filename + "' is not a valid zip file.");
}
Set<Module> modules = ModuleLayer.boot().modules();
Set<String> moduleNames = modules.stream().map(Module::getName).collect(Collectors.toSet());
Set<String> sysMods = ModuleFinder.ofSystem()
.findAll()
.stream()
.map(mr -> mr.descriptor().name())
.collect(Collectors.toSet());
ModuleDescriptor newMod = null;
try {
newMod = FileUtils.deriveModuleDescriptor(download, filename, sysMods.contains("jdk.zipfs"));
} catch (IllegalArgumentException | InvalidModuleDescriptorException | FindException e) {
Warning.illegalModule(filename);
throw e;
}
if (moduleNames.contains(newMod.name())) {
Warning.moduleConflict(newMod.name());
throw new IllegalStateException(
"Module '" + newMod.name() + "' conflicts with a module in the boot modulepath");
}
Set<String> packages = modules.stream().flatMap(m -> m.getPackages().stream()).collect(Collectors.toSet());
for (String p : newMod.packages()) {
if (packages.contains(p)) {
Warning.packageConflict(p);
throw new IllegalStateException("Package '" + p + "' in module '" + newMod.name()
+ "' conflicts with a package in the boot modulepath");
}
}
for (Requires require : newMod.requires()) {
// static requires are not mandatory
if (require.modifiers().contains(Requires.Modifier.STATIC))
continue;
String reqName = require.name();
if (StringUtils.isSystemModule(reqName)) {
if (!sysMods.contains(reqName)) {
Warning.missingSysMod(reqName);
throw new IllegalStateException("System module '" + reqName
+ "' is missing from JVM image, required by '" + newMod.name() + "'");
}
}
}
}
/**
* Reads a packaged or exploded module, returning a {@code ModuleReference}
* to the module. Returns {@code null} if the entry is not recognized.
*
* @throws IOException if an I/O error occurs
* @throws FindException if an error occurs parsing its module descriptor
*/
private ModuleReference readModule(Path entry, BasicFileAttributes attrs)
throws IOException
{
try {
// exploded module
if (attrs.isDirectory()) {
return readExplodedModule(entry); // may return null
}
// JAR or JMOD file
if (attrs.isRegularFile()) {
String fn = entry.getFileName().toString();
boolean isDefaultFileSystem = isDefaultFileSystem(entry);
// JAR file
if (fn.endsWith(".jar")) {
if (isDefaultFileSystem) {
return readJar(entry);
} else {
// the JAR file is in a custom file system so
// need to copy it to the local file system
Path tmpdir = Files.createTempDirectory("mlib");
Path target = Files.copy(entry, tmpdir.resolve(fn));
return readJar(target);
}
}
// JMOD file
if (isDefaultFileSystem && isLinkPhase && fn.endsWith(".jmod")) {
return readJMod(entry);
}
}
return null;
} catch (InvalidModuleDescriptorException e) {
throw new FindException("Error reading module: " + entry, e);
}
}
/**
* Reads a packaged or exploded module, returning a {@code ModuleReference}
* to the module. Returns {@code null} if the entry is not recognized.
*
* @throws IOException if an I/O error occurs
* @throws FindException if an error occurs parsing its module descriptor
*/
private ModuleReference readModule(Path entry, BasicFileAttributes attrs)
throws IOException
{
try {
// exploded module
if (attrs.isDirectory()) {
return readExplodedModule(entry); // may return null
}
// JAR or JMOD file
if (attrs.isRegularFile()) {
String fn = entry.getFileName().toString();
boolean isDefaultFileSystem = isDefaultFileSystem(entry);
// JAR file
if (fn.endsWith(".jar")) {
if (isDefaultFileSystem) {
return readJar(entry);
} else {
// the JAR file is in a custom file system so
// need to copy it to the local file system
Path tmpdir = Files.createTempDirectory("mlib");
Path target = Files.copy(entry, tmpdir.resolve(fn));
return readJar(target);
}
}
// JMOD file
if (isDefaultFileSystem && isLinkPhase && fn.endsWith(".jmod")) {
return readJMod(entry);
}
}
return null;
} catch (InvalidModuleDescriptorException e) {
throw new FindException("Error reading module: " + entry, e);
}
}
/**
* Root module not found
*/
@Test(expectedExceptions = { FindException.class })
public void testRootNotFound() {
resolve(ModuleFinder.of(), "m1");
}
/**
* Test attempting to create a configuration with modules for different
* platforms.
*/
@Test(dataProvider = "platformmismatch",
expectedExceptions = FindException.class )
public void testPlatformMisMatch(String s1, String s2) throws IOException {
testPlatformMatch(s1, s2);
}