1 /* 2 * Copyright (c) 2015, 2018, 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 * @modules java.base/jdk.internal.misc 29 * @library ../.. 30 * @library /test/lib 31 * @run main OverrideTests 32 * @summary AppCDS tests for overriding archived classes with -p and --upgrade-module-path 33 */ 34 35 /* 36 * This test consists of 4 tests: 37 * 1. Archive PLATFORM class and override with --upgrade-module-path. 38 * 2. Archive PLATFORM class and override with -p. 39 * 3. Archive APP class and override with --upgrade-module-path. 40 * 4. Archive App class and override with -p. 41 * For all 4 tests, the class is instantiatied and toString() is called 42 * to check whether the archived version or the override version was instantiatied. 43 * For tests 1 and 3, the overridden version should be instantiatied. 44 * For tests 2 and 4, the archived version should be instantiated. 45 * 46 * This test uses the same test helper class in all 4 cases. It is located in 47 * src/test/jdk/test/Main.java. It will be invoked once for each test cases, 48 * with parameters to the test determining how it is run and what the 49 * expected result is. See Main.java for a description of these 3 arguments. 50 */ 51 52 import java.io.File; 53 import java.nio.file.Files; 54 import java.nio.file.Path; 55 import java.nio.file.Paths; 56 57 import jdk.test.lib.Asserts; 58 import jdk.test.lib.cds.CDSOptions; 59 import jdk.test.lib.cds.CDSTestUtils; 60 import jdk.test.lib.process.OutputAnalyzer; 61 import jdk.test.lib.process.ProcessTools; 62 63 64 public class OverrideTests { 65 private static final String TEST_SRC = System.getProperty("test.src"); 66 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 67 private static final Path MODS_DIR = Paths.get("mods"); 68 69 // the module that is upgraded 70 private static final String[] UPGRADED_MODULES = {"jdk.compiler", "java.net.http"}; 71 private static final Path[] UPGRADEDMODS_DIR = {Paths.get("upgradedmod1"), Paths.get("upgradedmod2")}; 72 73 // the test module 74 private static final String TEST_MODULE = "test"; 75 private static final String MAIN_CLASS = "jdk.test.Main"; 76 77 // test classes to archive. These are both in UPGRADED_MODULES 78 private static final String APP_ARCHIVE_CLASS = "com/sun/tools/javac/Main"; 79 private static final String PLATFORM_ARCHIVE_CLASS = "java/net/http/HttpTimeoutException"; 80 private static final String[] ARCHIVE_CLASSES = {APP_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS}; 81 private static String testArchiveName; 82 83 84 public static void main(String[] args) throws Exception { 85 OverrideTests tests = new OverrideTests(); 86 tests.compileModulesAndDumpArchive(); 87 tests.testAppClassOverriding(); 88 tests.testPlatformClassOverriding(); 89 } 90 91 void compileModulesAndDumpArchive() throws Exception { 92 boolean compiled; 93 // javac -d upgradedmods/$upgradedMod src/$upgradedMod/** 94 int i = 0; 95 for (String upgradedMod : UPGRADED_MODULES) { 96 compiled = CompilerUtils.compile( 97 SRC_DIR.resolve(UPGRADED_MODULES[i]), 98 UPGRADEDMODS_DIR[i].resolve(UPGRADED_MODULES[i]) 99 ); 100 Asserts.assertTrue(compiled, UPGRADED_MODULES[i] + " did not compile"); 101 i++; 102 } 103 104 // javac -d mods/test --upgrade-module-path upgradedmods ... 105 compiled = CompilerUtils.compile( 106 SRC_DIR.resolve(TEST_MODULE), 107 MODS_DIR.resolve(TEST_MODULE), 108 "--upgrade-module-path", UPGRADEDMODS_DIR[0].toString() + 109 System.getProperty("path.separator") + UPGRADEDMODS_DIR[1].toString() 110 ); 111 Asserts.assertTrue(compiled, TEST_MODULE + " did not compile"); 112 113 // dump the archive with jdk.compiler and java.net.http classes in the class list 114 OutputAnalyzer output = TestCommon.dump(null /* appJar*/, TestCommon.list(ARCHIVE_CLASSES)); 115 TestCommon.checkDump(output); 116 // Make sure all the classes where successfully archived. 117 for (String archiveClass : ARCHIVE_CLASSES) { 118 output.shouldNotContain("Preload Warning: Cannot find " + archiveClass); 119 } 120 121 testArchiveName = TestCommon.getCurrentArchiveName(); 122 } 123 124 /** 125 * APP Class Overriding Tests 126 * 127 * Archive APP class com.sun.tools.javac.Main from module jdk.compiler. 128 * -At run time, upgrade module jdk.compiler using --upgrade-module-path. 129 * Class.forname(Main) MUST NOT load the archived Main. 130 * -At run time, module jdk.compiler also exists in --module-path. 131 * Class.forname(Main) MUST load the archived Main. 132 */ 133 public void testAppClassOverriding() throws Exception { 134 testClassOverriding(APP_ARCHIVE_CLASS, "app"); 135 } 136 137 /** 138 * PLATFORM Class Overriding Tests 139 * 140 * Archive PLATFORM class java.net.http.HttpTimeoutException from module java.net.http. 141 * -At run time, upgrade module java.net.http using --upgrade-module-path. 142 * Class.forname(HttpTimeoutException) MUST NOT load the archived HttpTimeoutException. 143 * -At run time, module java.net.http also exists in --module-path. 144 * Class.forname(HttpTimeoutException) MUST load the archived HttpTimeoutException. 145 */ 146 public void testPlatformClassOverriding() throws Exception { 147 testClassOverriding(PLATFORM_ARCHIVE_CLASS, "platform"); 148 } 149 150 /** 151 * Run the test twice. Once with upgrade module on --upgrade-module-path and once with it on -p. 152 * Only modules defined to the PlatformClassLoader are upgradeable. 153 * Modules defined to the AppClassLoader are not upgradeble; we expect the 154 * FindException to be thrown. 155 */ 156 void testClassOverriding(String archiveClass, String loaderName) throws Exception { 157 String mid = TEST_MODULE + "/" + MAIN_CLASS; 158 OutputAnalyzer output; 159 boolean isAppLoader = loaderName.equals("app"); 160 int upgradeModIdx = isAppLoader ? 0 : 1; 161 String expectedException = "java.lang.module.FindException: Unable to compute the hash"; 162 String prefix[] = new String[4]; 163 prefix[0] = "-cp"; 164 prefix[1] = "\"\""; 165 prefix[2] = "--add-modules"; 166 prefix[3] = "java.net.http"; 167 168 // Run the test with --upgrade-module-path set to alternate location of archiveClass 169 // The alternate version of archiveClass SHOULD be found. 170 TestCommon.runWithModules(prefix, 171 UPGRADEDMODS_DIR[upgradeModIdx].toString(), 172 MODS_DIR.toString(), 173 mid, 174 archiveClass, loaderName, "true") // last 3 args passed to test 175 .ifNoMappingFailure(out -> out.shouldContain(expectedException)); 176 177 // Now run this same test again, but this time without AppCDS. Behavior should be the same. 178 CDSOptions opts = (new CDSOptions()) 179 .addPrefix(prefix) 180 .setArchiveName(testArchiveName).setUseVersion(false) 181 .addSuffix("--upgrade-module-path", UPGRADEDMODS_DIR[upgradeModIdx].toString(), 182 "-p", MODS_DIR.toString(), "-m", mid) 183 .addSuffix(archiveClass, loaderName, "true"); 184 185 output = CDSTestUtils.runWithArchive(opts); 186 187 try { 188 output.shouldContain(expectedException); 189 } catch (Exception e) { 190 TestCommon.checkCommonExecExceptions(output, e); 191 } 192 193 // Run the test with -p set to alternate location of archiveClass. 194 // The alternate version of archiveClass SHOULD NOT be found. 195 TestCommon.runWithModules( 196 prefix, 197 null, 198 UPGRADEDMODS_DIR[upgradeModIdx].toString() + java.io.File.pathSeparator + MODS_DIR.toString(), 199 mid, 200 archiveClass, loaderName, "false") // last 3 args passed to test 201 .assertNormalExit(); 202 203 // Now run this same test again, but this time without AppCDS. Behavior should be the same. 204 opts = (new CDSOptions()) 205 .addPrefix(prefix) 206 .setArchiveName(testArchiveName).setUseVersion(false) 207 .addSuffix("-p", MODS_DIR.toString(), "-m", mid) 208 .addSuffix(archiveClass, loaderName, "false"); // params to the test class 209 210 OutputAnalyzer out = CDSTestUtils.runWithArchive(opts); 211 if (!CDSTestUtils.isUnableToMap(out)) 212 out.shouldHaveExitValue(0); 213 } 214 }