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