1 /**
   2  * Copyright (c) 2018, 2019, 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  * @test
  26  * @summary Test archived module graph with custom runtime image
  27  * @requires vm.cds.archived.java.heap
  28  * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds
  29  * @build sun.hotspot.WhiteBox
  30  * @compile CheckArchivedModuleApp.java
  31  * @run driver ClassFileInstaller -jar app.jar CheckArchivedModuleApp
  32  * @run driver ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
  33  * @run driver ArchivedModuleWithCustomImageTest
  34  */
  35 
  36 import java.io.File;
  37 import java.nio.file.Files;
  38 import java.nio.file.Path;
  39 import java.nio.file.Paths;
  40 
  41 import jdk.test.lib.compiler.CompilerUtils;
  42 import jdk.test.lib.process.OutputAnalyzer;
  43 import jdk.test.lib.process.ProcessTools;
  44 
  45 public class ArchivedModuleWithCustomImageTest {
  46     private static final String JAVA_HOME = System.getProperty("java.home");
  47     private static final String TEST_MODULE = "test";
  48     private static final Path jdkHome = Paths.get(System.getProperty("test.jdk"));
  49     private static final Path jdkMods = jdkHome.resolve("jmods");
  50     private static final Path testSrc = Paths.get(System.getProperty("test.src"));
  51     private static final Path src = testSrc.resolve("src").resolve(TEST_MODULE);
  52     private static final Path classes = Paths.get("classes");
  53     private static final Path jmods = Paths.get("jmods");
  54 
  55     public static void main(String[] args) throws Throwable {
  56         if (Files.notExists(jdkMods)) {
  57             System.out.println("No jmods/ in test JDK, not supported.");
  58             return;
  59         }
  60 
  61         // compile test module class
  62         if (!CompilerUtils.compile(src, classes)) {
  63             throw new RuntimeException("Compilation failure.");
  64         }
  65 
  66         System.out.println("Java Home: " + JAVA_HOME);
  67         System.out.println("JDK Home: " + jdkHome.toString());
  68         System.out.println("jdkModes: " + jdkMods.toString());
  69         System.out.println("testSrc: " + testSrc.toString());
  70 
  71         // create custom runtime image named 'myimage'
  72         Files.createDirectories(jmods);
  73         Path image = Paths.get("myimage");
  74         runJmod(classes.toString(), TEST_MODULE);
  75         runJlink(image, TEST_MODULE);
  76 
  77         // test using 'myimage'
  78         testArchivedModuleUsingImage(image);
  79 
  80         // Files.delete(jmods.resolve(TEST_MODULE + ".jmod"));
  81     }
  82 
  83     private static void runJlink(Path image, String modName) throws Throwable {
  84         Path jlink = Paths.get(JAVA_HOME, "bin", "jlink");
  85         String cmd = jlink.toString() + " --output " + image.toString() + " --add-modules " +  modName +
  86             " --module-path " + jdkMods + File.pathSeparator + jmods;
  87         System.out.println("Cmd: " + cmd);  
  88         OutputAnalyzer output = ProcessTools.executeProcess(jlink.toString(),
  89                         "--output", image.toString(),
  90                         "--add-modules", modName,
  91                         "--module-path", jdkMods + File.pathSeparator + jmods);
  92         output.shouldHaveExitValue(0);
  93     }
  94 
  95     private static void runJmod(String cp, String modName) throws Throwable {
  96         Path jmod = Paths.get(JAVA_HOME, "bin", "jmod");
  97         String cmd = jmod.toString() + 
  98                        " create " +
  99                        " --class-path " + cp +
 100                        " --module-version " +  "1.0" +
 101                        " --main-class "  + " jdk.test.Test " +
 102                        jmods.resolve(modName + ".jmod").toString();
 103        System.out.println("Cmd: " + cmd);
 104 
 105         OutputAnalyzer output = ProcessTools.executeProcess(jmod.toString(),
 106                        "create",
 107                        "--class-path", cp,
 108                        "--module-version", "1.0",
 109                        "--main-class", "jdk.test.Test",
 110                        jmods.resolve(modName + ".jmod").toString());
 111         output.shouldHaveExitValue(0);
 112     }
 113 
 114     private static void testArchivedModuleUsingImage(Path image)
 115                             throws Throwable {
 116         String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
 117         String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
 118         String appJar = ClassFileInstaller.getJarPath("app.jar");
 119         Path customJava = Paths.get(image.toString(), "bin", "java");
 120 
 121         // -Xshare:dump with custom runtime image
 122         String[] dumpCmd = {
 123             customJava.toString(),
 124             "-XX:SharedArchiveFile=./ArchivedModuleWithCustomImageTest.jsa",
 125             "-Xshare:dump", "-Xlog:cds"};
 126         printCommand(dumpCmd);
 127         ProcessBuilder pbDump = new ProcessBuilder();
 128         pbDump.command(dumpCmd);
 129         OutputAnalyzer output = TestCommon.executeAndLog(
 130             pbDump, "custom.runtime.image.dump");
 131         TestCommon.checkDump(output);
 132 
 133         // Test case 1):
 134         // test archived module graph objects are used with custome runtime image
 135         System.out.println("------------------- Test case 1 -------------------");
 136         String[] runCmd = {customJava.toString(),
 137                            use_whitebox_jar,
 138                            "-XX:SharedArchiveFile=./ArchivedModuleWithCustomImageTest.jsa",
 139                            "-cp",
 140                            appJar,
 141                            "-Xshare:on",
 142                            "-XX:+UnlockDiagnosticVMOptions",
 143                            "-XX:+WhiteBoxAPI",
 144                            "CheckArchivedModuleApp",
 145                            "yes",
 146                            "yes"};
 147         printCommand(runCmd);
 148         ProcessBuilder pbRun = new ProcessBuilder();
 149         pbRun.command(runCmd);
 150         output = TestCommon.executeAndLog(pbRun, "custom.runtime.image.run");
 151         output.shouldHaveExitValue(0);
 152 
 153 
 154         // Test case 2):
 155         // verify --show-module-resolution output
 156         System.out.println("------------------- Test case 2 -------------------");
 157 
 158         // myimage/bin/java -Xshare:off --show-module-resolution -version
 159         String[] showModuleCmd1 = {customJava.toString(),
 160                                    "-Xshare:off",
 161                                    "--show-module-resolution",
 162                                    "-version"};
 163         printCommand(showModuleCmd1);
 164         pbRun = new ProcessBuilder();
 165         pbRun.command(showModuleCmd1);
 166         output = TestCommon.executeAndLog(
 167             pbRun, "custom.runtime.image.showModuleResolution.nocds");
 168         output.shouldHaveExitValue(0);
 169         String moduleResolutionOut1 = output.getStdout();
 170 
 171         // myimage/bin/java -Xshare:on --show-module-resolution -version
 172         //    -XX:SharedArchiveFile=./ArchivedModuleWithCustomImageTest.jsa
 173         String[] showModuleCmd2 = {
 174             customJava.toString(),
 175             "-XX:SharedArchiveFile=./ArchivedModuleWithCustomImageTest.jsa",
 176             "-Xshare:on",
 177             "--show-module-resolution",
 178             "-version"};
 179         printCommand(showModuleCmd2);
 180         pbRun = new ProcessBuilder();
 181         pbRun.command(showModuleCmd2);
 182         output = TestCommon.executeAndLog(
 183             pbRun, "custom.runtime.image.showModuleResolution.cds");
 184         if (output.getStderr().contains("sharing")) {
 185             String moduleResolutionOut2 = output.getStdout();
 186             TestCommon.checkOutputStrings(
 187                 moduleResolutionOut1, moduleResolutionOut2, "\n");
 188         }
 189     }
 190 
 191     private static void printCommand(String opts[]) {
 192         StringBuilder cmdLine = new StringBuilder();
 193         for (String cmd : opts)
 194             cmdLine.append(cmd).append(' ');
 195         System.out.println("Command line: [" + cmdLine.toString() + "]");
 196     }
 197 }