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  * @summary AppCDS tests for testing -Xbootclasspath/a
  28  * @requires vm.cds & !vm.graal.enabled
  29  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  30  * @modules java.base/jdk.internal.misc
  31  *          java.management
  32  *          jdk.jartool/sun.tools.jar
  33  *          jdk.internal.jvmstat/sun.jvmstat.monitor
  34  * @compile src/jdk/test/Main.java
  35  * @compile src/com/sun/tools/javac/Main2.jasm
  36  * @compile src/sun/nio/cs/ext/MyClass.java
  37  * @compile src/sun/nio/cs/ext1/MyClass.java
  38  * @run main BootAppendTests
  39  */
  40 
  41 import java.io.File;
  42 import java.nio.file.Path;
  43 import java.nio.file.Paths;
  44 import jdk.test.lib.cds.CDSOptions;
  45 import jdk.test.lib.cds.CDSTestUtils;
  46 import jdk.test.lib.process.ProcessTools;
  47 import jdk.test.lib.process.OutputAnalyzer;
  48 
  49 public class BootAppendTests {
  50     private static final String TEST_SRC = System.getProperty("test.src");
  51     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
  52     private static final Path CLASSES_DIR = Paths.get("classes");
  53 
  54     private static final String MAIN_CLASS = "jdk.test.Main";
  55     private static final String APP_MODULE_CLASS = "com/sun/tools/javac/Main2";
  56     private static final String BOOT_APPEND_MODULE_CLASS = "sun/nio/cs/ext/MyClass";
  57     private static final String BOOT_APPEND_CLASS = "sun/nio/cs/ext1/MyClass";
  58     private static final String[] ARCHIVE_CLASSES =
  59          {APP_MODULE_CLASS, BOOT_APPEND_MODULE_CLASS, BOOT_APPEND_CLASS};
  60 
  61     private static String appJar;
  62     private static String bootAppendJar;
  63     private static String testArchiveName;
  64 
  65     public static void main(String... args) throws Exception {
  66         dumpArchive();
  67 
  68         System.out.println("TESTCASE: 1: testBootAppendModuleClassWithoutAppCDS");
  69         testBootAppendModuleClassWithoutAppCDS();
  70 
  71         System.out.println("TESTCASE: 2" );
  72         testBootAppendModuleClassWithAppCDS();
  73 
  74         System.out.println("TESTCASE: 3" );
  75         testBootAppendExcludedModuleClassWithoutAppCDS();
  76 
  77         System.out.println("TESTCASE: 4" );
  78         testBootAppendExcludedModuleClassWithAppCDS();
  79 
  80         System.out.println("TESTCASE: 5" );
  81         testBootAppendClassWithoutAppCDS();
  82 
  83         System.out.println("TESTCASE: 6" );
  84         testBootAppendClassWithAppCDS();
  85 
  86         System.out.println("TESTCASE: 7" );
  87         testBootAppendAppModuleClassWithoutAppCDS();
  88 
  89         System.out.println("TESTCASE: 9" );
  90         testBootAppendAppModuleClassWithAppCDS();
  91 
  92         System.out.println("TESTCASE: 9" );
  93         testBootAppendAppExcludeModuleClassWithoutAppCDS();
  94 
  95         System.out.println("TESTCASE: 10" );
  96         testBootAppendAppExcludeModuleClassAppCDS();
  97     }
  98 
  99     static void dumpArchive() throws Exception {
 100         JarBuilder.build("classpathtests", "jdk/test/Main");
 101         appJar = TestCommon.getTestJar("classpathtests.jar");
 102 
 103         JarBuilder.build("bootAppend",
 104                          APP_MODULE_CLASS, BOOT_APPEND_MODULE_CLASS, BOOT_APPEND_CLASS);
 105         bootAppendJar = TestCommon.getTestJar("bootAppend.jar");
 106 
 107         OutputAnalyzer output1  = TestCommon.dump(
 108             appJar, TestCommon.list(ARCHIVE_CLASSES), "-Xbootclasspath/a:" + bootAppendJar);
 109         TestCommon.checkDump(output1);
 110 
 111         if (!TestCommon.isUnableToMap(output1)) {
 112             // Make sure all the classes were successfully archived.
 113             for (String archiveClass : ARCHIVE_CLASSES) {
 114                 output1.shouldNotContain("Preload Warning: Cannot find " + archiveClass);
 115             }
 116         }
 117 
 118         testArchiveName = TestCommon.getCurrentArchiveName();
 119     }
 120 
 121     // Test #1: A class in package defined in boot module
 122     //    - should not be loaded from the -Xbootclasspath/a without AppCDS
 123     public static void testBootAppendModuleClassWithoutAppCDS() throws Exception {
 124         CDSOptions opts = (new CDSOptions())
 125             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
 126             .setArchiveName(testArchiveName)
 127             .addSuffix(MAIN_CLASS, "Test #1", BOOT_APPEND_MODULE_CLASS, "false");
 128 
 129         CDSTestUtils.runWithArchiveAndCheck(opts);
 130     }
 131 
 132     // Test #2: A shared class in package defined in boot module that's archived
 133     //          from -Xbootclasspath/a
 134     //     - should not be loaded by AppCDS
 135     public static void testBootAppendModuleClassWithAppCDS() throws Exception {
 136         OutputAnalyzer output = TestCommon.exec(
 137             appJar,
 138             "-Xbootclasspath/a:" + bootAppendJar,
 139             MAIN_CLASS,
 140             "Test #2", BOOT_APPEND_MODULE_CLASS, "false");
 141         TestCommon.checkExec(output);
 142     }
 143 
 144 
 145     // Test #3: A class in excluded package defined in boot module
 146     //     - should be loaded from the -Xbootclasspath/a by the boot classloader
 147     public static void testBootAppendExcludedModuleClassWithoutAppCDS() throws Exception {
 148         CDSOptions opts = (new CDSOptions())
 149             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
 150                        "-Xlog:class+load=info",
 151                        "--limit-modules", "java.base")
 152             .setArchiveName(testArchiveName)
 153             .setUseVersion(false)
 154             .addSuffix(MAIN_CLASS, "Test #3", BOOT_APPEND_MODULE_CLASS, "true", "BOOT");
 155 
 156         OutputAnalyzer output = CDSTestUtils.runWithArchive(opts);
 157         output.shouldHaveExitValue(0);
 158         if (!TestCommon.isUnableToMap(output))
 159             output.shouldMatch(".class.load. sun.nio.cs.ext.MyClass source:.*bootAppend.jar");
 160     }
 161 
 162     // Test #4: A shared class in excluded package that's archived from
 163     //          -Xbootclasspath/a
 164     //     - should be loaded from the jar since AppCDS will be disabled with
 165     //       the --limit-modules option
 166     public static void testBootAppendExcludedModuleClassWithAppCDS() throws Exception {
 167         OutputAnalyzer output = TestCommon.exec(
 168             appJar,
 169             "-Xbootclasspath/a:" + bootAppendJar,
 170             "--limit-modules", "java.base",
 171             "-XX:+TraceClassLoading",
 172             MAIN_CLASS,
 173             "Test #4", BOOT_APPEND_MODULE_CLASS, "true", "BOOT");
 174         output.shouldHaveExitValue(0);
 175         if (!TestCommon.isUnableToMap(output))
 176             output.shouldMatch(".class.load. sun.nio.cs.ext.MyClass source:.*bootAppend.jar");
 177     }
 178 
 179 
 180     // Test #5: A class not in package defined in boot module
 181     //    - should be loaded from the -Xbootclasspath/a without AppCDS
 182     public static void testBootAppendClassWithoutAppCDS() throws Exception {
 183         CDSOptions opts = (new CDSOptions())
 184             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
 185             .setArchiveName(testArchiveName)
 186             .addSuffix(MAIN_CLASS, "Test #5", BOOT_APPEND_CLASS, "true", "BOOT");
 187 
 188         CDSTestUtils.runWithArchiveAndCheck(opts);
 189     }
 190 
 191 
 192     // Test #6: A shared class not in package defined in boot module that's
 193     //          archived from -Xbootclasspath/a
 194     //    - should be loaded from the archive by the bootstrap class loader
 195     public static void testBootAppendClassWithAppCDS() throws Exception {
 196         OutputAnalyzer output = TestCommon.exec(
 197             appJar,
 198             "-Xbootclasspath/a:" + bootAppendJar,
 199             "-XX:+TraceClassLoading",
 200             MAIN_CLASS,
 201             "Test #6", BOOT_APPEND_CLASS, "true", "BOOT");
 202         TestCommon.checkExec(output);
 203         if (!TestCommon.isUnableToMap(output))
 204             output.shouldContain("[class,load] sun.nio.cs.ext1.MyClass source: shared objects file");
 205     }
 206 
 207 
 208     // Test #7: A class in package defined in jimage app module
 209     //    - should not be loaded from the -Xbootclasspath/a without AppCDS
 210     public static void testBootAppendAppModuleClassWithoutAppCDS() throws Exception {
 211         CDSOptions opts = (new CDSOptions())
 212             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
 213             .setArchiveName(testArchiveName)
 214             .addSuffix(MAIN_CLASS, "Test #7", APP_MODULE_CLASS, "false");
 215 
 216         CDSTestUtils.runWithArchiveAndCheck(opts);
 217     }
 218 
 219 
 220     // Test #8: A shared class in package defined in jimage app module that's
 221     //          archived from -Xbootclasspath/a
 222     //    - should not be loaded from the archive
 223     public static void testBootAppendAppModuleClassWithAppCDS() throws Exception {
 224         OutputAnalyzer output = TestCommon.exec(
 225             appJar,
 226             "-Xbootclasspath/a:" + bootAppendJar,
 227             MAIN_CLASS,
 228             "Test #8", APP_MODULE_CLASS, "false");
 229         TestCommon.checkExec(output);
 230     }
 231 
 232 
 233     // Test #9: A class in excluded package defined in jimage app module
 234     //    - should be loaded from the -Xbootclasspath/a without AppCDS
 235     public static void testBootAppendAppExcludeModuleClassWithoutAppCDS()
 236         throws Exception {
 237 
 238         CDSOptions opts = (new CDSOptions())
 239             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
 240                        "-Xlog:class+load=info",
 241                        "--limit-modules", "java.base")
 242             .setArchiveName(testArchiveName)
 243             .setUseVersion(false)
 244             .addSuffix(MAIN_CLASS, "Test #9", APP_MODULE_CLASS, "true", "BOOT");
 245 
 246         OutputAnalyzer output = CDSTestUtils.runWithArchive(opts);
 247         output.shouldHaveExitValue(0);
 248         if (!TestCommon.isUnableToMap(output))
 249             output.shouldMatch(".class.load. com.sun.tools.javac.Main2 source:.*bootAppend.jar");
 250     }
 251 
 252     // Test #10: A shared class in excluded package defined in jimage app module
 253     //    - should be loaded from the -Xbootclasspath/a with AppCDS
 254     public static void testBootAppendAppExcludeModuleClassAppCDS() throws Exception {
 255         OutputAnalyzer output = TestCommon.exec(
 256             appJar,
 257             "-Xbootclasspath/a:" + bootAppendJar,
 258             "-XX:+TraceClassLoading",
 259             "--limit-modules", "java.base",
 260             MAIN_CLASS,
 261             "Test #10", APP_MODULE_CLASS, "true", "BOOT");
 262 
 263         output.shouldHaveExitValue(0);
 264         if (!TestCommon.isUnableToMap(output))
 265             output.shouldMatch(".class.load. com.sun.tools.javac.Main2 source:.*bootAppend.jar");
 266     }
 267 }