--- /dev/null 2018-01-25 15:56:53.000000000 -0800 +++ new/test/hotspot/jtreg/serviceability/jvmti/8161605/CanGenerateAllClassHook.java 2018-01-25 15:56:51.959681000 -0800 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.io.File; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.stream.Collectors; + +/** + * @test + * @bug 8161605 + * @summary Tests that jvmtiEnv::GetPotentialCapabilities returns the same value for + * can_generate_all_class_hook_events capability with CDS (-Xshare:on) + * at ONLOAD and LIVE phases + * @compile CanGenerateAllClassHook.java + * @run main/othervm/native CanGenerateAllClassHook + */ + +/* + * The simplest way to test is to use system classes.jsa, + * but we cannot rely on tested JRE/JDK has it. + * So the test runs 2 java process - + * 1st to generate custom shared archive file: + * java -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile= -Xshare:dump + * and 2nd to perform the actual testing using generated shared archive: + * java -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile= -Xshare:on + * -agentlib: CanGenerateAllClassHook + */ +public class CanGenerateAllClassHook { + + private static final String agentLib = "CanGenerateAllClassHook"; + + private static native int getClassHookAvail(); + private static native int getOnLoadClassHookAvail(); + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + // this is master run + + final File jsaFile = File.createTempFile(agentLib, ".jsa"); + jsaFile.deleteOnExit(); + final String jsaPath = jsaFile.getAbsolutePath(); + + int dumpResult = createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + jsaPath, + "-Xshare:dump") + .start() + .waitFor(); + if (dumpResult != 0) { + throw new RuntimeException("CDS generation failed: " + dumpResult); + } + log("CDS generation completed."); + + int testResult = createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=" + jsaPath, + "-Xshare:on", + // copy classpath + "-cp", System.getProperty("java.class.path"), + "-agentlib:" + agentLib, + // copy java.library.path + "-Djava.library.path=" + System.getProperty("java.library.path"), + // class to run + CanGenerateAllClassHook.class.getCanonicalName(), + // and arg + "test") + .start() + .waitFor(); + if (testResult != 0) { + throw new RuntimeException("test run failed: " + testResult); + } + log("Test PASSED."); + } else { + // this is test run + try { + System.loadLibrary(agentLib); + } catch (UnsatisfiedLinkError ex) { + System.err.println("Failed to load " + agentLib + " lib"); + System.err.println("java.library.path: " + System.getProperty("java.library.path")); + throw ex; + } + + final int onLoadValue = getOnLoadClassHookAvail(); + final int liveValue = getClassHookAvail(); + + log("onLoad = " + onLoadValue); + log("live= " + liveValue); + if (onLoadValue != liveValue) { + throw new RuntimeException("Inconsistent can_generate_all_class_hook_events value"); + } + } + } + + private static void log(String msg) { + System.out.println(msg); + System.out.flush(); + } + + private static boolean isWin() { + return System.getProperty("os.name").toLowerCase().startsWith("win"); + } + + private static String getJavaPath() { + // JTReg sets "test.jdk" property + String javaHome = System.getProperty("test.jdk"); + if (javaHome == null) { + log("'test.jdk' property is not set, using 'java.home' instead"); + // fallback (test is run manually) + javaHome = System.getProperty("java.home"); + if (javaHome == null) { + throw new RuntimeException("Could not detect java home"); + } + } + return Paths.get(javaHome, "bin", "java" + (isWin() ? ".exe" : "")).toAbsolutePath().toString(); + } + + private static ProcessBuilder createJavaProcessBuilder(String... args) { + ArrayList params = new ArrayList<>(); + params.add(getJavaPath()); + Collections.addAll(params, args); + + //log("CommandLine: " + params.stream().collect(Collectors.joining(" "))); + + return new ProcessBuilder(params.toArray(new String[params.size()])) + .inheritIO(); // inherit in/out/err + } +} +