下面列出了java.lang.module.Configuration#resolve ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static void main(String[] args) throws Exception {
final String MY_MODULE_NAME = "myModule";
// Verify that JVMTI reports exactly the same info as Java regarding the named modules
Asserts.assertEquals(ModuleLayer.boot().modules(), getModulesJVMTI());
// Load a new named module
ModuleDescriptor descriptor = ModuleDescriptor.newModule(MY_MODULE_NAME).build();
ModuleFinder finder = finderOf(descriptor);
ClassLoader loader = new ClassLoader() {};
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of(MY_MODULE_NAME));
ModuleLayer my = ModuleLayer.boot().defineModules(cf, m -> loader);
// Verify that the loaded module is indeed reported by JVMTI
Set<Module> jvmtiModules = getModulesJVMTI();
for (Module mod : my.modules()) {
if (!jvmtiModules.contains(mod)) {
throw new RuntimeException("JVMTI did not report the loaded named module: " + mod.getName());
}
}
}
/**
* Attempt to use defineModules to create a layer with a module
* containing a package in which a type is already loaded by the class
* loader.
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testPackageAlreadyInUnnamedModule() throws Exception {
Class<?> c = layertest.Test.class;
assertFalse(c.getModule().isNamed()); // in unnamed module
ModuleDescriptor md = newBuilder("m")
.packages(Set.of(c.getPackageName()))
.requires("java.base")
.build();
ModuleFinder finder = ModuleUtils.finderOf(md);
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
ModuleLayer.boot().defineModules(cf, mn -> c.getClassLoader());
}
/**
* Exercise defineModules with a configuration with a module that
* contains a package that is the same name as a non-exported package in
* a parent layer.
*/
public void testContainsSamePackageAsBootLayer() {
// check assumption that java.base contains sun.launcher
ModuleDescriptor base = Object.class.getModule().getDescriptor();
assertTrue(base.packages().contains("sun.launcher"));
ModuleDescriptor descriptor = newBuilder("m1")
.requires("java.base")
.packages(Set.of("sun.launcher"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor);
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
assertTrue(cf.modules().size() == 1);
ClassLoader loader = new ClassLoader() { };
ModuleLayer layer = ModuleLayer.boot().defineModules(cf, mn -> loader);
assertTrue(layer.modules().size() == 1);
}
/**
* Basic test of resolving a module that depends on modules in two parent
* configurations.
*
* The test consists of three configurations:
* - Configuration cf1: m1
* - Configuration cf2: m2
* - Configuration cf3(cf1,cf2): m3 requires m1, m2
*/
public void testResolvedInMultipleParents1() {
// Configuration cf1: m1
ModuleDescriptor descriptor1 = newBuilder("m1").build();
Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
assertEquals(cf1.parents(), List.of(Configuration.empty()));
assertTrue(cf1.findModule("m1").isPresent());
ResolvedModule m1 = cf1.findModule("m1").get();
assertTrue(m1.configuration() == cf1);
// Configuration cf2: m2
ModuleDescriptor descriptor2 = newBuilder("m2").build();
Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
assertEquals(cf2.parents(), List.of(Configuration.empty()));
assertTrue(cf2.findModule("m2").isPresent());
ResolvedModule m2 = cf2.findModule("m2").get();
assertTrue(m2.configuration() == cf2);
// Configuration cf3(cf1,cf2): m3 requires m1 and m2
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.requires("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor3);
Configuration cf3 = Configuration.resolve(
finder,
List.of(cf1, cf2), // parents
ModuleFinder.of(),
Set.of("m3"));
assertEquals(cf3.parents(), List.of(cf1, cf2));
assertTrue(cf3.findModule("m3").isPresent());
ResolvedModule m3 = cf3.findModule("m3").get();
assertTrue(m3.configuration() == cf3);
// check readability
assertTrue(m1.reads().isEmpty());
assertTrue(m2.reads().isEmpty());
assertEquals(m3.reads(), Set.of(m1, m2));
}
/**
* Basic test of using the beforeFinder to override a module in a parent
* configuration.
*/
public void testOverriding2() {
ModuleDescriptor descriptor1 = newBuilder("m1").build();
Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
ModuleDescriptor descriptor2 = newBuilder("m2").build();
Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m2").isPresent());
ModuleDescriptor descriptor3 = newBuilder("m3").build();
Configuration cf3 = resolve(ModuleUtils.finderOf(descriptor3), "m3");
assertTrue(cf3.modules().size() == 1);
assertTrue(cf3.findModule("m3").isPresent());
// override m2, m1 and m3 should be found in parent configurations
ModuleFinder finder = ModuleUtils.finderOf(descriptor2);
Configuration cf4 = Configuration.resolve(
finder,
List.of(cf1, cf2, cf3),
ModuleFinder.of(),
Set.of("m1", "m2", "m3"));
assertTrue(cf4.modules().size() == 1);
assertTrue(cf4.findModule("m2").isPresent());
ResolvedModule m2 = cf4.findModule("m2").get();
assertTrue(m2.configuration() == cf4);
}
/**
* Basic test to detect reading two modules with the same name
*
* The test consists of three configurations:
* - Configuration cf1: m1, m2 requires transitive m1
* - Configuration cf2: m1, m3 requires transitive m1
* - Configuration cf3(cf1,cf2): m4 requires m2, m3
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testReadTwoModuleWithSameName() {
ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleDescriptor descriptor3 = newBuilder("m3")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m2")
.requires("m3")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
Configuration cf2 = resolve(finder2, "m3");
assertTrue(cf2.modules().size() == 2);
// should throw ResolutionException as m4 will read modules named "m1".
ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);
Configuration.resolve(finder3, List.of(cf1, cf2), ModuleFinder.of(), Set.of("m4"));
}
/**
* Invokes parent.resolve(...)
*/
private Configuration resolve(Configuration parent,
ModuleFinder before,
ModuleFinder after,
String... roots) {
return parent.resolve(before, after, Set.of(roots));
}
/**
* Create a custom layer by resolving the given module names. The modules
* are located in the {@code ${test.classes}/modules} directory.
*/
private ModuleLayer createCustomLayer(String... modules) {
Path dir = Paths.get(System.getProperty("test.classes", "."), "modules");
ModuleFinder finder = ModuleFinder.of(dir);
Set<String> roots = new HashSet<>();
Collections.addAll(roots, modules);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration parent = bootLayer.configuration();
Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
assertTrue(layer.modules().size() == 1);
return layer;
}
/**
* 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 ModuleLayer.defineModulesWithXXX when the modules that override same
* named modules in the parent layer.
*
* layer1: m1, m2, m3 => same loader
* layer2: m1, m3 => same loader
*/
public void testOverriding3() throws Exception {
Configuration cf1 = resolve("m1");
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = finderFor("m1", "m3");
Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
Set.of("m1"));
ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
checkLayer(layer2, "m1", "m3");
invoke(layer1, "m1", "p.Main");
ClassLoader loader1 = layer1.findLoader("m1");
ClassLoader loader2 = layer2.findLoader("m1");
assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2);
assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1);
assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2);
}
/**
* Resolve the given modules, by name, and returns the resulting
* Configuration.
*/
private static Configuration resolve(Configuration cf,
ModuleFinder finder,
String... roots) {
return cf.resolve(finder, ModuleFinder.of(), Set.of(roots));
}
@Test(expectedExceptions = { IllegalArgumentException.class })
public void testResolveRequiresWithNoParents() {
ModuleFinder empty = ModuleFinder.of();
Configuration.resolve(empty, List.of(), empty, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull3() {
Configuration empty = Configuration.empty();
Configuration.resolve(null, List.of(empty), ModuleFinder.of(), Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull4() {
ModuleFinder empty = ModuleFinder.of();
Configuration.resolve(empty, null, empty, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull5() {
Configuration cf = ModuleLayer.boot().configuration();
Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull6() {
ModuleFinder empty = ModuleFinder.of();
Configuration cf = ModuleLayer.boot().configuration();
Configuration.resolve(empty, List.of(cf), empty, null);
}
/**
* Basic test of automatic modules in a child configuration. All automatic
* modules that are found with the before finder should be resolved. The
* automatic modules that are found by the after finder and not shadowed
* by the before finder, or parent configurations, should also be resolved.
*/
public void testInConfiguration6() throws IOException {
// m1 requires auto1
ModuleDescriptor descriptor1
= ModuleDescriptor.newModule("m1")
.requires("auto1")
.build();
Path dir = Files.createTempDirectory(USER_DIR, "mods");
createDummyJarFile(dir.resolve("auto1.jar"), "p1/C.class");
// module finder locates m1 and auto1
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
ModuleFinder finder2 = ModuleFinder.of(dir);
ModuleFinder finder = ModuleFinder.compose(finder1, finder2);
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf1 = resolve(parent, finder, "m1");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
assertTrue(cf1.findModule("auto1").isPresent());
ResolvedModule base = parent.findModule("java.base")
.orElseThrow(() -> new RuntimeException());
ResolvedModule m1 = cf1.findModule("m1").get();
ResolvedModule auto1 = cf1.findModule("auto1").get();
assertTrue(m1.reads().size() == 2);
assertTrue(m1.reads().contains(auto1));
assertTrue(m1.reads().contains(base));
assertTrue(auto1.reads().contains(m1));
assertTrue(auto1.reads().contains(base));
// create child configuration - the after finder locates auto1
dir = Files.createTempDirectory(USER_DIR, "mods");
createDummyJarFile(dir.resolve("auto2.jar"), "p2/C.class");
ModuleFinder beforeFinder = ModuleFinder.of(dir);
dir = Files.createTempDirectory(USER_DIR, "mods");
createDummyJarFile(dir.resolve("auto1.jar"), "p1/C.class");
createDummyJarFile(dir.resolve("auto2.jar"), "p2/C.class");
createDummyJarFile(dir.resolve("auto3.jar"), "p3/C.class");
ModuleFinder afterFinder = ModuleFinder.of(dir);
Configuration cf2 = cf1.resolve(beforeFinder, afterFinder, Set.of("auto2"));
// auto1 should be found in parent and should not be in cf2
assertTrue(cf2.modules().size() == 2);
assertTrue(cf2.findModule("auto2").isPresent());
assertTrue(cf2.findModule("auto3").isPresent());
ResolvedModule auto2 = cf2.findModule("auto2").get();
ResolvedModule auto3 = cf2.findModule("auto3").get();
assertTrue(auto2.reads().contains(m1));
assertTrue(auto2.reads().contains(auto1));
assertTrue(auto2.reads().contains(auto3));
assertTrue(auto2.reads().contains(base));
assertTrue(auto3.reads().contains(m1));
assertTrue(auto3.reads().contains(auto1));
assertTrue(auto3.reads().contains(auto2));
assertTrue(auto3.reads().contains(base));
}
/**
* Invokes parent.resolve to resolve the given root modules.
*/
static Configuration resolve(Configuration parent,
ModuleFinder finder,
String... roots) {
return parent.resolve(finder, ModuleFinder.of(), Set.of(roots));
}
/**
* Attempt to use defineModules to create a layer with a module defined
* to a class loader that already has a module of the same name defined
* to the class loader.
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testModuleAlreadyDefinedToLoader() {
ModuleDescriptor md = newBuilder("m")
.requires("java.base")
.build();
ModuleFinder finder = ModuleUtils.finderOf(md);
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
ClassLoader loader = new ClassLoader() { };
ModuleLayer.boot().defineModules(cf, mn -> loader);
// should throw LayerInstantiationException as m1 already defined to loader
ModuleLayer.boot().defineModules(cf, mn -> loader);
}
/**
* Attempt to use defineModules to create a layer with a module containing
* package {@code p} where the class loader already has a module defined
* to it containing package {@code p}.
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testPackageAlreadyInNamedModule() {
ModuleDescriptor md1 = newBuilder("m1")
.packages(Set.of("p"))
.requires("java.base")
.build();
ModuleDescriptor md2 = newBuilder("m2")
.packages(Set.of("p"))
.requires("java.base")
.build();
ModuleFinder finder = ModuleUtils.finderOf(md1, md2);
ClassLoader loader = new ClassLoader() { };
// define m1 containing package p to class loader
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
ModuleLayer layer1 = ModuleLayer.boot().defineModules(cf1, mn -> loader);
// attempt to define m2 containing package p to class loader
Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2"));
// should throw exception because p already in m1
ModuleLayer layer2 = ModuleLayer.boot().defineModules(cf2, mn -> loader);
}