/* * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 8211825 * @modules jdk.compiler * @library /test/lib * @build jdk.test.lib.compiler.CompilerUtils jdk.test.lib.util.JarUtils * @run testng/othervm AutomaticModulesTest * @summary Tests automatic modules in module layers */ import java.nio.file.Files; import java.nio.file.Path; import java.lang.ModuleLayer.Controller; import java.lang.module.*; import java.lang.reflect.Method; import java.util.List; import java.util.Set; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.util.JarUtils; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import static org.testng.Assert.*; /** * This test uses two modules: * m requires alib and has an entry point p.Main * alib is an automatic module */ @Test public class AutomaticModulesTest { private static final String TEST_SRC = System.getProperty("test.src"); private static final Path CLASSES = Path.of("classes"); private static final Path LIB = Path.of("lib"); private static final Path MODS = Path.of("mods"); @BeforeTest public void setup() throws Exception { // javac -d classes src/alib/** // jar cf lib/alib.jar -C classes . Files.createDirectory(CLASSES); assertTrue(CompilerUtils.compile(Path.of(TEST_SRC, "src", "alib"), CLASSES)); JarUtils.createJarFile(LIB.resolve("alib.jar"), CLASSES); // javac -p lib -d mods/m - src/m/** Path src = Path.of(TEST_SRC, "src", "m"); Path output = Files.createDirectories(MODS.resolve("m")); assertTrue(CompilerUtils.compile(src, output, "-p", LIB.toString())); } /** * Create a module layer with modules m and alib mapped to the same class * loader. */ public void testOneLoader() throws Exception { Configuration cf = ModuleLayer.boot() .configuration() .resolve(ModuleFinder.of(), ModuleFinder.of(MODS, LIB), Set.of("m")); ResolvedModule m = cf.findModule("m").orElseThrow(); ResolvedModule alib = cf.findModule("alib").orElseThrow(); assertTrue(m.reads().contains(alib)); assertTrue(alib.reference().descriptor().isAutomatic()); ModuleLayer bootLayer = ModuleLayer.boot(); ClassLoader scl = ClassLoader.getSystemClassLoader(); Controller controller = ModuleLayer.defineModulesWithOneLoader(cf, List.of(bootLayer), scl); invokeMain(controller, "m/p.Main"); } /** * Create a module layer with modules m and alib mapped to different class * loaders. This will test that L(m) delegates to L(alib) in the same layer. */ public void testManyLoaders() throws Exception { Configuration cf = ModuleLayer.boot() .configuration() .resolve(ModuleFinder.of(), ModuleFinder.of(MODS, LIB), Set.of("m")); ResolvedModule m = cf.findModule("m").orElseThrow(); ResolvedModule alib = cf.findModule("alib").orElseThrow(); assertTrue(m.reads().contains(alib)); assertTrue(alib.reference().descriptor().isAutomatic()); ModuleLayer bootLayer = ModuleLayer.boot(); ClassLoader scl = ClassLoader.getSystemClassLoader(); Controller controller = ModuleLayer.defineModulesWithManyLoaders(cf, List.of(bootLayer), scl); invokeMain(controller, "m/p.Main"); } /** * Create a module layer with alib and another module layer with m. * This will test that L(m) delegates to L(alib) in a parent layer. */ public void testAutomaticModuleInParent() throws Exception { ModuleLayer bootLayer = ModuleLayer.boot(); ClassLoader scl = ClassLoader.getSystemClassLoader(); // configuration/layer containing alib Configuration cf1 = bootLayer .configuration() .resolve(ModuleFinder.of(), ModuleFinder.of(LIB), Set.of("alib")); ModuleLayer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl); // configuration/layer containing m Configuration cf2 = cf1.resolve(ModuleFinder.of(), ModuleFinder.of(MODS), Set.of("m")); Controller controller = ModuleLayer.defineModulesWithOneLoader(cf2, List.of(layer1), scl); invokeMain(controller, "m/p.Main"); } /** * Invokes the main method of the given entry point (module-name/class-name) */ private void invokeMain(Controller controller, String entry) throws Exception { String[] s = entry.split("/"); String moduleName = s[0]; String className = s[1]; int pos = className.lastIndexOf('.'); String packageName = className.substring(0, pos); ModuleLayer layer = controller.layer(); Module module = layer.findModule(moduleName).orElseThrow(); controller.addExports(module, packageName, this.getClass().getModule()); ClassLoader loader = layer.findLoader(moduleName); Class c = loader.loadClass(className); Method m = c.getMethod("main", String[].class); m.invoke(null, (Object)new String[0]); } }