1 /* 2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.File; 25 import java.io.IOException; 26 import java.nio.file.Files; 27 import java.nio.file.Path; 28 import java.nio.file.Paths; 29 import java.util.Arrays; 30 import java.util.Set; 31 import java.util.spi.ToolProvider; 32 import java.util.stream.Collectors; 33 import java.util.stream.Stream; 34 35 import jdk.test.lib.compiler.CompilerUtils; 36 import jdk.test.lib.util.FileUtils; 37 38 import static jdk.testlibrary.ProcessTools.*; 39 40 import org.testng.annotations.BeforeTest; 41 import org.testng.annotations.Test; 42 import static org.testng.Assert.*; 43 44 /** 45 * @test 46 * @bug 8142968 8173381 8174740 47 * @library /lib/testlibrary /test/lib 48 * @modules jdk.compiler jdk.jlink 49 * @modules java.base/jdk.internal.module 50 * @modules java.base/jdk.internal.org.objectweb.asm 51 * @build ModuleTargetHelper UserModuleTest jdk.test.lib.compiler.CompilerUtils jdk.testlibrary.ProcessTools 52 * @run testng UserModuleTest 53 */ 54 55 public class UserModuleTest { 56 private static final String JAVA_HOME = System.getProperty("java.home"); 57 private static final String TEST_SRC = System.getProperty("test.src"); 58 59 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 60 private static final Path MODS_DIR = Paths.get("mods"); 61 private static final Path JMODS_DIR = Paths.get("jmods"); 62 63 private static final Path IMAGE = Paths.get("image"); 64 private static final String MAIN_MID = "m1/p1.Main"; 65 66 // the names of the modules in this test 67 private static String[] modules = new String[] {"m1", "m2", "m3", "m4", "m5"}; 68 69 70 private static boolean hasJmods() { 71 if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) { 72 System.err.println("Test skipped. NO jmods directory"); 73 return false; 74 } 75 return true; 76 } 77 78 /* 79 * Compiles all modules used by the test 80 */ 81 @BeforeTest 82 public void compileAll() throws Throwable { 83 if (!hasJmods()) return; 84 85 for (String mn : modules) { 86 Path msrc = SRC_DIR.resolve(mn); 87 assertTrue(CompilerUtils.compile(msrc, MODS_DIR, 88 "--module-source-path", SRC_DIR.toString(), 89 "--add-exports", "java.base/jdk.internal.module=" + mn, 90 "--add-exports", "java.base/jdk.internal.org.objectweb.asm=" + mn)); 91 } 92 93 if (Files.exists(IMAGE)) { 94 FileUtils.deleteFileTreeUnchecked(IMAGE); 95 } 96 97 createImage(IMAGE, "m1", "m3"); 98 99 createJmods("m1", "m4"); 100 } 101 102 /* 103 * Test the image created when linking with a module with 104 * no Packages attribute 105 */ 106 @Test 107 public void testPackagesAttribute() throws Throwable { 108 if (!hasJmods()) return; 109 110 Path java = IMAGE.resolve("bin").resolve("java"); 111 assertTrue(executeProcess(java.toString(), 112 "--add-exports", "java.base/jdk.internal.module=m1,m4", 113 "--add-exports", "java.base/jdk.internal.org.objectweb.asm=m1,m4", 114 "-m", MAIN_MID) 115 .outputTo(System.out) 116 .errorTo(System.out) 117 .getExitValue() == 0); 118 } 119 120 /* 121 * Test the image created when linking with an open module 122 */ 123 @Test 124 public void testOpenModule() throws Throwable { 125 if (!hasJmods()) return; 126 127 Path java = IMAGE.resolve("bin").resolve("java"); 128 assertTrue(executeProcess(java.toString(), "-m", "m3/p3.Main") 129 .outputTo(System.out) 130 .errorTo(System.out) 131 .getExitValue() == 0); 132 } 133 134 /* 135 * Disable the fast loading of system modules. 136 * Parsing module-info.class 137 */ 138 @Test 139 public void disableSystemModules() throws Throwable { 140 if (!hasJmods()) return; 141 142 Path java = IMAGE.resolve("bin").resolve("java"); 143 assertTrue(executeProcess(java.toString(), 144 "--add-exports", "java.base/jdk.internal.module=m1,m4", 145 "--add-exports", "java.base/jdk.internal.org.objectweb.asm=m1,m4", 146 "-Djdk.system.module.finder.disabledFastPath", 147 "-m", MAIN_MID) 148 .outputTo(System.out) 149 .errorTo(System.out) 150 .getExitValue() == 0); 151 } 152 153 /* 154 * Test the optimization that deduplicates Set<String> on targets of exports, 155 * uses, provides. 156 */ 157 @Test 158 public void testDedupSet() throws Throwable { 159 if (!hasJmods()) return; 160 161 Path dir = Paths.get("dedupSetTest"); 162 createImage(dir, "m1", "m2", "m3", "m4"); 163 Path java = dir.resolve("bin").resolve("java"); 164 assertTrue(executeProcess(java.toString(), 165 "--add-exports", "java.base/jdk.internal.module=m1,m4", 166 "--add-exports", "java.base/jdk.internal.org.objectweb.asm=m1,m4", 167 "-m", MAIN_MID) 168 .outputTo(System.out) 169 .errorTo(System.out) 170 .getExitValue() == 0); 171 } 172 173 @Test 174 public void testRequiresStatic() throws Throwable { 175 if (!hasJmods()) return; 176 177 Path dir = Paths.get("requiresStatic"); 178 createImage(dir, "m5"); 179 Path java = dir.resolve("bin").resolve("java"); 180 assertTrue(executeProcess(java.toString(), "-m", "m5/p5.Main") 181 .outputTo(System.out) 182 .errorTo(System.out) 183 .getExitValue() == 0); 184 185 // run with m3 present 186 assertTrue(executeProcess(java.toString(), 187 "--module-path", MODS_DIR.toString(), 188 "--add-modules", "m3", 189 "-m", "m5/p5.Main") 190 .outputTo(System.out) 191 .errorTo(System.out) 192 .getExitValue() == 0); 193 } 194 195 @Test 196 public void testRequiresStatic2() throws Throwable { 197 if (!hasJmods()) return; 198 199 Path dir = Paths.get("requiresStatic2"); 200 createImage(dir, "m3", "m5"); 201 202 Path java = dir.resolve("bin").resolve("java"); 203 assertTrue(executeProcess(java.toString(), "-m", "m5/p5.Main") 204 .outputTo(System.out) 205 .errorTo(System.out) 206 .getExitValue() == 0); 207 208 // boot layer with m3 and m5 209 assertTrue(executeProcess(java.toString(), 210 "--add-modules", "m3", 211 "-m", "m5/p5.Main") 212 .outputTo(System.out) 213 .errorTo(System.out) 214 .getExitValue() == 0); 215 } 216 217 private void createJmods(String... modules) throws IOException { 218 ModuleTargetHelper.ModuleTarget mt = ModuleTargetHelper.getJavaBaseTarget(); 219 if (mt == null) { 220 throw new RuntimeException("ModuleTarget is missing for java.base"); 221 } 222 223 String[] values = mt.targetPlatform().split("-"); 224 String osName = values[0]; 225 String osArch = values[1]; 226 227 // create JMOD files 228 Files.createDirectories(JMODS_DIR); 229 Stream.of(modules).forEach(mn -> 230 assertTrue(jmod("create", 231 "--class-path", MODS_DIR.resolve(mn).toString(), 232 "--target-platform", mt.targetPlatform(), 233 "--main-class", mn.replace('m', 'p') + ".Main", 234 JMODS_DIR.resolve(mn + ".jmod").toString()) == 0) 235 ); 236 } 237 238 239 /** 240 * Verify the module descriptor if package p4.dummy is excluded at link time. 241 */ 242 @Test 243 public void testModulePackagesAttribute() throws Throwable { 244 if (!hasJmods()) return; 245 246 // create an image using JMOD files 247 Path dir = Paths.get("packagesTest"); 248 String mp = Paths.get(JAVA_HOME, "jmods").toString() + 249 File.pathSeparator + JMODS_DIR.toString(); 250 251 Set<String> modules = Set.of("m1", "m4"); 252 assertTrue(JLINK_TOOL.run(System.out, System.out, 253 "--output", dir.toString(), 254 "--exclude-resources", "m4/p4/dummy/*", 255 "--add-modules", modules.stream().collect(Collectors.joining(",")), 256 "--module-path", mp) == 0); 257 258 // verify ModuleDescriptor 259 Path java = dir.resolve("bin").resolve("java"); 260 assertTrue(executeProcess(java.toString(), 261 "--add-exports", "java.base/jdk.internal.module=m1,m4", 262 "--add-exports", "java.base/jdk.internal.org.objectweb.asm=m1,m4", 263 "--add-modules=m1", "-m", "m4") 264 .outputTo(System.out) 265 .errorTo(System.out) 266 .getExitValue() == 0); 267 } 268 269 /** 270 * Verify the plugin to retain ModuleTarget attribute 271 */ 272 @Test 273 public void testRetainModuleTarget() throws Throwable { 274 if (!hasJmods()) return; 275 276 // create an image using JMOD files 277 Path dir = Paths.get("retainModuleTargetTest"); 278 String mp = Paths.get(JAVA_HOME, "jmods").toString() + 279 File.pathSeparator + JMODS_DIR.toString(); 280 281 Set<String> modules = Set.of("m1", "m4"); 282 assertTrue(JLINK_TOOL.run(System.out, System.out, 283 "--output", dir.toString(), 284 "--system-modules", "retainModuleTarget", 285 "--exclude-resources", "m4/p4/dummy/*", 286 "--add-modules", modules.stream().collect(Collectors.joining(",")), 287 "--module-path", mp) == 0); 288 289 // verify ModuleDescriptor 290 Path java = dir.resolve("bin").resolve("java"); 291 assertTrue(executeProcess(java.toString(), 292 "--add-exports", "java.base/jdk.internal.module=m1,m4", 293 "--add-exports", "java.base/jdk.internal.org.objectweb.asm=m1,m4", 294 "--add-modules=m1", "-m", "m4", "retainModuleTarget") 295 .outputTo(System.out) 296 .errorTo(System.out) 297 .getExitValue() == 0); 298 } 299 300 static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") 301 .orElseThrow(() -> 302 new RuntimeException("jlink tool not found") 303 ); 304 305 static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod") 306 .orElseThrow(() -> 307 new RuntimeException("jmod tool not found") 308 ); 309 310 static final String MODULE_PATH = Paths.get(JAVA_HOME, "jmods").toString() 311 + File.pathSeparator + MODS_DIR.toString(); 312 313 private void createImage(Path outputDir, String... modules) throws Throwable { 314 assertTrue(JLINK_TOOL.run(System.out, System.out, 315 "--output", outputDir.toString(), 316 "--add-modules", Arrays.stream(modules).collect(Collectors.joining(",")), 317 "--module-path", MODULE_PATH) == 0); 318 } 319 320 private static int jmod(String... options) { 321 System.out.println("jmod " + Arrays.asList(options)); 322 return JMOD_TOOL.run(System.out, System.out, options); 323 } 324 }