1 /* 2 * Copyright (c) 2020, 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 25 /** 26 * @test 27 * @requires vm.cds 28 * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds 29 * @run driver OptimizeModuleHandlingTest 30 * @summary test module path changes for optimization of 31 * module handling. 32 * 33 */ 34 35 import java.io.File; 36 import java.nio.file.Files; 37 import java.nio.file.Path; 38 import java.nio.file.Paths; 39 40 import jdk.test.lib.process.OutputAnalyzer; 41 import jdk.test.lib.Platform; 42 43 public class OptimizeModuleHandlingTest { 44 45 private static final Path USER_DIR = Paths.get(System.getProperty("user.dir")); 46 47 private static final String TEST_SRC = System.getProperty("test.src"); 48 49 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 50 private static final Path MODS_DIR = Paths.get("mody"); 51 52 // the module name of the test module 53 private static final String MAIN_MODULE = "com.bars"; 54 private static final String TEST_MODULE = "com.foos"; 55 56 // the module main class 57 private static final String MAIN_CLASS = "com.bars.Main"; 58 private static final String TEST_CLASS = "com.foos.Test"; 59 60 private static String PATH_LIBS = "modylibs"; 61 private static Path libsDir = null; 62 private static Path mainJar = null; 63 private static Path testJar = null; 64 65 private static String CLASS_FOUND_MESSAGE = "com.foos.Test found"; 66 private static String CLASS_NOT_FOUND_MESSAGE = "java.lang.ClassNotFoundException: com.foos.Test"; 67 private static String OPTIMIZE_ENABLED = "Using optimized module handling"; 68 private static String OPTIMIZE_DISABLED = "use_optimized_module_handling disabled"; 69 70 private static String CP_SEPARATOR = Platform.isWindows() ? ";" : ":"; 71 72 public static void buildTestModule() throws Exception { 73 74 // javac -d mods/$TESTMODULE src/$TESTMODULE/** 75 JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE), 76 MODS_DIR.resolve(TEST_MODULE), 77 null); 78 79 // javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/** 80 JarBuilder.compileModule(SRC_DIR.resolve(MAIN_MODULE), 81 MODS_DIR.resolve(MAIN_MODULE), 82 MODS_DIR.toString()); 83 84 libsDir = Files.createTempDirectory(USER_DIR, PATH_LIBS); 85 mainJar = libsDir.resolve(MAIN_MODULE + ".jar"); 86 testJar = libsDir.resolve(TEST_MODULE + ".jar"); 87 88 // modylibs contains both modules com.foos.jar, com.bars.jar 89 // build com.foos.jar 90 String classes = MODS_DIR.resolve(TEST_MODULE).toString(); 91 JarBuilder.createModularJar(testJar.toString(), classes, TEST_CLASS); 92 93 // build com.bars.jar 94 classes = MODS_DIR.resolve(MAIN_MODULE).toString(); 95 JarBuilder.createModularJar(mainJar.toString(), classes, MAIN_CLASS); 96 System.out.println("mainJar = " + mainJar.toString()); 97 } 98 99 public static void main(String... args) throws Exception { 100 runWithModulePath(); 101 runWithJarPath(); 102 } 103 104 private static void tty(String... args) { 105 for (String s : args) { 106 System.out.print(s + " "); 107 } 108 System.out.print("\n"); 109 } 110 111 public static void runWithModulePath(String... extraRuntimeArgs) throws Exception { 112 // compile the modules and create the modular jar files 113 buildTestModule(); 114 String appClasses[] = {MAIN_CLASS, TEST_CLASS}; 115 // create an archive with the classes in the modules built in the 116 // previous step 117 OutputAnalyzer output = TestCommon.createArchive( 118 null, appClasses, 119 "--module-path", 120 libsDir.toString(), 121 "-m", MAIN_MODULE); 122 TestCommon.checkDump(output); 123 124 // following 1 - 4 test with CDS off 125 tty("1. run with CDS off"); 126 TestCommon.execOff( "-p", libsDir.toString(), 127 "-m", MAIN_MODULE) 128 .shouldHaveExitValue(0) 129 .shouldNotContain(OPTIMIZE_ENABLED) 130 .shouldContain(CLASS_FOUND_MESSAGE); 131 tty("2. run with CDS off, without module path"); 132 TestCommon.execOff("-cp", 133 mainJar.toString(), 134 MAIN_CLASS) 135 .shouldHaveExitValue(0) 136 .shouldContain(CLASS_NOT_FOUND_MESSAGE); 137 tty("3. run with CDS off, but with full jars in path"); 138 TestCommon.execOff( "-cp", mainJar.toString() + CP_SEPARATOR + testJar.toString(), 139 MAIN_CLASS) 140 .shouldHaveExitValue(0) 141 .shouldNotContain(OPTIMIZE_ENABLED) 142 .shouldContain(CLASS_FOUND_MESSAGE); 143 tty("4. run with CDS off, only main jar on path, but given moudle path"); 144 TestCommon.execOff( "-cp", mainJar.toString(), 145 "--module-path", libsDir.toString(), 146 "--add-modules", TEST_MODULE, 147 MAIN_CLASS) 148 .shouldHaveExitValue(0) 149 .shouldNotContain(OPTIMIZE_ENABLED) 150 .shouldContain(CLASS_FOUND_MESSAGE); 151 152 // Following 5 - 10 test woith CDS on 153 tty("5. run with CDS on, with module path"); 154 String prefix[] = {"-Djava.class.path=", "-Xlog:cds"}; 155 TestCommon.runWithModules(prefix, 156 null, // --upgrade-module-path 157 libsDir.toString(), // --module-path 158 MAIN_MODULE) // -m 159 .assertNormalExit(out -> { 160 out.shouldNotContain(OPTIMIZE_ENABLED) 161 .shouldContain(OPTIMIZE_DISABLED) 162 .shouldContain(CLASS_FOUND_MESSAGE); 163 }); 164 tty("6. run with CDS on, with module paths set correctly"); 165 TestCommon.run("-Xlog:cds", 166 "-p", libsDir.toString(), 167 "-m", MAIN_MODULE) 168 .assertNormalExit(out -> { 169 out.shouldContain(CLASS_FOUND_MESSAGE) 170 .shouldContain(OPTIMIZE_DISABLED) 171 .shouldNotContain(OPTIMIZE_ENABLED); 172 }); 173 tty("7. run with CDS on, with jar on path"); 174 TestCommon.run("-Xlog:cds", 175 "-cp", mainJar + CP_SEPARATOR + testJar, 176 MAIN_CLASS) 177 .assertNormalExit(out -> { 178 out.shouldContain(CLASS_FOUND_MESSAGE) 179 .shouldContain(OPTIMIZE_DISABLED) 180 .shouldNotContain(OPTIMIZE_ENABLED); 181 }); 182 183 tty("8. run with CDS on, with --module-path, with jar should fail"); 184 TestCommon.run("-Xlog:cds", 185 "-p", libsDir.toString(), 186 "-cp", mainJar.toString(), 187 MAIN_CLASS) 188 .assertNormalExit(out -> { 189 out.shouldContain(CLASS_NOT_FOUND_MESSAGE) 190 .shouldNotContain(OPTIMIZE_ENABLED); 191 }); 192 tty("9. run with CDS on, with com.foos on --module-path, with main jar on cp should pass"); 193 TestCommon.run("-Xlog:cds", 194 "--module-path", libsDir.toString(), 195 "--add-modules", TEST_MODULE, 196 "-cp", mainJar.toString(), 197 MAIN_CLASS) 198 .assertNormalExit(out -> { 199 out.shouldContain(CLASS_FOUND_MESSAGE) 200 .shouldNotContain(OPTIMIZE_ENABLED); 201 }); 202 tty("10. run with CDS on, --module-path, with -Xbootclasspath/a: ."); 203 TestCommon.run("-Xlog:cds", 204 "-Xbootclasspath/a:", ".", 205 "--module-path", libsDir.toString(), 206 MAIN_CLASS) 207 .assertAbnormalExit(out -> { 208 out.shouldNotContain(CLASS_FOUND_MESSAGE) 209 .shouldContain(OPTIMIZE_DISABLED) // mapping info 210 .shouldContain("shared class paths mismatch"); 211 }); 212 } 213 214 public static void runWithJarPath(String... extraRuntimeArgs) throws Exception { 215 // compile the modules and create the modular jar files 216 buildTestModule(); 217 String appClasses[] = {MAIN_CLASS, TEST_CLASS}; 218 // create an archive with the classes in the modules built in the 219 // previous step 220 OutputAnalyzer output = TestCommon.createArchive( 221 null, appClasses, 222 "-cp", 223 testJar.toString() + CP_SEPARATOR + mainJar.toString(), 224 MAIN_CLASS); 225 TestCommon.checkDump(output); 226 227 // tests 1 - 4 test with CDS off are same as with module archive. 228 tty("tests 1 - 4 test with CDS off are same as with module archive, skipped"); 229 230 // Following 5 - 10 test with CDS on 231 tty("5. run with CDS on, with module path"); 232 String prefix[] = {"-Djava.class.path=", "-Xlog:cds"}; 233 TestCommon.runWithModules(prefix, 234 null, // --upgrade-module-path 235 libsDir.toString(), // --module-path 236 MAIN_MODULE) // -m 237 .assertAbnormalExit(out -> { 238 out.shouldNotContain(OPTIMIZE_ENABLED) 239 .shouldNotContain(CLASS_FOUND_MESSAGE); 240 }); 241 tty("6. run with CDS on, with module paths set correctly"); 242 TestCommon.run("-Xlog:cds", 243 "-p", libsDir.toString(), 244 "-m", MAIN_MODULE) 245 .assertAbnormalExit(out -> { 246 out.shouldNotContain(CLASS_FOUND_MESSAGE) 247 .shouldNotContain(OPTIMIZE_ENABLED); 248 }); 249 tty("7. run with CDS on, with jar on path"); 250 TestCommon.run("-Xlog:cds", 251 "-cp", testJar.toString() + CP_SEPARATOR + mainJar.toString(), 252 MAIN_CLASS) 253 .assertNormalExit(out -> { 254 out.shouldContain(CLASS_FOUND_MESSAGE) 255 .shouldContain(OPTIMIZE_ENABLED); 256 }); 257 tty("8. run with CDS on, with --module-path, with jars on classpath should fail"); 258 TestCommon.run("-Xlog:cds", 259 "-p", libsDir.toString(), 260 "-cp", testJar.toString() + CP_SEPARATOR + mainJar.toString(), 261 MAIN_CLASS) 262 .assertNormalExit(out -> { 263 out.shouldNotContain(CLASS_NOT_FOUND_MESSAGE) 264 .shouldContain(CLASS_FOUND_MESSAGE) 265 .shouldNotContain(OPTIMIZE_ENABLED); 266 }); 267 tty("9. run with CDS on, with main jar only on classpath should not pass"); 268 TestCommon.run("-Xlog:cds", 269 "-cp", mainJar.toString(), 270 MAIN_CLASS) 271 .assertAbnormalExit(out -> { 272 out.shouldNotContain(CLASS_FOUND_MESSAGE) 273 .shouldNotContain(CLASS_NOT_FOUND_MESSAGE) 274 .shouldNotContain(OPTIMIZE_ENABLED) 275 .shouldNotContain(OPTIMIZE_DISABLED) 276 .shouldContain("shared class paths mismatch"); 277 }); 278 tty("10. run with CDS on, with main/test jars on classpath also with -Xbootclasspath/a: should not pass"); 279 TestCommon.run("-Xlog:cds", 280 "-cp", mainJar.toString() + CP_SEPARATOR + testJar.toString(), 281 "-Xbootclasspath/a:", ".", 282 MAIN_CLASS) 283 .assertAbnormalExit(out -> { 284 out.shouldNotContain(CLASS_FOUND_MESSAGE) 285 .shouldNotContain(CLASS_NOT_FOUND_MESSAGE) 286 .shouldContain(OPTIMIZE_DISABLED) 287 .shouldNotContain(OPTIMIZE_ENABLED) 288 .shouldContain("shared class paths mismatch"); 289 }); 290 } 291 }