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/cds
  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/MyMain.jasm
  36  * @compile src/sun/nio/cs/ext/MyClass.java
  37  * @compile src/sun/nio/cs/ext1/MyClass.java
  38  * @run driver 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/MyMain";
  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         TestCommon.run(
 149             "-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
 150             "-Xlog:class+load=info",
 151             "--limit-modules", "java.base",
 152             MAIN_CLASS, "Test #3", BOOT_APPEND_MODULE_CLASS, "true", "BOOT")
 153             .assertSilentlyDisabledCDS(out -> {
 154                 out.shouldHaveExitValue(0)
 155                    .shouldMatch(".class.load. sun.nio.cs.ext.MyClass source:.*bootAppend.jar");
 156             });
 157     }
 158 
 159     // Test #4: A shared class in excluded package that's archived from
 160     //          -Xbootclasspath/a
 161     //     - should be loaded from the jar since AppCDS will be disabled with
 162     //       the --limit-modules option
 163     public static void testBootAppendExcludedModuleClassWithAppCDS() throws Exception {
 164         TestCommon.run(
 165             "-cp", appJar, "-Xbootclasspath/a:" + bootAppendJar,
 166             "-Xlog:class+load=info",
 167             "--limit-modules", "java.base",
 168             MAIN_CLASS,
 169             "Test #4", BOOT_APPEND_MODULE_CLASS, "true", "BOOT")
 170             .assertSilentlyDisabledCDS(out -> {
 171                 out.shouldHaveExitValue(0)
 172                    .shouldMatch(".class.load. sun.nio.cs.ext.MyClass source:.*bootAppend.jar");
 173             });
 174     }
 175 
 176 
 177     // Test #5: A class not in package defined in boot module
 178     //    - should be loaded from the -Xbootclasspath/a without AppCDS
 179     public static void testBootAppendClassWithoutAppCDS() throws Exception {
 180         CDSOptions opts = (new CDSOptions())
 181             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
 182             .setArchiveName(testArchiveName)
 183             .addSuffix(MAIN_CLASS, "Test #5", BOOT_APPEND_CLASS, "true", "BOOT");
 184 
 185         CDSTestUtils.runWithArchiveAndCheck(opts);
 186     }
 187 
 188 
 189     // Test #6: A shared class not in package defined in boot module that's
 190     //          archived from -Xbootclasspath/a
 191     //    - should be loaded from the archive by the bootstrap class loader
 192     public static void testBootAppendClassWithAppCDS() throws Exception {
 193         OutputAnalyzer output = TestCommon.exec(
 194             appJar,
 195             "-Xbootclasspath/a:" + bootAppendJar,
 196             "-XX:+TraceClassLoading",
 197             MAIN_CLASS,
 198             "Test #6", BOOT_APPEND_CLASS, "true", "BOOT");
 199         TestCommon.checkExec(output);
 200         if (!TestCommon.isUnableToMap(output))
 201             output.shouldContain("[class,load] sun.nio.cs.ext1.MyClass source: shared objects file");
 202     }
 203 
 204 
 205     // Test #7: A class in package defined in jimage app module
 206     //    - should not be loaded from the -Xbootclasspath/a without AppCDS
 207     public static void testBootAppendAppModuleClassWithoutAppCDS() throws Exception {
 208         CDSOptions opts = (new CDSOptions())
 209             .addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
 210             .setArchiveName(testArchiveName)
 211             .addSuffix(MAIN_CLASS, "Test #7", APP_MODULE_CLASS, "false");
 212 
 213         CDSTestUtils.runWithArchiveAndCheck(opts);
 214     }
 215 
 216 
 217     // Test #8: A shared class in package defined in jimage app module that's
 218     //          archived from -Xbootclasspath/a
 219     //    - should not be loaded from the archive
 220     public static void testBootAppendAppModuleClassWithAppCDS() throws Exception {
 221         OutputAnalyzer output = TestCommon.exec(
 222             appJar,
 223             "-Xbootclasspath/a:" + bootAppendJar,
 224             MAIN_CLASS,
 225             "Test #8", APP_MODULE_CLASS, "false");
 226         TestCommon.checkExec(output);
 227     }
 228 
 229 
 230     // Test #9: A class in excluded package defined in jimage app module
 231     //    - should be loaded from the -Xbootclasspath/a without AppCDS
 232     public static void testBootAppendAppExcludeModuleClassWithoutAppCDS()
 233         throws Exception {
 234 
 235         TestCommon.run(
 236             "-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
 237             "-Xlog:class+load=info",
 238             "--limit-modules", "java.base",
 239             MAIN_CLASS, "Test #9", APP_MODULE_CLASS, "true", "BOOT")
 240             .assertSilentlyDisabledCDS(out -> {
 241                 out.shouldHaveExitValue(0)
 242                    .shouldMatch(".class.load. com.sun.tools.javac.MyMain source:.*bootAppend.jar");
 243             });
 244     }
 245 
 246     // Test #10: A shared class in excluded package defined in jimage app module
 247     //    - should be loaded from the -Xbootclasspath/a with AppCDS
 248     public static void testBootAppendAppExcludeModuleClassAppCDS() throws Exception {
 249         TestCommon.run(
 250             "-cp", appJar, "-Xbootclasspath/a:" + bootAppendJar,
 251             "-Xlog:class+load=info",
 252             "--limit-modules", "java.base",
 253             MAIN_CLASS, "Test #10", APP_MODULE_CLASS, "true", "BOOT")
 254             .assertSilentlyDisabledCDS(out -> {
 255                 out.shouldHaveExitValue(0)
 256                    .shouldMatch(".class.load. com.sun.tools.javac.MyMain source:.*bootAppend.jar");
 257             });
 258     }
 259 }