下面列出了java.lang.module.ModuleFinder#of ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Test ModuleFinder with an exploded module containing a mix of class
* and non-class resources
*/
public void testOfOneExplodedModuleWithResources() throws Exception {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Path m_dir = createExplodedModule(dir.resolve("m"), "m",
"LICENSE",
"README",
"WEB-INF/tags",
"p/Type.class",
"p/resources/m.properties",
"q-/Type.class", // not a legal package name
"q-/resources/m/properties");
ModuleFinder finder = ModuleFinder.of(m_dir);
Optional<ModuleReference> mref = finder.find("m");
assertTrue(mref.isPresent(), "m not found");
ModuleDescriptor descriptor = mref.get().descriptor();
assertTrue(descriptor.packages().size() == 2);
assertTrue(descriptor.packages().contains("p"));
assertTrue(descriptor.packages().contains("p.resources"));
}
/**
* Test that a JAR file with a Main-Class attribute results
* in a module with a main class.
*/
public void testMainClass() throws IOException {
String mainClass = "p.Main";
Manifest man = new Manifest();
Attributes attrs = man.getMainAttributes();
attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
attrs.put(Attributes.Name.MAIN_CLASS, mainClass);
Path dir = Files.createTempDirectory(USER_DIR, "mods");
String entry = mainClass.replace('.', '/') + ".class";
createDummyJarFile(dir.resolve("m.jar"), man, entry);
ModuleFinder finder = ModuleFinder.of(dir);
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf = resolve(parent, finder, "m");
ModuleDescriptor descriptor = findDescriptor(cf, "m");
assertTrue(descriptor.mainClass().isPresent());
assertEquals(descriptor.mainClass().get(), mainClass);
}
@Test
public void test() throws Exception {
ModuleFinder empty = ModuleFinder.of();
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration cf0 = bootLayer.configuration();
Configuration cf1 = cf0.resolveAndBind(finder, empty, Set.of("s1", "s2"));
Configuration cf2 = cf1.resolveAndBind(finder, empty, Set.of("s1", "s2"));
// cf1 contains s1, p1, s2, p2
assertTrue(cf1.modules().size() == 4);
// cf1 contains s1, p1, s2, p2
assertTrue(cf2.modules().size() == 4);
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer1 = bootLayer.defineModulesWithManyLoaders(cf1, scl);
testLayer(layer1);
ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, scl);
testLayer(layer2);
}
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage AddPackagesAttribute exploded-java-home");
System.exit(-1);
}
String home = args[0];
Path dir = Paths.get(home, "modules");
ModuleFinder finder = ModuleFinder.of(dir);
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry : stream) {
Path mi = entry.resolve("module-info.class");
if (Files.isRegularFile(mi)) {
String mn = entry.getFileName().toString();
Optional<ModuleReference> omref = finder.find(mn);
if (omref.isPresent()) {
Set<String> packages = omref.get().descriptor().packages();
addPackagesAttribute(mi, packages);
}
}
}
}
}
/**
* 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();
}
}
@Test(dataProvider = "platformmatch")
public void testResolveRequiresWithCompatibleParents(String s1, String s2)
throws IOException
{
ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build();
Path system = writeModule(base, null);
ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1").build();
Path dir1 = writeModule(descriptor1, s1);
ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build();
Path dir2 = writeModule(descriptor2, s2);
ModuleFinder finder1 = ModuleFinder.of(system, dir1);
Configuration cf1 = resolve(finder1, "m1");
ModuleFinder finder2 = ModuleFinder.of(system, dir2);
Configuration cf2 = resolve(finder2, "m2");
Configuration cf3 = Configuration.resolve(ModuleFinder.of(),
List.of(cf1, cf2),
ModuleFinder.of(),
Set.of());
assertTrue(cf3.parents().size() == 2);
}
/**
* Test ModuleFinder with a JAR file containing a mix of class and
* non-class resources.
*/
public void testOfOneJarFileWithResources() throws Exception {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Path jar = createModularJar(dir.resolve("m.jar"), "m",
"LICENSE",
"README",
"WEB-INF/tags",
"p/Type.class",
"p/resources/m.properties",
"q-/Type.class", // not a legal package name
"q-/resources/m/properties");
ModuleFinder finder = ModuleFinder.of(jar);
Optional<ModuleReference> mref = finder.find("m");
assertTrue(mref.isPresent(), "m1 not found");
ModuleDescriptor descriptor = mref.get().descriptor();
assertTrue(descriptor.packages().size() == 2);
assertTrue(descriptor.packages().contains("p"));
assertTrue(descriptor.packages().contains("p.resources"));
}
@Override
public String call() throws Exception {
for (int i = 0 ; i < REPEATATION_PER_THREAD ; i++ ) {
//Obtain the parent Layer we currently have, which should be the boot layer
ModuleLayer parentLayer = ModuleLayer.boot();
//Obtain the parent Configuration
Path modulePath = FileSystems.getDefault().getPath(System.getProperty("module.path"));
ModuleFinder moduleFinder = ModuleFinder.of(modulePath);
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
Configuration cf1 = parentLayer.configuration()
.resolve(moduleFinder, ModuleFinder.of(), Set.of("com.hello"));
Configuration cf2 = parentLayer.configuration()
.resolve(moduleFinder, ModuleFinder.of(), Set.of("com.helper"));
ModuleLayer layer1 = parentLayer.defineModulesWithManyLoaders(cf1, systemClassLoader);
ModuleLayer layer2 = parentLayer.defineModulesWithManyLoaders(cf2, systemClassLoader);
Class<?> c1 = layer1.findLoader("com.hello").loadClass("adoptopenjdk.test.modularity.hello.Hello");
String returnValue = (String) c1.getMethod("name").invoke(null);
assertEquals("Test failed - Expected value: [Hello], but value received: [" + returnValue + "]", returnValue, "Hello");
Class<?> c2 = layer2.findLoader("com.helper").loadClass("adoptopenjdk.test.modularity.helper.pkgOne.HelperClass");
returnValue = (String) c2.getMethod("name").invoke(null);
assertEquals("Test failed - Expected value: [Helper], but value received: [" + returnValue + "]", returnValue, "helper");
}
System.out.println("Thread : " + Thread.currentThread().getName() + " done!");
return null;
}
/**
* Test ModuleLayer.defineModulesWithXXX when the modules that override same
* named modules in the parent layer.
*
* Test scenario:
* layer1: m1, m2, m3 => same loader
* layer2: m1, m2, m4 => same loader
*/
public void testOverriding1() throws Exception {
Configuration cf1 = resolve("m1");
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
Set.of("m1"));
ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
checkLayer(layer2, "m1", "m2", "m3");
invoke(layer1, "m1", "p.Main");
ClassLoader loader1 = layer1.findLoader("m1");
ClassLoader loader2 = layer1.findLoader("m2");
ClassLoader loader3 = layer1.findLoader("m3");
ClassLoader loader4 = layer2.findLoader("m1");
ClassLoader loader5 = layer2.findLoader("m2");
ClassLoader loader6 = layer2.findLoader("m3");
assertTrue(loader1 == loader2);
assertTrue(loader1 == loader3);
assertTrue(loader4 == loader5);
assertTrue(loader4 == loader6);
assertTrue(loader4 != loader1);
assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4);
assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4);
}
/**
* Test a multi-release JAR with a module-info.class in the versioned
* section of the JAR.
*/
public void testModuleInfoInVersionedSection() throws Exception {
String name = "m1";
ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
.requires("java.base")
.build();
// module descriptor for versioned section
ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
.requires("java.base")
.requires("jdk.unsupported")
.build();
Path jar = new JarBuilder(name)
.moduleInfo(MODULE_INFO, descriptor1)
.resource("p/Main.class")
.resource("p/Helper.class")
.moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
.resource("META-INF/versions/" + VERSION + "/p/Helper.class")
.resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
.build();
// find the module
ModuleFinder finder = ModuleFinder.of(jar);
Optional<ModuleReference> omref = finder.find(name);
assertTrue((omref.isPresent()));
ModuleReference mref = omref.get();
// ensure that the right module-info.class is loaded
ModuleDescriptor descriptor = mref.descriptor();
assertEquals(descriptor.name(), name);
if (MULTI_RELEASE) {
assertEquals(descriptor.requires(), descriptor2.requires());
} else {
assertEquals(descriptor.requires(), descriptor1.requires());
}
}
public ClassLoader createAndRunFromModule(String moduleName, Path modPath) {
ModuleFinder finder = ModuleFinder.of(modPath);
ModuleLayer parent = ModuleLayer.boot();
Configuration cf = parent.configuration()
.resolve(finder, ModuleFinder.of(), Set.of(moduleName));
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
ClassLoader loader = layer.findLoader(moduleName);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(loader);
return ccl;
}
public static void main(String[] args) throws Exception {
// create content for JAR file
Path dir = Files.createTempDirectory("classes");
Path p = Files.createDirectory(dir.resolve("p"));
Files.createFile(p.resolve("Foo.class"));
Files.createFile(p.resolve("foo.properties"));
Path resources = Files.createDirectory(p.resolve("resources"));
Files.createFile(resources.resolve("bar.properties"));
// create the JAR file, including a manifest
Path jarFile = Paths.get("library-1.0.jar");
Manifest man = new Manifest();
Attributes attrs = man.getMainAttributes();
attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
JarUtils.createJarFile(jarFile, man, dir, p);
// get the module name
ModuleFinder finder = ModuleFinder.of(jarFile);
ModuleReference mref = finder.findAll().stream().findAny().orElse(null);
if (mref == null)
throw new RuntimeException("Module not found!!!");
String name = mref.descriptor().name();
// launch the test with the JAR file on the module path
if (ProcessTools.executeTestJava("-p", jarFile.toString(),
"--add-modules", name,
"-cp", TEST_CLASSES,
"Main", name)
.outputTo(System.out)
.errorTo(System.out)
.getExitValue() != 0)
throw new RuntimeException("Test failed - see output");
}
/**
* Test miscellaneous methods.
*/
public void testMisc() throws IOException {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Path m_jar = createDummyJarFile(dir.resolve("m.jar"), "p/T.class");
ModuleFinder finder = ModuleFinder.of(m_jar);
assertTrue(finder.find("m").isPresent());
ModuleDescriptor m = finder.find("m").get().descriptor();
// test miscellaneous methods
assertTrue(m.isAutomatic());
assertFalse(m.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC));
}
private static ClassLoader createModuleLoader(final ClassLoader cl,
final String modulePath, final String addModules) {
if (addModules == null) {
throw new IllegalArgumentException("--module-path specified with no --add-modules");
}
final Path[] paths = Stream.of(modulePath.split(File.pathSeparator)).
map(s -> Paths.get(s)).
toArray(sz -> new Path[sz]);
final ModuleFinder mf = ModuleFinder.of(paths);
final Set<ModuleReference> mrefs = mf.findAll();
if (mrefs.isEmpty()) {
throw new RuntimeException("No modules in script --module-path: " + modulePath);
}
final Set<String> rootMods;
if (addModules.equals("ALL-MODULE-PATH")) {
rootMods = mrefs.stream().
map(mr->mr.descriptor().name()).
collect(Collectors.toSet());
} else {
rootMods = Stream.of(addModules.split(",")).
map(String::trim).
collect(Collectors.toSet());
}
final ModuleLayer boot = ModuleLayer.boot();
final Configuration conf = boot.configuration().
resolve(mf, ModuleFinder.of(), rootMods);
final String firstMod = rootMods.iterator().next();
return boot.defineModulesWithOneLoader(conf, cl).findLoader(firstMod);
}
/**
* Test ModuleFinder.of with a file path to a directory containing a file
* that will not be recognized as a module.
*/
public void testOfWithUnrecognizedEntryInDirectory1() throws Exception {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Files.createTempFile(dir, "m", ".junk");
ModuleFinder finder = ModuleFinder.of(dir);
assertFalse(finder.find("java.rhubarb").isPresent());
finder = ModuleFinder.of(dir);
assertTrue(finder.findAll().isEmpty());
}
@Override
public int execute(Config config) throws IOException {
var log = Log.create(name(), config.getOrThrow("pro", ProConf.class).loglevel());
log.debug(config, conf -> "config " + config);
var jlinkTool = ToolProvider.findFirst("jlink").orElseThrow(() -> new IllegalStateException("can not find jlink"));
var linkerConf = config.getOrThrow(name(), LinkerConf.class);
var systemModulePath = linkerConf.systemModulePath();
if (!(Files.exists(systemModulePath))) {
throw new IOException("unable to find system modules at " + systemModulePath);
}
var moduleFinder = ModuleFinder.of(linkerConf.moduleArtifactSourcePath());
var rootModules = linkerConf.rootModules().map(HashSet::new).orElseGet(() -> {
return moduleFinder.findAll().stream()
.map(reference -> reference.descriptor().name())
.collect(Collectors.toCollection(HashSet::new));
});
linkerConf.serviceNames().ifPresent(serviceNames -> {
ModuleFinder rootFinder = ModuleFinder.compose(moduleFinder, ModuleHelper.systemModulesFinder());
ModuleHelper.findAllModulesWhichProvideAService(serviceNames, rootFinder)
.map(ref -> ref.descriptor().name())
.forEach(rootModules::add);
});
// find launchers
var launchers = linkerConf.launchers().orElseGet(() -> findLaunchersFromMainClasses(rootModules, moduleFinder));
if (launchers.isEmpty()) {
log.error(null, __ -> "no launcher found and no main classes defined in the root modules");
return 1; //FIXME
}
var modulePath =
linkerConf.modulePath()
.orElseGet(() -> StableList.of(linkerConf.moduleArtifactSourcePath())
.appendAll(FileHelper.pathFromFilesThatExist(linkerConf.moduleDependencyPath()))
.append(systemModulePath));
log.debug(rootModules, roots -> "rootModules " + roots);
log.debug(launchers, launcherMains -> "launchers " + launcherMains);
var jlink = new Jlink(linkerConf, rootModules, launchers, modulePath);
var destination = linkerConf.destination();
FileHelper.deleteAllFiles(destination, true);
var arguments = OptionAction.gatherAll(JlinkOption.class, option -> option.action).apply(jlink, new CmdLine()).toArguments();
log.verbose(null, __ -> OptionAction.toPrettyString(JlinkOption.class, option -> option.action).apply(jlink, "jlink"));
var errorCode = jlinkTool.run(System.out, System.err, arguments);
if (errorCode != 0) {
return errorCode;
}
if (linkerConf.includeSystemJMODs()) {
var jmods = destination.resolve("jmods");
Files.createDirectories(jmods);
try(var directoryStream = Files.newDirectoryStream(systemModulePath)) {
for(var path: directoryStream) {
Files.copy(path, jmods.resolve(path.getFileName()));
}
}
}
return 0;
}
private static Optional<String> findArtifactModuleName(ArtifactDescriptor resolvedArtifact) {
var finder = ModuleFinder.of(resolvedArtifact.getPath());
var referenceOpt = finder.findAll().stream().findFirst();
return referenceOpt.map(ref -> ref.descriptor().name());
}
public static void main(String[] args) throws Exception {
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
ModuleLayer layerBoot = ModuleLayer.boot();
Configuration cf = layerBoot
.configuration()
.resolve(ModuleFinder.of(), finder, Set.of(MODULE_NAME));
Module testModule = Main.class.getModule();
ClassLoader scl = ClassLoader.getSystemClassLoader();
// Create an unique module/class loader in a layer above the boot layer.
// Export this module to the jdk.test/test package.
Callable<Void> task = new Callable<Void>() {
@Override
public Void call() throws Exception {
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
Module transletModule = layer.findModule(MODULE_NAME).get();
testModule.addExports("test", transletModule);
Class<?> c = layer.findLoader(MODULE_NAME).loadClass("translet.Main");
Method method = c.getDeclaredMethod("go");
method.invoke(null);
return null;
}
};
List<Future<Void>> results = new ArrayList<>();
// Repeatedly create the layer above stressing the exportation of
// package jdk.test/test to several different modules.
ExecutorService pool = Executors.newFixedThreadPool(Math.min(100, Runtime.getRuntime().availableProcessors()*10));
try {
for (int i = 0; i < 10000; i++) {
results.add(pool.submit(task));
}
} finally {
pool.shutdown();
}
int passed = 0;
int failed = 0;
// The failed state should be 0, the created modules in layers above the
// boot layer should be allowed access to the contents of the jdk.test/test
// package since that package was exported to the transletModule above.
for (Future<Void> result : results) {
try {
result.get();
passed++;
} catch (Throwable x) {
x.printStackTrace();
failed++;
}
}
System.out.println("passed: " + passed);
System.out.println("failed: " + failed);
}
/**
* Test ModuleFinder.compose with no module finders
*/
public void testComposeOfNone() throws Exception {
ModuleFinder finder = ModuleFinder.of();
assertTrue(finder.findAll().isEmpty());
assertFalse(finder.find("java.rhubarb").isPresent());
}
@Test(expectedExceptions = { IllegalArgumentException.class })
public void testResolveRequiresWithNoParents() {
ModuleFinder empty = ModuleFinder.of();
Configuration.resolve(empty, List.of(), empty, Set.of());
}