Optional<ModuleDescriptor> describeModule(URI uri) { var path = load(uri); if (!path.isPresent()) { return Optional.empty(); } try { debug("describeModule({0} -> {1})", uri, path); return describeModule(path.get(), true); } finally { try { Files.delete(path.get()); } catch (Exception e) { debug("deleting temp file failed: {0}", e); } } }
public void testOpensToTargets() { Set<String> targets = new HashSet<>(); targets.add("bar"); targets.add("gus"); Opens o = ModuleDescriptor.newModule("foo") .opens("p", targets) .build() .opens() .iterator() .next(); assertEquals(o, o); assertTrue(o.modifiers().isEmpty()); assertEquals(o.source(), "p"); assertTrue(o.isQualified()); assertTrue(o.targets().size() == 2); assertTrue(o.targets().contains("bar")); assertTrue(o.targets().contains("gus")); }
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()); } } }
static void checkModuleDescriptor(ModuleDescriptor md, String... packages) throws IOException { String mainClass = md.name().replace('m', 'p') + ".Main"; if (!md.mainClass().get().equals(mainClass)) { throw new RuntimeException(md.mainClass().toString()); } // ModuleTarget attribute should be present if (!hasModuleTarget(md.name())) { throw new RuntimeException("ModuleTarget missing for " + md.name()); } Set<String> pkgs = md.packages(); if (!pkgs.equals(Set.of(packages))) { throw new RuntimeException(pkgs + " expected: " + Set.of(packages)); } }
public void testExportsToTargets() { Set<String> targets = new HashSet<>(); targets.add("bar"); targets.add("gus"); Exports e = ModuleDescriptor.newModule("foo") .exports("p", targets) .build() .exports() .iterator() .next(); assertEquals(e, e); assertTrue(e.modifiers().isEmpty()); assertEquals(e.source(), "p"); assertTrue(e.isQualified()); assertTrue(e.targets().size() == 2); assertTrue(e.targets().contains("bar")); assertTrue(e.targets().contains("gus")); }
/** * Test the scenario where a module contains a package p and reads * a module that exports package p. */ @Test(expectedExceptions = { ResolutionException.class }) public void testPackageSuppliedBySelfAndOther() { ModuleDescriptor descriptor1 = newBuilder("m1") .requires("m2") .packages(Set.of("p")) .build(); ModuleDescriptor descriptor2 = newBuilder("m2") .exports("p") .build(); ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); // m1 contains package p, module m2 exports package p to m1 resolve(finder, "m1"); }
/** * Basic test to ensure that no automatic modules are resolved when * an automatic module is not a root or required by other modules. */ public void testInConfiguration4() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") .requires("java.base") .build(); // automatic modules Path 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"); // module finder locates m1 and the modules in the directory ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); ModuleFinder finder2 = ModuleFinder.of(dir); ModuleFinder finder = ModuleFinder.compose(finder1, finder2); Configuration parent = ModuleLayer.boot().configuration(); Configuration cf = resolve(parent, finder, "m1"); // ensure that no automatic module is resolved assertTrue(cf.modules().size() == 1); assertTrue(cf.findModule("m1").isPresent()); }
/** * Test "uses p.S" where p is contained in a different module. */ @Test(expectedExceptions = { ResolutionException.class }) public void testContainsService2() { ModuleDescriptor descriptor1 = newBuilder("m1") .packages(Set.of("p")) .build(); ModuleDescriptor descriptor2 = newBuilder("m2") .requires("m1") .uses("p.S") .build(); ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); // m2 does not read a module that exports p resolve(finder, "m2"); }
@DataProvider(name = "sortedModuleDescriptors") public Object[][] sortedModuleDescriptors() { return new Object[][]{ { ModuleDescriptor.newModule("m2").build(), ModuleDescriptor.newModule("m1").build() }, { ModuleDescriptor.newModule("m").version("2").build(), ModuleDescriptor.newModule("m").version("1").build() }, { ModuleDescriptor.newModule("m").version("1").build(), ModuleDescriptor.newModule("m").build() }, { ModuleDescriptor.newOpenModule("m").build(), ModuleDescriptor.newModule("m").build() }, }; }
/** * 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); }
/** * Test two modules exporting package p to a module that reads both. */ @Test(expectedExceptions = { ResolutionException.class }) public void testPackageSuppliedByTwoOthers() { ModuleDescriptor descriptor1 = newBuilder("m1") .requires("m2") .requires("m3") .build(); ModuleDescriptor descriptor2 = newBuilder("m2") .exports("p") .build(); ModuleDescriptor descriptor3 = newBuilder("m3") .exports("p", Set.of("m1")) .build(); ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); // m2 and m3 export package p to module m1 resolve(finder, "m1"); }
private void dedups(ModuleDescriptor md) { // exports for (Exports e : md.exports()) { dedupSetBuilder.stringSet(e.targets()); dedupSetBuilder.exportsModifiers(e.modifiers()); } // opens for (Opens opens : md.opens()) { dedupSetBuilder.stringSet(opens.targets()); dedupSetBuilder.opensModifiers(opens.modifiers()); } // requires for (Requires r : md.requires()) { dedupSetBuilder.requiresModifiers(r.modifiers()); } // uses dedupSetBuilder.stringSet(md.uses()); }
/** * 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"); }
/** * Apply transitive reduction on the resulting graph and reports * recommended requires. */ private void analyzeDeps() { printModuleDescriptor(log, root); ModuleDescriptor analyzedDescriptor = descriptor(); if (!matches(root.descriptor(), analyzedDescriptor)) { log.format(" [Suggested module descriptor for %s]%n", root.name()); analyzedDescriptor.requires() .stream() .sorted(Comparator.comparing(ModuleDescriptor.Requires::name)) .forEach(req -> log.format(" requires %s;%n", req)); } ModuleDescriptor reduced = reduced(); if (!matches(root.descriptor(), reduced)) { log.format(" [Transitive reduced graph for %s]%n", root.name()); reduced.requires() .stream() .sorted(Comparator.comparing(ModuleDescriptor.Requires::name)) .forEach(req -> log.format(" requires %s;%n", req)); } checkQualifiedExports(); log.println(); }
public void testAutomaticModule() { ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo") .packages(Set.of("p")) .provides("p.Service", List.of("q.ServiceImpl")) .build(); // modifiers assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC)); assertTrue(descriptor.isAutomatic()); // requires assertTrue(descriptor.requires().size() == 1); Set<String> names = descriptor.requires() .stream() .map(Requires::name) .collect(Collectors.toSet()); assertEquals(names, Set.of("java.base")); // packages assertEquals(descriptor.packages(), Set.of("p", "q")); assertTrue(descriptor.exports().isEmpty()); assertTrue(descriptor.opens().isEmpty()); }
/** * Test ModuleDescriptor with a packager finder */ public void testReadsWithPackageFinder() throws Exception { ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo") .requires("java.base") .build(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ModuleInfoWriter.write(descriptor, baos); ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray()); descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q")); assertTrue(descriptor.packages().size() == 2); assertTrue(descriptor.packages().contains("p")); assertTrue(descriptor.packages().contains("q")); }
/** * Creates a new named Module. The resulting Module will be defined to the * VM but will not read any other modules, will not have any exports setup * and will not be registered in the service catalog. */ Module(ModuleLayer layer, ClassLoader loader, ModuleDescriptor descriptor, URI uri) { this.layer = layer; this.name = descriptor.name(); this.loader = loader; this.descriptor = descriptor; // define module to VM boolean isOpen = descriptor.isOpen() || descriptor.isAutomatic(); Version version = descriptor.version().orElse(null); String vs = Objects.toString(version, null); String loc = Objects.toString(uri, null); String[] packages = descriptor.packages().toArray(new String[0]); defineModule0(this, isOpen, vs, loc, packages); }
/** * Creates a {@code Loader} in a loader pool that loads classes/resources * from one module. */ public Loader(ResolvedModule resolvedModule, LoaderPool pool, ClassLoader parent) { super("Loader-" + resolvedModule.name(), parent); this.pool = pool; this.parent = parent; ModuleReference mref = resolvedModule.reference(); ModuleDescriptor descriptor = mref.descriptor(); String mn = descriptor.name(); this.nameToModule = Map.of(mn, mref); Map<String, LoadedModule> localPackageToModule = new HashMap<>(); LoadedModule lm = new LoadedModule(mref); descriptor.packages().forEach(pn -> localPackageToModule.put(pn, lm)); this.localPackageToModule = localPackageToModule; this.acc = AccessController.getContext(); }
/** * Creates a {@code Loader} that loads classes/resources from a collection * of modules. * * @throws IllegalArgumentException * If two or more modules have the same package */ public Loader(Collection<ResolvedModule> modules, ClassLoader parent) { super(parent); this.pool = null; this.parent = parent; Map<String, ModuleReference> nameToModule = new HashMap<>(); Map<String, LoadedModule> localPackageToModule = new HashMap<>(); for (ResolvedModule resolvedModule : modules) { ModuleReference mref = resolvedModule.reference(); ModuleDescriptor descriptor = mref.descriptor(); nameToModule.put(descriptor.name(), mref); descriptor.packages().forEach(pn -> { LoadedModule lm = new LoadedModule(mref); if (localPackageToModule.put(pn, lm) != null) throw new IllegalArgumentException("Package " + pn + " in more than one module"); }); } this.nameToModule = nameToModule; this.localPackageToModule = localPackageToModule; this.acc = AccessController.getContext(); }
/** * Test "provides p.S" where p is not exported to the module. */ @Test(expectedExceptions = { ResolutionException.class }) public void testServiceTypePackageNotExported2() { ModuleDescriptor descriptor1 = newBuilder("m1") .provides("p.S", List.of("q.T")) .build(); ModuleFinder finder = ModuleUtils.finderOf(descriptor1); // m1 does not read a module that exports p resolve(finder, "m1"); }
/** * Test layers with a qualified export. The module exporting the package * reads the target module in the parent layer (due to requires transitive). * * - Configuration/layer1: m1, m2 { requires transitive m1; } * - Configuration/layer2: m1, m3 { requires m2; exports p to m1; } */ public void testQualifiedExports6() { // create layer1 with m1 and m2 ModuleDescriptor descriptor1 = newBuilder("m1").build(); ModuleDescriptor descriptor2 = newBuilder("m2") .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") .build(); ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); Configuration cf1 = resolve(finder1, "m2"); ClassLoader loader1 = new ClassLoader() { }; ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> loader1); assertTrue(layer1.modules().size() == 2); // create layer2 with m1 and m3 ModuleDescriptor descriptor3 = newBuilder("m3") .requires("m2") .exports("p", Set.of("m1")) .build(); ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3); Configuration cf2 = resolve(cf1, finder2, "m1", "m3"); ClassLoader loader2 = new ClassLoader() { }; ModuleLayer layer2 = layer1.defineModules(cf2, mn -> loader2); assertTrue(layer2.modules().size() == 2); Module m1_v1 = layer1.findModule("m1").get(); Module m2 = layer1.findModule("m2").get(); Module m1_v2 = layer2.findModule("m1").get(); Module m3 = layer2.findModule("m3").get(); assertTrue(m3.canRead(m1_v1)); assertFalse(m3.canRead(m1_v2)); assertFalse(m3.isExported("p")); assertTrue(m3.isExported("p", m1_v1)); assertFalse(m3.isExported("p", m1_v2)); assertFalse(m3.isExported("p", m2)); }
private static String parseVersion(ModuleDescriptor.Version v) { return Runtime.Version.parse(v.toString()) .version() .stream() .map(Object::toString) .collect(Collectors.joining(".")); }
public void testBasic() throws Exception { ModuleDescriptor descriptor = ModuleDescriptor.newModule("m") .exports("p") .exports("q") .packages(Set.of("p.internal")) .build(); URI uri = URI.create("module:/m"); ModuleReference mref = newModuleReference(descriptor, uri); assertTrue(mref.descriptor().equals(descriptor)); assertTrue(mref.location().get().equals(uri)); }
@Test(dataProvider = "illegalModuleNames", expectedExceptions = InvalidModuleDescriptorException.class) public void testIllegalOpens(String mn, String ignore) throws Exception { ModuleDescriptor md = newBuilder("m") .requires("java.base") .opens("p", Set.of(mn)) .build(); ByteBuffer bb = toBuffer(md); ModuleDescriptor.read(bb); // throws InvalidModuleDescriptorException }
static ModuleDescriptor getModuleDescriptor(Path jar) { ClassLoader cl = ClassLoader.getSystemClassLoader(); try (JarFile jf = new JarFile(jar.toFile())) { JarEntry entry = jf.getJarEntry("module-info.class"); try (InputStream in = jf.getInputStream(entry)) { return ModuleDescriptor.read(in); } } catch (IOException ioe) { throw new UncheckedIOException(ioe); } }
/** * 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)); }
public void testVersion2() { String vs = "1.0"; Version v1 = ModuleDescriptor.newModule("foo") .version(vs) .build() .version() .get(); Version v2 = Version.parse(vs); assertEquals(v1, v2); }
@Override public Optional<ModuleDescriptor> read(String name) throws UncheckedIOException { if (!name.endsWith(".java")) { return Optional.empty(); } return ModuleHelper.sourceModuleDescriptor(Paths.get(name)); }
@Test(expectedExceptions = InvalidModuleDescriptorException.class) public void testReadOfJavaBaseWithRequires() { ModuleDescriptor descriptor = ModuleDescriptor.newModule("java.base") .requires("other") .build(); ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor); ModuleDescriptor.read(bb); }
/** * Returns a byte array containing the given module-info.class plus any * extended attributes. * * If --module-version, --main-class, or other options were provided * then the corresponding class file attributes are added to the * module-info here. */ private byte[] extendedInfoBytes(ModuleDescriptor md, byte[] miBytes, Set<String> packages) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream is = new ByteArrayInputStream(miBytes); ModuleInfoExtender extender = ModuleInfoExtender.newExtender(is); // Add (or replace) the Packages attribute extender.packages(packages); // --main-class if (ename != null) extender.mainClass(ename); // --module-version if (moduleVersion != null) extender.version(moduleVersion); // --hash-modules if (modulesToHash != null) { String mn = md.name(); Hasher hasher = new Hasher(md, fname); ModuleHashes moduleHashes = hasher.computeHashes(mn); if (moduleHashes != null) { extender.hashes(moduleHashes); } else { warn("warning: no module is recorded in hash in " + mn); } } if (moduleResolution.value() != 0) { extender.moduleResolution(moduleResolution); } extender.write(baos); return baos.toByteArray(); }
/** * 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"); }
@Test(expectedExceptions = InvalidModuleDescriptorException.class) public void testReadWithNoRequiresBase() { ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess() .newModuleBuilder("m1", false, Set.of()).requires("m2").build(); ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor); ModuleDescriptor.read(bb); }
/** * Returns true if target is an upgradeable module but not required * by the source module directly and indirectly. */ private static boolean accept(ModuleDescriptor source, String target) { if (HashedModules.contains(target)) return false; if (!ModuleFinder.ofSystem().find(target).isPresent()) return false; Configuration cf = Configuration.empty().resolve(ModuleFinder.of(), ModuleFinder.ofSystem(), Set.of(source.name())); return !cf.findModule(target).isPresent(); }
/** * Creates a module layer with one module that is defined to the given class * loader. * * @param parent the parent layer of the new module * @param descriptor the module descriptor for the newly created module * @param loader the class loader of the module * @return the new Module */ static Module createModuleTrusted(final ModuleLayer parent, final ModuleDescriptor descriptor, final ClassLoader loader) { final String mn = descriptor.name(); final ModuleReference mref = new ModuleReference(descriptor, null) { @Override public ModuleReader open() { throw new UnsupportedOperationException(); } }; final ModuleFinder finder = new ModuleFinder() { @Override public Optional<ModuleReference> find(final String name) { if (name.equals(mn)) { return Optional.of(mref); } else { return Optional.empty(); } } @Override public Set<ModuleReference> findAll() { return Set.of(mref); } }; final Configuration cf = parent.configuration() .resolve(finder, ModuleFinder.of(), Set.of(mn)); final PrivilegedAction<ModuleLayer> pa = () -> parent.defineModules(cf, name -> loader); final ModuleLayer layer = AccessController.doPrivileged(pa, GET_LOADER_ACC_CTXT); final Module m = layer.findModule(mn).get(); assert m.getLayer() == layer; return m; }
ModuleDescriptorBuilder(ModuleDescriptor md, Set<String> packages, int index) { if (md.isAutomatic()) { throw new InternalError("linking automatic module is not supported"); } this.md = md; this.packages = packages; this.index = index; }
private ModuleReference newModuleReference(ModuleDescriptor descriptor, URI uri) { return new ModuleReference(descriptor, uri) { @Override public ModuleReader open() { throw new UnsupportedOperationException(); } }; }
/** * Basic test of a multi-release JAR. */ public void testBasic() throws Exception { String name = "m1"; ModuleDescriptor descriptor = ModuleDescriptor.newModule(name) .requires("java.base") .build(); Path jar = new JarBuilder(name) .moduleInfo("module-info.class", descriptor) .resource("p/Main.class") .resource("p/Helper.class") .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(); // check module packages descriptor = mref.descriptor(); Set<String> packages = descriptor.packages(); assertTrue(packages.contains("p")); if (MULTI_RELEASE) { assertTrue(packages.size() == 2); assertTrue(packages.contains("p.internal")); } else { assertTrue(packages.size() == 1); } }
@Test(dataProvider = "invalidNames", expectedExceptions = IllegalArgumentException.class ) public void testPackagesWithBadName(String pn, String ignore) { Set<String> pkgs = new HashSet<>(); // allows nulls pkgs.add(pn); ModuleDescriptor.newModule("foo").packages(pkgs); }
public void testNewModuleToBuildOpenModule() { Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.OPEN); ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build(); assertTrue(descriptor.modifiers().equals(ms)); assertTrue(descriptor.isOpen()); ms = Set.of(ModuleDescriptor.Modifier.OPEN, ModuleDescriptor.Modifier.SYNTHETIC); descriptor = ModuleDescriptor.newModule("foo", ms).build(); assertTrue(descriptor.modifiers().equals(ms)); assertTrue(descriptor.isOpen()); }
/** * 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); }