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 & !vm.graal.enabled 28 * @library ../.. 29 * @library /test/lib 30 * @modules java.compiler 31 * java.base/jdk.internal.misc 32 * jdk.jartool/sun.tools.jar 33 * @compile src/jdk/test/Main.java 34 * @compile src/com/sun/tools/javac/Main.jasm 35 * @compile src/com/sun/tools/javac/MyMain.jasm 36 * @compile ../../../SharedArchiveFile/javax/annotation/processing/FilerException.jasm 37 * @run main ClassPathTests 38 * @summary AppCDS tests for testing classpath/package conflicts 39 */ 40 41 /* 42 * These tests will verify that AppCDS will correctly handle archived classes 43 * on the classpath that are in a package that is also exported by the jimage. 44 * These classes should fail to load unless --limit-modules is used to hide the 45 * package exported by the jimage. There are 8 variants of this test: 46 * - With a jimage app package and with a jimage ext package 47 * - With --limit-modules and without --limit-modules 48 * - With AppCDS and without AppCDS (to verify behaviour is the same for both). 49 * 50 * There is also a 9th test to verify that when --limit-modules is used, a jimage 51 * class in the archive can be replaced by a classpath class with the 52 * same name and package. 53 */ 54 55 import java.lang.reflect.InvocationTargetException; 56 import java.lang.reflect.Method; 57 import java.nio.file.Path; 58 import java.nio.file.Paths; 59 60 import jdk.test.lib.Asserts; 61 import jdk.test.lib.cds.CDSOptions; 62 import jdk.test.lib.cds.CDSTestUtils; 63 import jdk.test.lib.process.ProcessTools; 64 import jdk.test.lib.process.OutputAnalyzer; 65 66 import jtreg.SkippedException; 67 68 69 public class ClassPathTests { 70 private static final String TEST_SRC = System.getProperty("test.src"); 71 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 72 private static final Path CLASSES_DIR = Paths.get("classes"); 73 74 // the test module 75 private static final String MAIN_CLASS = "jdk.test.Main"; 76 private static final String LIMITMODS_MAIN_CLASS = "jdk.test.LimitModsMain"; 77 78 // test classes to archive. These are both in UPGRADED_MODULES 79 private static final String JIMAGE_CLASS = "com/sun/tools/javac/Main"; 80 private static final String APP_ARCHIVE_CLASS = "com/sun/tools/javac/MyMain"; 81 private static final String PLATFORM_ARCHIVE_CLASS = "javax/annotation/processing/FilerException"; 82 private static final String[] ARCHIVE_CLASSES = {APP_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, JIMAGE_CLASS}; 83 private static final int NUMBER_OF_TEST_CASES = 10; 84 85 private static String appJar; 86 private static String testArchiveName; 87 88 89 public static void main(String[] args) throws Exception { 90 ClassPathTests tests = new ClassPathTests(); 91 tests.dumpArchive(); 92 93 Method[] methods = tests.getClass().getDeclaredMethods(); 94 int numOfTestMethodsRun = 0; 95 for (Method m : methods) { 96 if (m.getName().startsWith("test")) { 97 System.out.println("About to run test method: " + m.getName()); 98 try { 99 m.invoke(tests); 100 } catch (InvocationTargetException ite) { 101 if (ite.getCause() instanceof SkippedException) { 102 System.out.println("Test PASSED: " + ite.getCause().getMessage()); 103 } else { 104 throw ite; 105 } 106 } 107 numOfTestMethodsRun++; 108 } 109 } 110 111 Asserts.assertTrue((numOfTestMethodsRun == NUMBER_OF_TEST_CASES), 112 "Expected " + NUMBER_OF_TEST_CASES + " test methods to run, actual number is " 113 + numOfTestMethodsRun); 114 } 115 116 private void dumpArchive() throws Exception { 117 // Create a jar file with all the classes related to this test. 118 JarBuilder.build( "classpathtests", 119 APP_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, JIMAGE_CLASS, 120 "jdk/test/Main"); 121 appJar = TestCommon.getTestJar("classpathtests.jar"); 122 123 // dump the archive with altnernate jdk.comiler and jdk.activation classes in the class list 124 OutputAnalyzer output1 = TestCommon.dump(appJar, TestCommon.list(ARCHIVE_CLASSES)); 125 TestCommon.checkDump(output1); 126 // The PLATFORM_ARCHIVE_CLASS belongs to the java.compiler 127 // module will be found from the module during dumping. 128 // The JIMAGE_CLASS will be found from the jdk.compiler module during 129 // dumping. 130 // The APP_ARCHIVE_CLASS, which belongs to a package within the 131 // jdk.compiler module, will not be found during dump time. 132 for (String archiveClass : ARCHIVE_CLASSES) { 133 if (archiveClass.equals(APP_ARCHIVE_CLASS)) { 134 output1.shouldContain("Preload Warning: Cannot find " + archiveClass); 135 } else { 136 output1.shouldNotContain("Preload Warning: Cannot find " + archiveClass); 137 } 138 } 139 140 testArchiveName = TestCommon.getCurrentArchiveName(); 141 } 142 143 // #1: Archived classpath class in same package as jimage app class. With AppCDS. 144 // Should fail to load. 145 public void testAppClassWithAppCDS() throws Exception { 146 OutputAnalyzer output = TestCommon.exec( 147 appJar, MAIN_CLASS, 148 "Test #1", APP_ARCHIVE_CLASS, "false"); // last 3 args passed to test 149 TestCommon.checkExec(output); 150 } 151 152 // #2: Archived classpath class in same package as jimage app class. Without AppCDS. 153 // Should fail to load. 154 public void testAppClassWithoutAppCDS() throws Exception { 155 CDSOptions opts = (new CDSOptions()) 156 .addPrefix("-cp", appJar) 157 .setArchiveName(testArchiveName) 158 .addSuffix(MAIN_CLASS, "Test #2", APP_ARCHIVE_CLASS, "false"); 159 160 CDSTestUtils.runWithArchiveAndCheck(opts); 161 } 162 163 // #3: Archived classpath class in same package as jimage ext class. With AppCDS. 164 // The class should be loaded from the module. 165 public void testExtClassWithAppCDS() throws Exception { 166 OutputAnalyzer output = TestCommon.exec( 167 appJar, MAIN_CLASS, 168 "Test #3", PLATFORM_ARCHIVE_CLASS, "true", "EXT"); // last 4 args passed to test 169 TestCommon.checkExec(output); 170 } 171 172 // #4: Archived classpath class in same package as jimage ext class. Without AppCDS. 173 // The class should be loaded from the module. 174 public void testExtClassWithoutAppCDS() throws Exception { 175 CDSOptions opts = (new CDSOptions()) 176 .addPrefix("-cp", appJar) 177 .setArchiveName(testArchiveName) 178 .addSuffix(MAIN_CLASS, "Test #4", PLATFORM_ARCHIVE_CLASS, "true", "EXT"); 179 180 CDSTestUtils.runWithArchiveAndCheck(opts); 181 } 182 183 // #5: Archived classpath class in same package as jimage app class. With AppCDS. 184 // Should load with CDS disabled because --limit-modules is used. 185 public void testAppClassWithLimitModsWithAppCDS() throws Exception { 186 TestCommon.run("-cp", appJar, 187 "--limit-modules", "java.base", 188 MAIN_CLASS, 189 "Test #5", APP_ARCHIVE_CLASS, "true") // last 3 args passed to test 190 .assertSilentlyDisabledCDS(out -> { 191 out.shouldHaveExitValue(0); 192 }); 193 } 194 195 // #6: Archived classpath class in same package as jimage app class. Without AppCDS. 196 // Should load with CDS disabled because --limit-modules is used. 197 public void testAppClassWithLimitModsWithoutAppCDS() throws Exception { 198 CDSOptions opts = (new CDSOptions()) 199 .addPrefix("-cp", appJar, "--limit-modules", "java.base") 200 .setArchiveName(testArchiveName) 201 .addSuffix(MAIN_CLASS, "Test #6", APP_ARCHIVE_CLASS, "true"); 202 CDSTestUtils.run(opts) 203 .assertSilentlyDisabledCDS(out -> { 204 out.shouldHaveExitValue(0); 205 }); 206 } 207 208 // #7: Archived classpath class in same package as jimage ext class. With AppCDS. 209 // Should load with CDS disabled because --limit-modules is used. 210 public void testExtClassWithLimitModsWithAppCDS() throws Exception { 211 TestCommon.run("-cp", appJar, 212 "--limit-modules", "java.base", 213 MAIN_CLASS, 214 "Test #7", PLATFORM_ARCHIVE_CLASS, "true") // last 3 args passed to test 215 .assertSilentlyDisabledCDS(out -> { 216 out.shouldHaveExitValue(0); 217 }); 218 } 219 220 // #8: Archived classpath class in same package as jimage ext class. Without AppCDS. 221 // Should load with CDS disabled because --limit-modules is used. 222 public void testExtClassWithLimitModsWithoutAppCDS() throws Exception { 223 CDSOptions opts = (new CDSOptions()) 224 .addPrefix("-cp", appJar, "--limit-modules", "java.base") 225 .setArchiveName(testArchiveName) 226 .addSuffix(MAIN_CLASS, "Test #8", PLATFORM_ARCHIVE_CLASS, "true"); 227 CDSTestUtils.run(opts) 228 .assertSilentlyDisabledCDS(out -> { 229 out.shouldHaveExitValue(0); 230 }); 231 } 232 233 // #9: Archived classpath class with same name as jimage app class. With AppCDS. 234 // Should load with CDS disabled because --limit-modules is used. 235 public void testReplacingJImageClassWithAppCDS() throws Exception { 236 TestCommon.run("-cp", appJar, 237 "--limit-modules", "java.base", 238 MAIN_CLASS, 239 "Test #9", JIMAGE_CLASS, "true") // last 3 args passed to test 240 .assertSilentlyDisabledCDS(out -> { 241 out.shouldHaveExitValue(0); 242 }); 243 } 244 245 // #10: Archived classpath class with same name as jimage app class. Without AppCDS. 246 // Should load because --limit-modules is used. Note the archive will actually contain 247 // the original jimage version of the class, but AppCDS should refuse to load it 248 // since --limit-modules is used. This should result in the -cp version being used. 249 public void testReplacingJImageClassWithoutAppCDS() throws Exception { 250 CDSOptions opts = (new CDSOptions()) 251 .addPrefix("-cp", appJar, "--limit-modules", "java.base") 252 .setArchiveName(testArchiveName) 253 .addSuffix(MAIN_CLASS, "Test #10", JIMAGE_CLASS, "true"); 254 CDSTestUtils.run(opts) 255 .assertSilentlyDisabledCDS(out -> { 256 out.shouldHaveExitValue(0); 257 }); 258 } 259 }