Path: blob/master/test/jdk/java/lang/ModuleLayer/LayerAndLoadersTest.java
41149 views
/*1* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @library /test/lib26* @modules jdk.compiler27* @build LayerAndLoadersTest28* jdk.test.lib.compiler.CompilerUtils29* jdk.test.lib.util.ModuleUtils30* @run testng LayerAndLoadersTest31* @summary Tests for java.lang.ModuleLayer@defineModulesWithXXX methods32*/3334import java.io.IOException;35import java.io.InputStream;36import java.io.UncheckedIOException;37import java.lang.module.Configuration;38import java.lang.module.ModuleDescriptor;39import java.lang.module.ModuleFinder;40import java.lang.module.ModuleReference;41import java.lang.module.ResolvedModule;42import java.lang.reflect.Method;43import java.net.URL;44import java.nio.file.Path;45import java.nio.file.Paths;46import java.util.ArrayList;47import java.util.Enumeration;48import java.util.HashMap;49import java.util.Iterator;50import java.util.List;51import java.util.Map;52import java.util.Optional;53import java.util.ServiceLoader;54import java.util.Set;55import java.util.stream.Collectors;5657import jdk.test.lib.compiler.CompilerUtils;58import jdk.test.lib.util.ModuleUtils;5960import org.testng.annotations.BeforeTest;61import org.testng.annotations.Test;62import static org.testng.Assert.*;6364@Test65public class LayerAndLoadersTest {6667private static final String TEST_SRC = System.getProperty("test.src");6869private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");70private static final Path MODS_DIR = Paths.get("mods");7172@BeforeTest73public void setup() throws Exception {74// javac -d mods --module-source-path src src/**75assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR,76"--module-source-path", SRC_DIR.toString()));77}787980/**81* Basic test of ModuleLayer.defineModulesWithOneLoader82*83* Test scenario:84* m1 requires m2 and m385*/86public void testWithOneLoader() throws Exception {87Configuration cf = resolve("m1");8889ClassLoader scl = ClassLoader.getSystemClassLoader();9091ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);9293checkLayer(layer, "m1", "m2", "m3");9495ClassLoader cl1 = layer.findLoader("m1");96ClassLoader cl2 = layer.findLoader("m2");97ClassLoader cl3 = layer.findLoader("m3");9899assertTrue(cl1.getParent() == scl);100assertTrue(cl2 == cl1);101assertTrue(cl3 == cl1);102103invoke(layer, "m1", "p.Main");104}105106107/**108* Basic test of ModuleLayer.defineModulesWithManyLoaders109*110* Test scenario:111* m1 requires m2 and m3112*/113public void testWithManyLoaders() throws Exception {114Configuration cf = resolve("m1");115116ClassLoader scl = ClassLoader.getSystemClassLoader();117118ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);119120checkLayer(layer, "m1", "m2", "m3");121122ClassLoader cl1 = layer.findLoader("m1");123ClassLoader cl2 = layer.findLoader("m2");124ClassLoader cl3 = layer.findLoader("m3");125126assertTrue(cl1.getParent() == scl);127assertTrue(cl2.getParent() == scl);128assertTrue(cl3.getParent() == scl);129assertTrue(cl2 != cl1);130assertTrue(cl3 != cl1);131assertTrue(cl3 != cl2);132133invoke(layer, "m1", "p.Main");134}135136137/**138* Basic test of ModuleLayer.defineModulesWithOneLoader where one of the139* modules is a service provider module.140*141* Test scenario:142* m1 requires m2 and m3143* m1 uses S144* m4 provides S with ...145*/146public void testServicesWithOneLoader() throws Exception {147Configuration cf = resolveAndBind("m1");148149ClassLoader scl = ClassLoader.getSystemClassLoader();150151ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);152153checkLayer(layer, "m1", "m2", "m3", "m4");154155ClassLoader cl1 = layer.findLoader("m1");156ClassLoader cl2 = layer.findLoader("m2");157ClassLoader cl3 = layer.findLoader("m3");158ClassLoader cl4 = layer.findLoader("m4");159160assertTrue(cl1.getParent() == scl);161assertTrue(cl2 == cl1);162assertTrue(cl3 == cl1);163assertTrue(cl4 == cl1);164165Class<?> serviceType = cl1.loadClass("p.Service");166assertTrue(serviceType.getClassLoader() == cl1);167168Iterator<?> iter = ServiceLoader.load(serviceType, cl1).iterator();169Object provider = iter.next();170assertTrue(serviceType.isInstance(provider));171assertTrue(provider.getClass().getClassLoader() == cl1);172assertFalse(iter.hasNext());173}174175176/**177* Basic test of ModuleLayer.defineModulesWithManyLoaders where one of the178* modules is a service provider module.179*180* Test scenario:181* m1 requires m2 and m3182* m1 uses S183* m4 provides S with ...184*/185public void testServicesWithManyLoaders() throws Exception {186Configuration cf = resolveAndBind("m1");187188ClassLoader scl = ClassLoader.getSystemClassLoader();189190ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);191192checkLayer(layer, "m1", "m2", "m3", "m4");193194ClassLoader cl1 = layer.findLoader("m1");195ClassLoader cl2 = layer.findLoader("m2");196ClassLoader cl3 = layer.findLoader("m3");197ClassLoader cl4 = layer.findLoader("m4");198199assertTrue(cl1.getParent() == scl);200assertTrue(cl2.getParent() == scl);201assertTrue(cl3.getParent() == scl);202assertTrue(cl4.getParent() == scl);203assertTrue(cl2 != cl1);204assertTrue(cl3 != cl1);205assertTrue(cl3 != cl2);206assertTrue(cl4 != cl1);207assertTrue(cl4 != cl2);208assertTrue(cl4 != cl3);209210Class<?> serviceType = cl1.loadClass("p.Service");211assertTrue(serviceType.getClassLoader() == cl1);212213// Test that the service provider can be located via any of214// the class loaders in the layer215for (Module m : layer.modules()) {216ClassLoader loader = m.getClassLoader();217Iterator<?> iter = ServiceLoader.load(serviceType, loader).iterator();218Object provider = iter.next();219assertTrue(serviceType.isInstance(provider));220assertTrue(provider.getClass().getClassLoader() == cl4);221assertFalse(iter.hasNext());222}223}224225226/**227* Tests that the class loaders created by defineModulesWithXXX delegate228* to the given parent class loader.229*/230public void testDelegationToParent() throws Exception {231Configuration cf = resolve("m1");232233ClassLoader parent = this.getClass().getClassLoader();234String cn = this.getClass().getName();235236// one loader237ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent);238testLoad(layer, cn);239240// one loader with boot loader as parent241layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, null);242testLoadFail(layer, cn);243244// many loaders245layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, parent);246testLoad(layer, cn);247248// many loader with boot loader as parent249layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null);250testLoadFail(layer, cn);251}252253254/**255* Test defineModulesWithXXX when modules that have overlapping packages.256*257* Test scenario:258* m1 exports p259* m2 exports p260*/261public void testOverlappingPackages() {262ModuleDescriptor descriptor1263= ModuleDescriptor.newModule("m1").exports("p").build();264265ModuleDescriptor descriptor2266= ModuleDescriptor.newModule("m2").exports("p").build();267268ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);269270Configuration cf = ModuleLayer.boot()271.configuration()272.resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));273274// cannot define both module m1 and m2 to the same class loader275try {276ModuleLayer.boot().defineModulesWithOneLoader(cf, null);277assertTrue(false);278} catch (LayerInstantiationException expected) { }279280// should be okay to have one module per class loader281ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null);282checkLayer(layer, "m1", "m2");283}284285286/**287* Test ModuleLayer.defineModulesWithXXX with split delegation.288*289* Test scenario:290* layer1: m1 exports p, m2 exports p291* layer2: m3 reads m1, m4 reads m2292*/293public void testSplitDelegation() {294ModuleDescriptor descriptor1295= ModuleDescriptor.newModule("m1").exports("p").build();296297ModuleDescriptor descriptor2298= ModuleDescriptor.newModule("m2").exports("p").build();299300ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);301302Configuration cf1 = ModuleLayer.boot()303.configuration()304.resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));305306ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);307checkLayer(layer1, "m1", "m2");308309ModuleDescriptor descriptor3310= ModuleDescriptor.newModule("m3").requires("m1").build();311312ModuleDescriptor descriptor4313= ModuleDescriptor.newModule("m4").requires("m2").build();314315ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);316317Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(),318Set.of("m3", "m4"));319320// package p cannot be supplied by two class loaders321try {322layer1.defineModulesWithOneLoader(cf2, null);323assertTrue(false);324} catch (LayerInstantiationException expected) { }325326// no split delegation when modules have their own class loader327ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);328checkLayer(layer2, "m3", "m4");329}330331332/**333* Test ModuleLayer.defineModulesWithXXX when the modules that override same334* named modules in the parent layer.335*336* Test scenario:337* layer1: m1, m2, m3 => same loader338* layer2: m1, m2, m4 => same loader339*/340public void testOverriding1() throws Exception {341Configuration cf1 = resolve("m1");342343ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);344checkLayer(layer1, "m1", "m2", "m3");345346ModuleFinder finder = ModuleFinder.of(MODS_DIR);347Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),348Set.of("m1"));349350ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);351checkLayer(layer2, "m1", "m2", "m3");352invoke(layer1, "m1", "p.Main");353354ClassLoader loader1 = layer1.findLoader("m1");355ClassLoader loader2 = layer1.findLoader("m2");356ClassLoader loader3 = layer1.findLoader("m3");357358ClassLoader loader4 = layer2.findLoader("m1");359ClassLoader loader5 = layer2.findLoader("m2");360ClassLoader loader6 = layer2.findLoader("m3");361362assertTrue(loader1 == loader2);363assertTrue(loader1 == loader3);364365assertTrue(loader4 == loader5);366assertTrue(loader4 == loader6);367assertTrue(loader4 != loader1);368369assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);370assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);371assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);372373assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);374assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4);375assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4);376}377378379/**380* Test Layer defineModulesWithXXX when the modules that override same381* named modules in the parent layer.382*383* Test scenario:384* layer1: m1, m2, m3 => loader pool385* layer2: m1, m2, m3 => loader pool386*/387public void testOverriding2() throws Exception {388Configuration cf1 = resolve("m1");389390ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);391checkLayer(layer1, "m1", "m2", "m3");392393ModuleFinder finder = ModuleFinder.of(MODS_DIR);394Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),395Set.of("m1"));396397ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);398checkLayer(layer2, "m1", "m2", "m3");399invoke(layer1, "m1", "p.Main");400401ClassLoader loader1 = layer1.findLoader("m1");402ClassLoader loader2 = layer1.findLoader("m2");403ClassLoader loader3 = layer1.findLoader("m3");404405ClassLoader loader4 = layer2.findLoader("m1");406ClassLoader loader5 = layer2.findLoader("m2");407ClassLoader loader6 = layer2.findLoader("m3");408409assertTrue(loader4 != loader1);410assertTrue(loader5 != loader2);411assertTrue(loader6 != loader3);412413assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);414assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);415assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3);416417// p.Main is not visible via loader2418try {419loader2.loadClass("p.Main");420assertTrue(false);421} catch (ClassNotFoundException expected) { }422423// w.Hello is not visible via loader2424try {425loader2.loadClass("w.Hello");426assertTrue(false);427} catch (ClassNotFoundException expected) { }428429// p.Main is not visible via loader3430try {431loader3.loadClass("p.Main");432assertTrue(false);433} catch (ClassNotFoundException expected) { }434435// q.Hello is not visible via loader3436try {437loader3.loadClass("q.Hello");438assertTrue(false);439} catch (ClassNotFoundException expected) { }440441442assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);443assertTrue(loader5.loadClass("q.Hello").getClassLoader() == loader5);444assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);445446// p.Main is not visible via loader5447try {448loader5.loadClass("p.Main");449assertTrue(false);450} catch (ClassNotFoundException expected) { }451452// w.Hello is not visible via loader5453try {454loader5.loadClass("w.Hello");455assertTrue(false);456} catch (ClassNotFoundException expected) { }457458// p.Main is not visible via loader6459try {460loader6.loadClass("p.Main");461assertTrue(false);462} catch (ClassNotFoundException expected) { }463464// q.Hello is not visible via loader6465try {466loader6.loadClass("q.Hello");467assertTrue(false);468} catch (ClassNotFoundException expected) { }469}470471472/**473* Test ModuleLayer.defineModulesWithXXX when the modules that override same474* named modules in the parent layer.475*476* layer1: m1, m2, m3 => same loader477* layer2: m1, m3 => same loader478*/479public void testOverriding3() throws Exception {480Configuration cf1 = resolve("m1");481482ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);483checkLayer(layer1, "m1", "m2", "m3");484485ModuleFinder finder = finderFor("m1", "m3");486487Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),488Set.of("m1"));489490ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, null);491checkLayer(layer2, "m1", "m3");492invoke(layer1, "m1", "p.Main");493494ClassLoader loader1 = layer1.findLoader("m1");495ClassLoader loader2 = layer2.findLoader("m1");496497assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);498assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);499assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);500501assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2);502assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1);503assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2);504}505506507/**508* Test Layer defineModulesWithXXX when the modules that override same509* named modules in the parent layer.510*511* layer1: m1, m2, m3 => loader pool512* layer2: m1, m3 => loader pool513*/514public void testOverriding4() throws Exception {515Configuration cf1 = resolve("m1");516517ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);518checkLayer(layer1, "m1", "m2", "m3");519520ModuleFinder finder = finderFor("m1", "m3");521522Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),523Set.of("m1"));524525ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);526checkLayer(layer2, "m1", "m3");527invoke(layer1, "m1", "p.Main");528529ClassLoader loader1 = layer1.findLoader("m1");530ClassLoader loader2 = layer1.findLoader("m2");531ClassLoader loader3 = layer1.findLoader("m3");532533ClassLoader loader4 = layer2.findLoader("m1");534ClassLoader loader5 = layer2.findLoader("m2");535ClassLoader loader6 = layer2.findLoader("m3");536537assertTrue(loader4 != loader1);538assertTrue(loader5 == loader2); // m2 not overridden539assertTrue(loader6 != loader3);540541assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);542assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);543assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3);544545assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader2);546547assertTrue(loader3.loadClass("w.Hello").getClassLoader() == loader3);548549assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);550assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader2);551assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader6);552553assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);554}555556/**557* Basic test for locating resources with a class loader created by558* defineModulesWithOneLoader.559*/560public void testResourcesWithOneLoader() throws Exception {561testResourcesWithOneLoader(ClassLoader.getSystemClassLoader());562testResourcesWithOneLoader(null);563}564565/**566* Test locating resources with the class loader created by567* defineModulesWithOneLoader. The class loader has the given class568* loader as its parent.569*/570void testResourcesWithOneLoader(ClassLoader parent) throws Exception {571Configuration cf = resolve("m1");572ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, parent);573574ClassLoader loader = layer.findLoader("m1");575assertNotNull(loader);576assertTrue(loader.getParent() == parent);577578// check that getResource and getResources are consistent579URL url1 = loader.getResource("module-info.class");580URL url2 = loader.getResources("module-info.class").nextElement();581assertEquals(url1.toURI(), url2.toURI());582583// use getResources to find module-info.class resources584Enumeration<URL> urls = loader.getResources("module-info.class");585List<String> list = readModuleNames(urls);586587// m1, m2, ... should be first (order not specified)588int count = cf.modules().size();589cf.modules().stream()590.map(ResolvedModule::name)591.forEach(mn -> assertTrue(list.indexOf(mn) < count));592593// java.base should be after m1, m2, ...594assertTrue(list.indexOf("java.base") >= count);595596// check resources(String)597List<String> list2 = loader.resources("module-info.class")598.map(this::readModuleName)599.collect(Collectors.toList());600assertEquals(list2, list);601602// check nulls603try {604loader.getResource(null);605assertTrue(false);606} catch (NullPointerException e) { }607try {608loader.getResources(null);609assertTrue(false);610} catch (NullPointerException e) { }611try {612loader.resources(null);613assertTrue(false);614} catch (NullPointerException e) { }615}616617/**618* Basic test for locating resources with class loaders created by619* defineModulesWithManyLoaders.620*/621public void testResourcesWithManyLoaders() throws Exception {622testResourcesWithManyLoaders(ClassLoader.getSystemClassLoader());623testResourcesWithManyLoaders(null);624}625626/**627* Test locating resources with class loaders created by628* defineModulesWithManyLoaders. The class loaders have the given class629* loader as their parent.630*/631void testResourcesWithManyLoaders(ClassLoader parent) throws Exception {632Configuration cf = resolve("m1");633ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, parent);634635for (Module m : layer.modules()) {636String name = m.getName();637ClassLoader loader = m.getClassLoader();638assertNotNull(loader);639assertTrue(loader.getParent() == parent);640641// getResource should find the module-info.class for the module642URL url = loader.getResource("module-info.class");643assertEquals(readModuleName(url), name);644645// list of modules names read from module-info.class646Enumeration<URL> urls = loader.getResources("module-info.class");647List<String> list = readModuleNames(urls);648649// module should be the first element650assertTrue(list.indexOf(name) == 0);651652// the module-info.class for the other modules in the layer653// should not be found654layer.modules().stream()655.map(Module::getName)656.filter(mn -> !mn.equals(name))657.forEach(mn -> assertTrue(list.indexOf(mn) < 0));658659// java.base cannot be the first element660assertTrue(list.indexOf("java.base") > 0);661662// check resources(String)663List<String> list2 = loader.resources("module-info.class")664.map(this::readModuleName)665.collect(Collectors.toList());666assertEquals(list2, list);667668// check nulls669try {670loader.getResource(null);671assertTrue(false);672} catch (NullPointerException e) { }673try {674loader.getResources(null);675assertTrue(false);676} catch (NullPointerException e) { }677try {678loader.resources(null);679assertTrue(false);680} catch (NullPointerException e) { }681}682}683684private List<String> readModuleNames(Enumeration<URL> e) {685List<String> list = new ArrayList<>();686while (e.hasMoreElements()) {687URL url = e.nextElement();688list.add(readModuleName(url));689}690return list;691}692693private String readModuleName(URL url) {694try (InputStream in = url.openStream()) {695ModuleDescriptor descriptor = ModuleDescriptor.read(in);696return descriptor.name();697} catch (IOException ioe) {698throw new UncheckedIOException(ioe);699}700}701702703// -- supporting methods --704705706/**707* Resolve the given modules, by name, and returns the resulting708* Configuration.709*/710private static Configuration resolve(String... roots) {711ModuleFinder finder = ModuleFinder.of(MODS_DIR);712return ModuleLayer.boot()713.configuration()714.resolve(finder, ModuleFinder.of(), Set.of(roots));715}716717/**718* Resolve the given modules, by name, and returns the resulting719* Configuration.720*/721private static Configuration resolveAndBind(String... roots) {722ModuleFinder finder = ModuleFinder.of(MODS_DIR);723return ModuleLayer.boot()724.configuration()725.resolveAndBind(finder, ModuleFinder.of(), Set.of(roots));726}727728729/**730* Invokes the static void main(String[]) method on the given class731* in the given module.732*/733private static void invoke(ModuleLayer layer, String mn, String mc) throws Exception {734ClassLoader loader = layer.findLoader(mn);735Class<?> c = loader.loadClass(mc);736Method mainMethod = c.getMethod("main", String[].class);737mainMethod.invoke(null, (Object)new String[0]);738}739740741/**742* Checks that the given layer contains exactly the expected modules743* (by name).744*/745private void checkLayer(ModuleLayer layer, String ... expected) {746Set<String> names = layer.modules().stream()747.map(Module::getName)748.collect(Collectors.toSet());749assertTrue(names.size() == expected.length);750for (String name : expected) {751assertTrue(names.contains(name));752}753}754755756/**757* Test that a class can be loaded via the class loader of all modules758* in the given layer.759*/760static void testLoad(ModuleLayer layer, String cn) throws Exception {761for (Module m : layer.modules()) {762ClassLoader l = m.getClassLoader();763l.loadClass(cn);764}765}766767768/**769* Test that a class cannot be loaded via any of the class loaders of770* the modules in the given layer.771*/772static void testLoadFail(ModuleLayer layer, String cn) throws Exception {773for (Module m : layer.modules()) {774ClassLoader l = m.getClassLoader();775try {776l.loadClass(cn);777assertTrue(false);778} catch (ClassNotFoundException expected) { }779}780}781782783/**784* Returns a ModuleFinder that only finds the given test modules785*/786static ModuleFinder finderFor(String... names) {787788ModuleFinder finder = ModuleFinder.of(MODS_DIR);789790Map<String, ModuleReference> mrefs = new HashMap<>();791for (String name : names) {792Optional<ModuleReference> omref = finder.find(name);793assert omref.isPresent();794mrefs.put(name, omref.get());795}796797return new ModuleFinder() {798@Override799public Optional<ModuleReference> find(String name) {800ModuleReference mref = mrefs.get(name);801return Optional.ofNullable(mref);802}803@Override804public Set<ModuleReference> findAll() {805return mrefs.values().stream().collect(Collectors.toSet());806}807};808}809810}811812813