1 /*
   2  * Copyright (c) 2014, 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 test the -XX:+PrintSharedArchiveAndExit flag
  28  * @requires vm.cds
  29  * @library /test/lib
  30  * @modules java.base/jdk.internal.misc
  31  *          java.management
  32  *          jdk.jartool/sun.tools.jar
  33  * @compile test-classes/Hello.java
  34  * @compile test-classes/HelloMore.java
  35  * @run main/othervm/timeout=3600 PrintSharedArchiveAndExit
  36  */
  37 
  38 import java.io.File;
  39 import jdk.test.lib.process.OutputAnalyzer;
  40 
  41 public class PrintSharedArchiveAndExit {
  42   private static void check(OutputAnalyzer output, int ret, boolean checkContain, String... matches) throws Exception {
  43     // Tests specific to this test
  44     TestCommon.checkExecReturn(output, ret, checkContain, matches);
  45 
  46     // In all test case, we should never print out the following due to
  47     // PrintSharedArchiveAndExit. JVM should have been terminated
  48     // before reaching these outputs.
  49     TestCommon.checkExecReturn(output, ret, false,
  50                                "Usage:",            // JVM help message
  51                                "java version",      // JVM version
  52                                "Hello World");      // output from the Hello.class in hello.jar
  53   }
  54 
  55   private static void log(String msg) {
  56     System.out.println(">---------------------------------------------------------------------");
  57     System.out.println(msg);
  58     System.out.println("<---------------------------------------------------------------------");
  59   }
  60 
  61   public static void main(String[] args) throws Exception {
  62     String appJar = JarBuilder.getOrCreateHelloJar();
  63     String appJar2 = JarBuilder.build("PrintSharedArchiveAndExit-more", "HelloMore");
  64 
  65     String cp = appJar + File.pathSeparator + appJar2;
  66     String lastCheckMsg = "checking shared classpath entry: " + appJar2; // the last JAR to check
  67 
  68     TestCommon.testDump(cp, TestCommon.list("Hello"));
  69 
  70     log("Normal execution -- all the JAR paths should be checked");
  71     TestCommon.run(
  72         "-cp", cp,
  73         "-XX:+PrintSharedArchiveAndExit")
  74       .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
  75 
  76     TestCommon.run(
  77         "-cp", cp,
  78         "-XX:+PrintSharedArchiveAndExit",
  79         "-XX:+PrintSharedDictionary")  // Test PrintSharedDictionary as well.
  80       .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg, "java.lang.Object"));
  81 
  82     log("Normal execution -- Make sure -version, help message and app main()\n" +
  83         "class are not invoked. These are checked inside check().");
  84     TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-version")
  85       .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
  86 
  87     TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-help")
  88       .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
  89 
  90     TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello")
  91       .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
  92 
  93     log("Execution with simple errors -- with 'simple' errors like missing or modified\n" +
  94         "JAR files, the VM should try to continue to print the remaining information.\n" +
  95         "Use an invalid Boot CP -- all the JAR paths should be checked");
  96     TestCommon.run(
  97         "-cp", cp,
  98         "-Xbootclasspath/a:foo.jar",
  99         "-XX:+PrintSharedArchiveAndExit")
 100       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, "));
 101 
 102     log("Use an App CP shorter than the one at dump time -- all the JAR paths should be checked");
 103     TestCommon.run(
 104         "-cp", ".",
 105         "-XX:+PrintSharedArchiveAndExit")
 106       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: ."));
 107 
 108     log("Use an invalid App CP -- all the JAR paths should be checked");
 109     String invalidCP = "non-existing-dir" + File.pathSeparator + cp;
 110     TestCommon.run(
 111         "-cp", invalidCP,
 112         "-XX:+PrintSharedArchiveAndExit")
 113       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP));
 114 
 115     log("Changed modification time of hello.jar -- all the JAR paths should be checked");
 116     (new File(appJar)).setLastModified(System.currentTimeMillis() + 2000);
 117     TestCommon.run(
 118         "-cp", cp,
 119         "-XX:+PrintSharedArchiveAndExit")
 120       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[Timestamp mismatch]"));
 121 
 122     log("Even if hello.jar is out of date, we should still be able to print the dictionary.");
 123     TestCommon.run(
 124         "-cp", cp,
 125         "-XX:+PrintSharedArchiveAndExit",
 126         "-XX:+PrintSharedDictionary")  // Test PrintSharedDictionary as well.
 127       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "java.lang.Object"));
 128 
 129 
 130     log("Remove hello.jar -- all the JAR paths should be checked");
 131     (new File(appJar)).delete();
 132     TestCommon.run(
 133         "-cp", cp,
 134         "-XX:+PrintSharedArchiveAndExit")
 135       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[Required classpath entry does not exist: " + appJar + "]"));
 136 
 137     log("Execution with major errors -- with 'major' errors like the JSA file\n" +
 138         "is missing, we should stop immediately to avoid crashing the JVM.");
 139     TestCommon.run(
 140         "-cp", cp,
 141         "-XX:+PrintSharedArchiveAndExit",
 142         "-XX:SharedArchiveFile=./no-such-fileappcds.jsa")
 143       .ifNoMappingFailure(output -> check(output, 1, false, lastCheckMsg));
 144   }
 145 }