1 /*
2  * Copyright (c) 2013, 2020, 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 import java.util.Arrays;
25 
26 import jdk.test.lib.Utils;
27 import jdk.test.lib.process.OutputAnalyzer;
28 import jdk.test.lib.process.ProcessTools;
29 import jdk.test.lib.JDKToolLauncher;
30 
31 /**
32  * Helper class for starting jcmd process.
33  * <pre>
34  * - jcmd will send diagnostic requests to the current java process:
35  *      jcmd pid_to_current_process PerfCounter.print
36  * - jcmd will be run without sending request to any JVM
37  *      jcmd -h
38  * </pre>
39  */
40 public final class JcmdBase {
41 
42     private static ProcessBuilder processBuilder = new ProcessBuilder();
43 
JcmdBase()44     private JcmdBase() {
45         // Private constructor to prevent class instantiation
46     }
47 
48     /**
49      * Sends the diagnostic command request to the current process
50      *
51      * @see #jcmd(boolean, String[], String[])
52      */
jcmd(String... jcmdArgs)53     public final static OutputAnalyzer jcmd(String... jcmdArgs)
54             throws Exception {
55         return jcmd(true, null, jcmdArgs);
56     }
57 
58     /**
59      * Sends the diagnostic command request to the current process.
60      * jcmd will be run with specified {@code vmArgs}.
61      *
62      * @see #jcmd(boolean, String[], String[])
63      */
jcmd(String[] vmArgs, String[] jcmdArgs)64     public final static OutputAnalyzer jcmd(String[] vmArgs,
65             String[] jcmdArgs) throws Exception {
66         return jcmd(true, vmArgs, jcmdArgs);
67     }
68 
69     /**
70      * Runs jcmd without sending request to any JVM
71      *
72      * @see #jcmd(boolean, String[], String[])
73      */
jcmdNoPid(String[] vmArgs, String[] jcmdArgs)74     public final static OutputAnalyzer jcmdNoPid(String[] vmArgs,
75             String[] jcmdArgs) throws Exception {
76         return jcmd(false, vmArgs, jcmdArgs);
77     }
78 
79     /**
80      * If {@code requestToCurrentProcess} is {@code true}
81      * sends a diagnostic command request to the current process.
82      * If {@code requestToCurrentProcess} is {@code false}
83      * runs jcmd without sending request to any JVM.
84      *
85      * @param requestToCurrentProcess
86      *            Defines if jcmd will send request to the current process
87      * @param vmArgs
88      *            jcmd will be run with VM arguments specified,
89      *            e.g. -XX:+UsePerfData
90      * @param jcmdArgs
91      *            jcmd will be run with option or command and its arguments
92      *            specified, e.g. VM.flags
93      * @return The output from {@link OutputAnalyzer} object
94      * @throws Exception
95      */
jcmd(boolean requestToCurrentProcess, String[] vmArgs, String[] jcmdArgs)96     private static final OutputAnalyzer jcmd(boolean requestToCurrentProcess,
97             String[] vmArgs, String[] jcmdArgs) throws Exception {
98         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd");
99         launcher.addVMArgs(Utils.getTestJavaOpts());
100         if (vmArgs != null) {
101             for (String vmArg : vmArgs) {
102                 launcher.addVMArg(vmArg);
103             }
104         }
105         if (requestToCurrentProcess) {
106             launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
107         }
108         if (jcmdArgs != null) {
109             for (String toolArg : jcmdArgs) {
110                 launcher.addToolArg(toolArg);
111             }
112         }
113         processBuilder.command(launcher.getCommand());
114         System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
115         OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
116         System.out.println(output.getOutput());
117 
118         return output;
119     }
120 
121 }
122