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 }