提交 33bb7b5d 编写于 作者: F fparain

7104647: Adding a diagnostic command framework

Reviewed-by: mchung, dholmes
上级 3d1dadfe
......@@ -320,6 +320,7 @@ TOOLS = \
sun/tools/jar \
sun/tools/java \
sun/tools/javac \
sun/tools/jcmd \
sun/tools/jps \
sun/tools/jstat \
sun/tools/jstatd \
......@@ -432,6 +433,7 @@ NOTJRETOOLS = \
apt$(EXE_SUFFIX) \
javah$(EXE_SUFFIX) \
javap$(EXE_SUFFIX) \
jcmd$(EXE_SUFFIX) \
jdb$(EXE_SUFFIX) \
jps$(EXE_SUFFIX) \
jrunscript$(EXE_SUFFIX) \
......@@ -535,6 +537,7 @@ $(NOT_RT_JAR_LIST): FRC
$(ECHO) "sun/tools/javac/" >> $@
$(ECHO) "com/sun/tools/classfile/" >> $@
$(ECHO) "com/sun/tools/javap/" >> $@
$(ECHO) "sun/tools/jcmd/" >> $@
$(ECHO) "sun/tools/jconsole/" >> $@
$(ECHO) "sun/tools/jps/" >> $@
$(ECHO) "sun/tools/jstat/" >> $@
......
......@@ -54,6 +54,9 @@ SUNWprivate_1.1 {
Java_sun_management_GcInfoBuilder_getLastGcInfo0;
Java_sun_management_GcInfoBuilder_getNumGcExtAttributes;
Java_sun_management_HotSpotDiagnostic_dumpHeap;
Java_sun_management_HotSpotDiagnostic_executeDiagnosticCommand0;
Java_sun_management_HotSpotDiagnostic_getDiagnosticCommandInfo0;
Java_sun_management_HotSpotDiagnostic_getDiagnosticCommands0;
Java_sun_management_HotspotThread_getInternalThreadCount;
Java_sun_management_HotspotThread_getInternalThreadTimes0;
Java_sun_management_MemoryImpl_getMemoryManagers0;
......
......@@ -64,6 +64,7 @@ $(call make-launcher, javac, com.sun.tools.javac.Main, , )
$(call make-launcher, javadoc, com.sun.tools.javadoc.Main, , )
$(call make-launcher, javah, com.sun.tools.javah.Main, , )
$(call make-launcher, javap, com.sun.tools.javap.Main, , )
$(call make-launcher, jcmd, sun.tools.jcmd.JCmd, , )
$(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \
-J-Djconsole.showOutputViewer, )
$(call make-launcher, jdb, com.sun.tools.example.debug.tty.TTY, , )
......
......@@ -42,6 +42,7 @@ AUTO_FILES_JAVA_DIRS = \
sun/tools/jstack \
sun/tools/jstat \
sun/tools/jstatd \
sun/tools/jcmd \
com/sun/tools/hat \
com/sun/tools/script/shell \
sun/jvmstat
......
." Copyright (c) 2011, 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.
."
.TH jcmd 1 "22 Novembre 2011"
.LP
.SH "Name"
jcmd \- Diagnostic Command
.br
.LP
.SH "SYNOPSIS"
.LP
.nf
\f3
.fl
\fP\f3jcmd\fP [ option ]
.fl
\f3jcmd\fP <\fIpid\fR | \fImain class\fR> PerfCounter.print
.fl
\f3jcmd\fP <\fIpid\fR | \fImain class\fR> \fIcommand\fR [\fIarguments\fR]
.fl
\f3jcmd\fP <\fIpid\fR | \fImain class\fR> -f \fIfile\fR
.fl
.fl
.fi
.LP
.SH "DESCRIPTION"
.LP
.LP
\f3jcmd\fP is a utility to send diagnostic command requests to a Java
Virtual Machine supporting this feature. Used without arguments or with the \-l option, jcmd prints the list of running Java processes with their process id, their main class and their command line arguments. When a process id is specified on the command line, jcmd sends the diagnostic command request to the process with this id. When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes with this main class. With the PerfCounter.print argument, jcmd prints the performance counters available on the targeted Java process(es). With the \-f option, jcmd sends to the targeted Java process(es) the diagnostic commands stored in the file \fIfile\fR.
.LP
\fP
.fi
.SH "OPTIONS"
.LP
.LP
Options are mutually exclusive. Options, if used, should follow immediately after the command name.
.LP
.RS 3
.TP 3
\-l
prints the list of running Java processes with their process id, their
main class and their command line arguments.
.TP 3
\-h
prints a help message.
.br
.br
.TP 3
\-help
prints a help message
.br
.RE
.LP
.SH "PARAMETERS"
.LP
.RS 3
.TP 3
\fIpid\fR
Identifies the process which will receive the diagnostic command requests. The process must be a Java process. To get a list of Java processes running on a machine, jps(1) or jcmd(1) may be used.
.RE
.LP
.RS 3
.TP 3
\fImain class\fR
Main class of the process which will receive the diagnostic command requests. If several running Java processes share this main class, the diagnostic command request will be sent to all these processes. To get a list of Java processes running on a machine, jps(1) or jcmd(1) may be used.
.RE
.RS 3
.TP 3
\fIcommand\fR [\fIarguments\fR]
Invoke the diagnostic command called \fIcommand\fR on the targeted Java
process(es). The list of available diagnostic commands for a given
process can be obtained by invoking the 'help' command on this process.
Each diagnostic command has its own set of \fIarguments\fR which can be
obtained by invoking the 'help' command followed by the command name.
.RE
.RS 3
.TP 3
\fIPerfCounter.print\fR
Print the performance counters available on the targeted Java
process(es). The list of performance counters may vary with the Java
process.
.RE
.RS 3
.TP 3
\fI-f file\fR
Read commands from \fIfile\fR and invoke them on the targeted Java
process(es). In \fIfile\fR, each command must be written on a single line.
Lines starting with # are ignored. Processing of \fIfile\fR ends when
all lines have been invoked or when a line containing the 'stop' keyword
is read.
.LP
.SH "SEE ALSO"
.LP
.RS 3
.TP 2
o
jps(1)
.RE
/*
* Copyright (c) 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.management;
import java.beans.ConstructorProperties;
/**
* Diagnostic Command Argument information. It contains the description
* of one parameter of the diagnostic command. A parameter can either be an
* option or an argument. Options are identified by the option name while
* arguments are identified by their position in the command line. The generic
* syntax of a diagnostic command is:
* <blockquote>
* &lt;command name&gt; [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
* </blockquote>
* Example:
* <blockquote>
* command_name option1=value1 option2=value argumentA argumentB argumentC
* </blockquote>
* In this command line, the diagnostic command receives five parameters, two
* options named {@code option1} and {@code option2}, and three arguments.
* argumentA's position is 0, argumentB's position is 1 and argumentC's
* position is 2.
*
* @author Frederic Parain
* @since 7u4
*/
public class DiagnosticCommandArgumentInfo {
private final String name;
private final String description;
private final String type;
private final String defaultValue;
private final boolean mandatory;
private final boolean option;
private final int position;
/**
* Returns the argument name
*
* @return the argument name
*/
public String getName() {
return name;
}
/**
* Returns the argument description
*
* @return the argument description
*/
public String getDescription() {
return description;
}
/**
* Returns the argument type
*
* @return the argument type
*/
public String getType() {
return type;
}
/**
* Returns the default value as a String if a default value
* is defined, null otherwise.
*
* @return the default value as a String if a default value
* is defined, null otherwise.
*/
public String getDefault() {
return defaultValue;
}
/**
* Returns {@code true} if the argument is mandatory,
* {@code false} otherwise
*
* @return {@code true} if the argument is mandatory,
* {@code false} otherwise
*/
public boolean isMandatory() {
return mandatory;
}
/**
* Returns {@code true} if the argument is an option,
* {@code false} otherwise. Options have to be specified using the
* &lt;key&gt;=&lt;value&gt; syntax on the command line, while other
* arguments are specified with a single &lt;value&gt; field and are
* identified by their position on command line.
*
* @return {@code true} if the argument is an option,
* {@code false} otherwise
*/
public boolean isOption() {
return option;
}
/**
* Returns the expected position of this argument if it is not an option,
* -1 otherwise. Argument position if defined from left to right,
* starting at zero and ignoring the diagnostic command name and
* options.
*
* @return the expected position of this argument if it is not an option,
* -1 otherwise.
*/
public int getPosition() {
return position;
}
@ConstructorProperties({"name","description","type","default",
"mandatory","option","position"})
public DiagnosticCommandArgumentInfo(String name, String description,
String type, String defaultValue,
boolean mandatory, boolean option,
int position) {
this.name = name;
this.description = description;
this.type = type;
this.defaultValue = defaultValue;
this.mandatory = mandatory;
this.option = option;
this.position = position;
}
}
/*
* Copyright (c) 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.management;
import java.beans.ConstructorProperties;
import java.util.List;
/**
* Diagnostic command information. It contains the description of a
* diagnostic command.
*
* @author Frederic Parain
* @since 7u4
*/
public class DiagnosticCommandInfo {
private final String name;
private final String description;
private final String impact;
private final boolean enabled;
private final List<DiagnosticCommandArgumentInfo> arguments;
/**
* Returns the diagnostic command name
*
* @return the diagnostic command name
*/
public String getName() {
return name;
}
/**
* Returns the diagnostic command description
*
* @return the diagnostic command description
*/
public String getDescription() {
return description;
}
/**
* Returns the potential impact of the diagnostic command execution
* on the Java virtual machine behavior
*
* @return the potential impact of the diagnostic command execution
* on the Java virtual machine behavior
*/
public String getImpact() {
return impact;
}
/**
* Returns {@code true} if the diagnostic command is enabled,
* {@code false} otherwise. The enabled/disabled
* status of a diagnostic command can evolve during
* the lifetime of the Java virtual machine.
*
* @return {@code true} if the diagnostic command is enabled,
* {@code false} otherwise
*/
public boolean isEnabled() {
return enabled;
}
/**
* Returns the list of the diagnostic command arguments description.
* If the diagnostic command has no arguments, it returns an empty list.
*
* @return a list of the diagnostic command arguments description
*/
public List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
return arguments;
}
@ConstructorProperties({"name", "description","impact","enabled",
"argumentsInfo"})
public DiagnosticCommandInfo(String name, String description,
String impact, boolean enabled,
List<DiagnosticCommandArgumentInfo> arguments)
{
this.name = name;
this.description = description;
this.impact = impact;
this.enabled = enabled;
this.arguments = arguments;
}
}
/*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 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
......@@ -25,11 +25,18 @@
package com.sun.management;
import java.util.List;
import java.lang.management.PlatformManagedObject;
/**
* Diagnostic management interface for the HotSpot Virtual Machine.
* The diagnostic MBean is registered to the platform MBeanServer
*
* <p>{@linkplain #getDiagnosticCommands Diagnostic commands}
* are actions that can be invoked dynamically and
* executed in a target Java virtual machine, mainly for troubleshooting
* and diagnosis.
*
* <p>The diagnostic MBean is registered to the platform MBeanServer
* as are other platform MBeans.
*
* <p>The <tt>ObjectName</tt> for uniquely identifying the diagnostic
......@@ -41,6 +48,9 @@ import java.lang.management.PlatformManagedObject;
* It can be obtained by calling the
* {@link PlatformManagedObject#getObjectName} method.
*
* All methods throw a {@code NullPointerException} if any input argument is
* {@code null} unless it's stated otherwise.
*
* @see ManagementFactory#getPlatformMXBeans(Class)
*/
public interface HotSpotDiagnosticMXBean extends PlatformManagedObject {
......@@ -101,9 +111,113 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject {
* @throws IllegalArgumentException if the VM option is not writeable.
* @throws NullPointerException if name or value is <tt>null</tt>.
*
* @throws java.security.SecurityException
* @throws java.lang.SecurityException
* if a security manager exists and the caller does not have
* ManagementPermission("control").
*/
public void setVMOption(String name, String value);
/**
* Returns the {@linkplain DiagnosticCommandInfo#getName() names}
* of all diagnostic commands.
* A diagnostic command is an action that can be invoked dynamically
* mainly for troubleshooting and diagnosis. The list of diagnostic
* commands may change at runtime. A diagnostic command may be
* {@linkplain DiagnosticCommandInfo#isEnabled disabled} but will
* not be removed from a previously returned list.
*
* @return the names of all diagnostic commands.
*
* @since 7u4
*/
public List<String> getDiagnosticCommands();
/**
* Returns a {@code DiagnosticCommandInfo} object describing the
* diagnostic command of the specified name {@code command}
*
* @param command a diagnostic command name
* @return a {@code DiagnosticCommandInfo} object
* @throws java.lang.IllegalArgumentException if the {@code command}
* doesn't match any diagnostic command registered in the
* targeted Java virtual machine.
*
* @since 7u4
*/
public DiagnosticCommandInfo getDiagnosticCommandInfo(String command);
/**
* Returns a list of {@code DiagnosticCommandInfo} object describing
* all diagnostic commands available on the targeted Java virtual machine
*
* @return a list of {@code DiagnosticCommandInfo} objects
*
* @since 7u4
*/
public List<DiagnosticCommandInfo> getDiagnosticCommandInfo();
/**
* Returns a list of {@code DiagnosticCommandInfo} object describing
* all diagnostic commands specified in the {@code commands} list.
*
* @param commands {@code List} of {@code String} containing diagnostic
* command names
* @return a {@code List} of {@code DiagnosticCommandInfo} objects
*
* @throws java.lang.IllegalArgumentException if at least one
* command specified in the {@code commands } list
* doesn't match any diagnostic command registered in the
* targeted Java virtual machine.
*
* @since 7u4
*/
public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(List<String> commands);
/**
* Executes the command line {@code commandLine}. The command line must
* start with a diagnostic command name, optionally followed by parameters.
* Each command has its own syntax but the generic syntax for a diagnostic
* command line is:
* <blockquote>
* &lt;command name&gt; [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
* </blockquote>
*
* @param commandLine command line to execute
* @return a {@code String} object containing the diagnostic command
* output.
*
* @throws java.lang.IllegalArgumentException if the command line doesn't
* match any diagnostic command registered in the virtual machine
* of if the parameters don't match the diagnostic command syntax.
* @throws java.lang.SecurityException
* if a security manager exists and the caller does not have
* ManagementPermission("control").
*
* @since 7u4
*/
public String execute(String commandLine);
/**
* Invokes the diagnostic command named {@code cmd} with the parameters
* specified in {@code args}. Each command has its own syntax but
* the generic syntax for parameters is:
* <blockquote>
* [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
* </blockquote>
*
* @param cmd a diagnostic command name
* @param args the command parameters
* @return a {@code String} object containing the diagnostic command
* output.
*
* @throws java.lang.IllegalArgumentException if the command line doesn't
* match any diagnostic command registered in the virtual machine
* of if the parameters don't match the diagnostic command syntax.
* @throws java.lang.SecurityException
* if a security manager exists and the caller does not have
* ManagementPermission("control").
*
* @since 7u4
*/
public String execute(String cmd, String... args);
}
/*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 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
......@@ -27,9 +27,13 @@ package sun.management;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.management.ObjectName;
import com.sun.management.DiagnosticCommandInfo;
import com.sun.management.DiagnosticCommandArgumentInfo;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
......@@ -116,7 +120,54 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
}
}
public List<String> getDiagnosticCommands() {
String[] commands = getDiagnosticCommands0();
return commands == null ? Collections.<String>emptyList() :
Arrays.asList(commands);
}
public DiagnosticCommandInfo getDiagnosticCommandInfo(String command) {
String[] array = new String[] { command };
return getDiagnosticCommandInfo0(array)[0];
}
public List<DiagnosticCommandInfo> getDiagnosticCommandInfo() {
String[] commands = getDiagnosticCommands0();
return Arrays.asList(getDiagnosticCommandInfo0(commands));
}
public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(
List<String> commands) {
return Arrays.asList(getDiagnosticCommandInfo0(
commands.toArray(new String[commands.size()])));
}
public String execute(String command) {
Util.checkControlAccess();
return executeDiagnosticCommand0(command);
}
public String execute(String cmd, String... arguments) {
if(cmd == null) {
throw new NullPointerException("Missing command name");
}
StringBuilder sb = new StringBuilder();
sb.append(cmd);
sb.append(" ");
for(String arg : arguments) {
sb.append(arg);
sb.append(" ");
}
return execute(sb.toString());
}
public ObjectName getObjectName() {
return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
}
private native String[] getDiagnosticCommands0();
private native DiagnosticCommandInfo[] getDiagnosticCommandInfo0(
String[] commands) throws IllegalArgumentException;
private native String executeDiagnosticCommand0(String command)
throws IllegalArgumentException;
}
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 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
......@@ -195,6 +195,10 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine {
return executeCommand("printflag", name);
}
public InputStream executeJCmd(String command) throws IOException {
return executeCommand("jcmd", command);
}
// -- Supporting methods
......
/*
* Copyright (c) 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package sun.tools.jcmd;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class Arguments {
private boolean listProcesses = false;
private boolean listCounters = false;
private boolean showUsage = false;
private int pid = -1;
private String command = null;
private String processSubstring;
public boolean isListProcesses() { return listProcesses; }
public boolean isListCounters() { return listCounters; }
public boolean isShowUsage() { return showUsage; }
public int getPid() { return pid; }
public String getCommand() { return command; }
public String getProcessSubstring() { return processSubstring; }
public Arguments(String[] args) {
if (args.length == 0 || args[0].equals("-l")) {
listProcesses = true;
return;
}
if (args[0].equals("-h") || args[0].equals("-help") ) {
showUsage = true;
return;
}
try {
pid = Integer.parseInt(args[0]);
} catch (NumberFormatException ex) {
// use as a partial class-name instead
if (args[0].charAt(0) != '-') {
// unless it starts with a '-'
processSubstring = args[0];
}
}
StringBuilder sb = new StringBuilder();
for (int i = 1; i < args.length; i++) {
if (args[i].equals("-f")) {
if (args.length == i + 1) {
throw new IllegalArgumentException(
"No file specified for parameter -f");
} else if (args.length == i + 2) {
try {
readCommandFile(args[i + 1]);
} catch(IOException e) {
throw new IllegalArgumentException(
"Could not read from file specified with -f option: "
+ args[i + 1]);
}
return;
} else {
throw new IllegalArgumentException(
"Options after -f are not allowed");
}
} else if (args[i].equals("PerfCounter.print")) {
listCounters = true;
} else {
sb.append(args[i]).append(" ");
}
}
if (listCounters != true && sb.length() == 0) {
throw new IllegalArgumentException("No command specified");
}
command = sb.toString().trim();
}
private void readCommandFile(String path) throws IOException {
try (BufferedReader bf = new BufferedReader(new FileReader(path));) {
StringBuilder sb = new StringBuilder();
String s;
while ((s = bf.readLine()) != null) {
sb.append(s).append("\n");
}
command = sb.toString();
}
}
public static void usage() {
System.out.println("Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>");
System.out.println(" or: jcmd -l ");
System.out.println(" or: jcmd -h ");
System.out.println(" ");
System.out.println(" command must be a valid jcmd command for the selected jvm. ");
System.out.println(" Use the command \"help\" to see which commands are available. ");
System.out.println(" If the pid is 0, commands will be sent to all Java processes. ");
System.out.println(" The main class argument will be used to match (either partially ");
System.out.println(" or fully) the class used to start Java. ");
System.out.println(" If no options are given, lists Java processes (same as -p). ");
System.out.println(" ");
System.out.println(" PerfCounter.print display the counters exposed by this process ");
System.out.println(" -f read and execute commands from the file ");
System.out.println(" -l list JVM processes on the local machine ");
System.out.println(" -h this help ");
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*com.sun.tools.attach.AttachNotSupportedException
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package sun.tools.jcmd;
import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;
import java.net.URISyntaxException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.jstat.JStatLogger;
import sun.jvmstat.monitor.Monitor;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.VmIdentifier;
public class JCmd {
public static void main(String[] args) {
Arguments arg = null;
try {
arg = new Arguments(args);
} catch (IllegalArgumentException ex) {
System.err.println("Error parsing arguments: " + ex.getMessage()
+ "\n");
Arguments.usage();
System.exit(1);
}
if (arg.isShowUsage()) {
Arguments.usage();
System.exit(1);
}
if (arg.isListProcesses()) {
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vmds) {
System.out.println(vmd.id() + " " + vmd.displayName());
}
System.exit(0);
}
List<String> pids = new ArrayList<String>();
if (arg.getPid() == 0) {
// find all VMs
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vmds) {
if (!isJCmdProcess(vmd)) {
pids.add(vmd.id());
}
}
} else if (arg.getProcessSubstring() != null) {
// use the partial class-name match
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vmds) {
if (isJCmdProcess(vmd)) {
continue;
}
try {
String mainClass = getMainClass(vmd);
if (mainClass != null
&& mainClass.indexOf(arg.getProcessSubstring()) != -1) {
pids.add(vmd.id());
}
} catch (MonitorException|URISyntaxException e) {
if (e.getMessage() != null) {
System.err.println(e.getMessage());
} else {
Throwable cause = e.getCause();
if ((cause != null) && (cause.getMessage() != null)) {
System.err.println(cause.getMessage());
} else {
e.printStackTrace();
}
}
}
}
if (pids.isEmpty()) {
System.err.println("Could not find any processes matching : '"
+ arg.getProcessSubstring() + "'");
System.exit(1);
}
} else if (arg.getPid() == -1) {
System.err.println("Invalid pid specified");
System.exit(1);
} else {
// Use the found pid
pids.add(arg.getPid() + "");
}
for (String pid : pids) {
System.out.println(pid + ":");
if (arg.isListCounters()) {
listCounters(pid);
} else {
try {
executeCommandForPid(pid, arg.getCommand());
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
private static void executeCommandForPid(String pid, String command)
throws AttachNotSupportedException, IOException,
UnsupportedEncodingException {
VirtualMachine vm = VirtualMachine.attach(pid);
// Cast to HotSpotVirtualMachine as this is an
// implementation specific method.
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) vm;
try (InputStream in = hvm.executeJCmd(command);) {
// read to EOF and just print output
byte b[] = new byte[256];
int n;
do {
n = in.read(b);
if (n > 0) {
String s = new String(b, 0, n, "UTF-8");
System.out.print(s);
}
} while (n > 0);
}
vm.detach();
}
private static void listCounters(String pid) {
// Code from JStat (can't call it directly since it does System.exit)
VmIdentifier vmId = null;
try {
vmId = new VmIdentifier(pid);
} catch (URISyntaxException e) {
System.err.println("Malformed VM Identifier: " + pid);
return;
}
try {
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1);
JStatLogger logger = new JStatLogger(monitoredVm);
logger.printSnapShot("\\w*", // all names
new AscendingMonitorComparator(), // comparator
false, // not verbose
true, // show unsupported
System.out);
monitoredHost.detach(monitoredVm);
} catch (MonitorException ex) {
ex.printStackTrace();
}
}
private static boolean isJCmdProcess(VirtualMachineDescriptor vmd) {
try {
String mainClass = getMainClass(vmd);
return mainClass != null && mainClass.equals(JCmd.class.getName());
} catch (URISyntaxException|MonitorException ex) {
return false;
}
}
private static String getMainClass(VirtualMachineDescriptor vmd)
throws URISyntaxException, MonitorException {
try {
String mainClass = null;
VmIdentifier vmId = new VmIdentifier(vmd.id());
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1);
mainClass = MonitoredVmUtil.mainClass(monitoredVm, true);
monitoredHost.detach(monitoredVm);
return mainClass;
} catch(NullPointerException e) {
// There is a potential race, where a running java app is being
// queried, unfortunately the java app has shutdown after this
// method is started but before getMonitoredVM is called.
// If this is the case, then the /tmp/hsperfdata_xxx/pid file
// will have disappeared and we will get a NullPointerException.
// Handle this gracefully....
return null;
}
}
/**
* Class to compare two Monitor objects by name in ascending order.
* (from jstat)
*/
static class AscendingMonitorComparator implements Comparator<Monitor> {
public int compare(Monitor m1, Monitor m2) {
String name1 = m1.getName();
String name2 = m2.getName();
return name1.compareTo(name2);
}
}
}
......@@ -48,7 +48,8 @@ enum {
JMM_VERSION_1_0 = 0x20010000,
JMM_VERSION_1_1 = 0x20010100, // JDK 6
JMM_VERSION_1_2 = 0x20010200, // JDK 7
JMM_VERSION = 0x20010201
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
JMM_VERSION = 0x20010202
};
typedef struct {
......@@ -188,6 +189,24 @@ typedef struct {
/* -1 indicates gc_ext_attribute_values is not big enough */
} jmmGCStat;
typedef struct {
const char* name;
const char* description;
const char* impact;
int num_arguments;
jboolean enabled;
} dcmdInfo;
typedef struct {
const char* name;
const char* description;
const char* type;
const char* default_string;
jboolean mandatory;
jboolean option;
int position;
} dcmdArgInfo;
typedef struct jmmInterface_1_ {
void* reserved1;
void* reserved2;
......@@ -293,9 +312,21 @@ typedef struct jmmInterface_1_ {
jlongArray ids,
jboolean lockedMonitors,
jboolean lockedSynchronizers);
void (JNICALL *SetGCNotificationEnabled) (JNIEnv *env,
jobject mgr,
jboolean enabled);
void (JNICALL *SetGCNotificationEnabled) (JNIEnv *env,
jobject mgr,
jboolean enabled);
jobjectArray (JNICALL *GetDiagnosticCommands) (JNIEnv *env);
void (JNICALL *GetDiagnosticCommandInfo)
(JNIEnv *env,
jobjectArray cmds,
dcmdInfo *infoArray);
void (JNICALL *GetDiagnosticCommandArgumentsInfo)
(JNIEnv *env,
jstring commandName,
dcmdArgInfo *infoArray);
jstring (JNICALL *ExecuteDiagnosticCommand)
(JNIEnv *env,
jstring command);
} JmmInterface;
#ifdef __cplusplus
......
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 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
......@@ -34,3 +34,141 @@ Java_sun_management_HotSpotDiagnostic_dumpHeap
{
jmm_interface->DumpHeap0(env, outputfile, live);
}
JNIEXPORT jobjectArray JNICALL
Java_sun_management_HotSpotDiagnostic_getDiagnosticCommands0
(JNIEnv *env, jobject dummy)
{
if ((jmm_version > JMM_VERSION_1_2_1)
|| (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=2))) {
return jmm_interface->GetDiagnosticCommands(env);
}
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"Diagnostic commands are not supported by this VM");
}
jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
int num_arg) {
int i;
jobject obj;
jobjectArray result;
dcmdArgInfo* dcmd_arg_info_array;
jclass dcmdArgInfoCls;
jclass arraysCls;
jmethodID mid;
jobject resultList;
dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
if (dcmd_arg_info_array == NULL) {
return NULL;
}
jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
dcmd_arg_info_array);
dcmdArgInfoCls = (*env)->FindClass(env,
"com/sun/management/DiagnosticCommandArgumentInfo");
result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
if (result == NULL) {
free(dcmd_arg_info_array);
return NULL;
}
for (i=0; i<num_arg; i++) {
obj = JNU_NewObjectByName(env,
"com/sun/management/DiagnosticCommandArgumentInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZI)V",
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
dcmd_arg_info_array[i].default_string == NULL ? NULL:
(*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
dcmd_arg_info_array[i].mandatory,
dcmd_arg_info_array[i].option,
dcmd_arg_info_array[i].position);
if (obj == NULL) {
free(dcmd_arg_info_array);
return NULL;
}
(*env)->SetObjectArrayElement(env, result, i, obj);
}
free(dcmd_arg_info_array);
arraysCls = (*env)->FindClass(env, "java/util/Arrays");
mid = (*env)->GetStaticMethodID(env, arraysCls,
"asList", "([Ljava/lang/Object;)Ljava/util/List;");
resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
return resultList;
}
/* Throws IllegalArgumentException if at least one the diagnostic command
* passed in argument is not supported by the JVM
*/
JNIEXPORT jobjectArray JNICALL
Java_sun_management_HotSpotDiagnostic_getDiagnosticCommandInfo0
(JNIEnv *env, jobject dummy, jobjectArray commands)
{
int i;
jclass dcmdInfoCls;
jobject result;
jobjectArray args;
jobject obj;
if (commands == NULL) {
JNU_ThrowNullPointerException(env, "Invalid String Array");
return NULL;
}
if ((jmm_version > JMM_VERSION_1_2_1)
|| (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=2))) {
jsize num_commands = (*env)->GetArrayLength(env, commands);
dcmdInfo* dcmd_info_array = (dcmdInfo*) malloc(num_commands *
sizeof(dcmdInfo));
if (dcmd_info_array == NULL) {
JNU_ThrowOutOfMemoryError(env, NULL);
}
jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
dcmdInfoCls = (*env)->FindClass(env,
"com/sun/management/DiagnosticCommandInfo");
result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
if (result == NULL) {
free(dcmd_info_array);
JNU_ThrowOutOfMemoryError(env, 0);
}
for (i=0; i<num_commands; i++) {
args = getDiagnosticCommandArgumentInfoArray(env,
(*env)->GetObjectArrayElement(env,commands,i),
dcmd_info_array[i].num_arguments);
if (args == NULL) {
free(dcmd_info_array);
JNU_ThrowOutOfMemoryError(env, 0);
}
obj = JNU_NewObjectByName(env,
"com/sun/management/DiagnosticCommandInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
(*env)->NewStringUTF(env,dcmd_info_array[i].name),
(*env)->NewStringUTF(env,dcmd_info_array[i].description),
(*env)->NewStringUTF(env,dcmd_info_array[i].impact),
dcmd_info_array[i].enabled,
args);
if (obj == NULL) {
free(dcmd_info_array);
JNU_ThrowOutOfMemoryError(env, 0);
}
(*env)->SetObjectArrayElement(env, result, i, obj);
}
free(dcmd_info_array);
return result;
}
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"Diagnostic commands are not supported by this VM");
}
/* Throws IllegalArgumentException if the diagnostic command
* passed in argument is not supported by the JVM
*/
JNIEXPORT jstring JNICALL
Java_sun_management_HotSpotDiagnostic_executeDiagnosticCommand0
(JNIEnv *env, jobject dummy, jstring command) {
if((jmm_version > JMM_VERSION_1_2_1 )
|| (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=2))) {
return jmm_interface->ExecuteDiagnosticCommand(env, command);
}
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"Diagnostic commands are not supported by this VM");
}
." Copyright (c) 2011, 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.
."
.TH jcmd 1 "22 Novembre 2011"
.LP
.SH "Name"
jcmd \- Diagnostic Command
.br
.LP
.SH "SYNOPSIS"
.LP
.nf
\f3
.fl
\fP\f3jcmd\fP [ option ]
.fl
\f3jcmd\fP <\fIpid\fR | \fImain class\fR> PerfCounter.print
.fl
\f3jcmd\fP <\fIpid\fR | \fImain class\fR> \fIcommand\fR [\fIarguments\fR]
.fl
\f3jcmd\fP <\fIpid\fR | \fImain class\fR> -f \fIfile\fR
.fl
.fl
.fi
.LP
.SH "DESCRIPTION"
.LP
.LP
\f3jcmd\fP is a utility to send diagnostic command requests to a Java
Virtual Machine supporting this feature. Used without arguments or with the \-l option, jcmd prints the list of running Java processes with their process id, their main class and their command line arguments. When a process id is specified on the command line, jcmd sends the diagnostic command request to the process with this id. When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes with this main class. With the PerfCounter.print argument, jcmd prints the performance counters available on the targeted Java process(es). With the \-f option, jcmd sends to the targeted Java process(es) the diagnostic commands stored in the file \fIfile\fR.
.LP
\fP
.fi
.SH "OPTIONS"
.LP
.LP
Options are mutually exclusive. Options, if used, should follow immediately after the command name.
.LP
.RS 3
.TP 3
\-l
prints the list of running Java processes with their process id, their
main class and their command line arguments.
.TP 3
\-h
prints a help message.
.br
.br
.TP 3
\-help
prints a help message
.br
.RE
.LP
.SH "PARAMETERS"
.LP
.RS 3
.TP 3
\fIpid\fR
Identifies the process which will receive the diagnostic command requests. The process must be a Java process. To get a list of Java processes running on a machine, jps(1) or jcmd(1) may be used.
.RE
.LP
.RS 3
.TP 3
\fImain class\fR
Main class of the process which will receive the diagnostic command requests. If several running Java processes share this main class, the diagnostic command request will be sent to all these processes. To get a list of Java processes running on a machine, jps(1) or jcmd(1) may be used.
.RE
.RS 3
.TP 3
\fIcommand\fR [\fIarguments\fR]
Invoke the diagnostic command called \fIcommand\fR on the targeted Java
process(es). The list of available diagnostic commands for a given
process can be obtained by invoking the 'help' command on this process.
Each diagnostic command has its own set of \fIarguments\fR which can be
obtained by invoking the 'help' command followed by the command name.
.RE
.RS 3
.TP 3
\fIPerfCounter.print\fR
Print the performance counters available on the targeted Java
process(es). The list of performance counters may vary with the Java
process.
.RE
.RS 3
.TP 3
\fI-f file\fR
Read commands from \fIfile\fR and invoke them on the targeted Java
process(es). In \fIfile\fR, each command must be written on a single line.
Lines starting with # are ignored. Processing of \fIfile\fR ends when
all lines have been invoked or when a line containing the 'stop' keyword
is read.
.LP
.SH "SEE ALSO"
.LP
.RS 3
.TP 2
o
jps(1)
.RE
/*
* Copyright (c) 2011, 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.
*/
/*
* @test
* @bug 7104647
* @summary Basic Test for HotSpotDiagnosticMXBean.execute()
* @author Frederic Parain
*
* @run main ExecuteDiagnosticCommand
*/
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
import java.lang.management.ManagementFactory;
import java.util.List;
import javax.management.MBeanServer;
public class ExecuteDiagnosticCommand {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=HotSpotDiagnostic";
public static void main(String[] args) throws Exception {
HotSpotDiagnosticMXBean mbean =
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
executeDiagnosticCommand(mbean);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
HotSpotDiagnosticMXBean.class);
executeDiagnosticCommand(mbean);
}
private static void executeDiagnosticCommand(HotSpotDiagnosticMXBean mbean) {
String s = mbean.execute("help help");
System.out.println(s);
s = mbean.execute("help", "help");
System.out.println(s);
String tab[] = { "help"};
s = mbean.execute("help", tab);
System.out.println(s);
}
}
/*
* Copyright (c) 2011, 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.
*/
/*
* @test
* @bug 7104647
* @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticCommandInfo()
* @author Frederic Parain
*
* @run main GetDiagnosticCommandInfo
*/
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.DiagnosticCommandInfo;
import com.sun.management.DiagnosticCommandArgumentInfo;
import com.sun.management.VMOption;
import java.lang.management.ManagementFactory;
import java.util.List;
import javax.management.MBeanServer;
public class GetDiagnosticCommandInfo {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=HotSpotDiagnostic";
public static void main(String[] args) throws Exception {
HotSpotDiagnosticMXBean mbean =
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
checkDiagnosticCommandArguments(mbean);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
HotSpotDiagnosticMXBean.class);
checkDiagnosticCommandArguments(mbean);
}
private static void checkDiagnosticCommandArguments(HotSpotDiagnosticMXBean mbean) {
// check getDiagnosticCommandInfo()
StringBuilder sb = new StringBuilder();
List<DiagnosticCommandInfo> infoList = mbean.getDiagnosticCommandInfo();
for(DiagnosticCommandInfo info : infoList) {
printCommandInfo(info,sb);
}
// check getDiagnosticCommandInfo(List<String>)
List<String> commands = mbean.getDiagnosticCommands();
List<DiagnosticCommandInfo> list2 =
mbean.getDiagnosticCommandInfo(commands);
for(DiagnosticCommandInfo info : list2) {
printCommandInfo(info,sb);
}
// check getDiagnosticCommandInfo(String)
for(String cmd : commands) {
DiagnosticCommandInfo info2 = mbean.getDiagnosticCommandInfo(cmd);
printCommandInfo(info2,sb);
}
System.out.println(sb.toString());
}
private static void printCommandInfo(DiagnosticCommandInfo info,
StringBuilder sb) {
sb.append("\t").append(info.getName()).append(":\n");
sb.append("\t\tDescription=").append(info.getDescription()).append("\n");
sb.append("\t\tImpact=").append(info.getImpact()).append("\n");
sb.append("\t\tStatus=");
if (info.isEnabled()) {
sb.append("Enabled\n");
} else {
sb.append("Disbled\n");
}
sb.append("\t\tArguments=");
for(DiagnosticCommandArgumentInfo arg : info.getArgumentsInfo()) {
printArgumentInfo(arg,sb);
}
}
private static void printArgumentInfo(DiagnosticCommandArgumentInfo info,
StringBuilder sb) {
sb.append("\t\t\t").append(info.getName()).append(":\n");
sb.append("\t\t\t\tType=").append(info.getType()).append("\n");
sb.append("\t\t\t\tDescription=").append(info.getDescription()).append("\n");
if(info.getDefault() != null) {
sb.append("\t\t\t\tDefault=").append(info.getDefault()).append("\n");
}
if(info.isMandatory()) {
sb.append("\t\t\t\tMandatory\n");
} else {
sb.append("\t\t\t\tOptional\n");
}
if(info.isOption()) {
sb.append("\t\t\t\tIs an option\n");
} else {
sb.append("\t\t\t\tIs an argument expected at position");
sb.append(info.getPosition());
sb.append("\n");
}
}
}
/*
* Copyright (c) 2011, 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.
*/
/*
* @test
* @bug 7104647
* @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticCommands()
* @author Frederic Parain
*
* @run main GetDiagnosticCommands
*/
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
import java.lang.management.ManagementFactory;
import java.util.List;
import javax.management.MBeanServer;
public class GetDiagnosticCommands {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=HotSpotDiagnostic";
public static void main(String[] args) throws Exception {
HotSpotDiagnosticMXBean mbean =
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
checkDiagnosticCommands(mbean);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
HotSpotDiagnosticMXBean.class);
checkDiagnosticCommands(mbean);
}
private static void checkDiagnosticCommands(HotSpotDiagnosticMXBean mbean) {
List<String> commands = mbean.getDiagnosticCommands();
System.out.println("Commands:");
for (String cmd : commands) {
System.out.println(cmd);
}
}
}
......@@ -34,6 +34,7 @@
# JMAP - jmap utility
# JPS - jps utility
# JSTACK - jstack utility
# JCMD - jcmd utility
# OS - operating system name
# PATTERN_EOL - grep or sed end-of-line pattern
# PATTERN_WS - grep or sed whitespace pattern
......@@ -72,6 +73,7 @@ JINFO="${TESTJAVA}/bin/jinfo"
JMAP="${TESTJAVA}/bin/jmap"
JPS="${TESTJAVA}/bin/jps"
JSTACK="${TESTJAVA}/bin/jstack"
JCMD="${TESTJAVA}/bin/jcmd"
isCygwin=false
isMKS=false
......
help
For more information about a specific command use 'help <command>'. With no argument this will show a list of available commands. 'help all' will show help for all commands.
Impact: Low:
Syntax : help [options] [<command name>]
Arguments:
command name : [optional] The name of the command for which we want help (STRING, no default value)
Options: (options must be specified using the <key> or <key>=<value> syntax)
-all : [optional] Show help for all commands (BOOLEAN, false)
#
# Copyright (c) 2011, 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.
#
# @test
# @bug 7104647
# @run shell jcmd-Defaults.sh
# @summary Test that output of 'jcmd' and 'jcmd -l' match a specific pattern
JCMD="${TESTJAVA}/bin/jcmd"
${JCMD} 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
${JCMD} -l 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
#!/bin/sh
#
# Copyright (c) 2011, 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.
#
# @test
# @bug 7104647
# @summary Unit test for jcmd utility
#
# @library ../common
# @build SimpleApplication ShutdownSimpleApplication
# @run shell jcmd-f.sh
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# Start application and use PORTFILE for coordination
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication SimpleApplication "${PORTFILE}"
# all return statuses are checked in this test
set +e
failed=0
# -f <script>
rm -f jcmd.out 2>/dev/null
${JCMD} $appJavaPid -f ${TESTSRC}/dcmd-script.txt | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
echo jcmd.out
diff -w jcmd.out ${TESTSRC}/help_help.out
if [ $? != 0 ]; then
echo "Output of jcmd [pid] -f dcmd-script.txt differ from expected output. Failed."
rm -f jcmd.out 2>/dev/null
failed=1;
fi
set -e
stopApplication "${PORTFILE}"
waitForApplication
exit $failed
#!/bin/sh
#
# Copyright (c) 2011, 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.
#
# @test
# @bug 7104647
# @summary Unit test for jcmd utility
#
# @library ../common
# @build SimpleApplication ShutdownSimpleApplication
# @run shell jcmd-help-help.sh
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# Start application and use PORTFILE for coordination
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication SimpleApplication "${PORTFILE}"
# all return statuses are checked in this test
set +e
failed=0
# help help
rm -f jcmd.out 2>/dev/null
${JCMD} $appJavaPid help help | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
echo jcmd.out
diff -w jcmd.out ${TESTSRC}/help_help.out
if [ $? != 0 ]; then
echo "Output of jcmd [pid] help help differ from expected output. Failed."
rm -f jcmd.out 2>/dev/null
failed=1;
fi
set -e
stopApplication "${PORTFILE}"
waitForApplication
exit $failed
#
# Copyright (c) 2011, 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.
#
# @test
# @bug 7104647
# @run shell jcmd-help.sh
# @summary Test that output of 'jcmd -h' matches the usage.out file
JCMD="${TESTJAVA}/bin/jcmd"
rm -f jcmd.out 2>/dev/null
${JCMD} -h > jcmd.out 2>&1
diff -w jcmd.out ${TESTSRC}/usage.out
if [ $? != 0 ]
then
echo "Output of jcmd -h differ from expected output. Failed."
rm -f jcmd.out 2>/dev/null
exit 1
fi
rm -f jcmd.out 2>/dev/null
${JCMD} -help > jcmd.out 2>&1
diff -w jcmd.out ${TESTSRC}/usage.out
if [ $? != 0 ]
then
echo "Output of jcmd -help differ from expected output. Failed."
rm -f jcmd.out 2>/dev/null
exit 1
fi
rm -f jcmd.out 2>/dev/null
exit 0
#!/bin/sh
#
# Copyright (c) 2011, 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.
#
# @test
# @bug 7104647
# @summary Unit test for jcmd utility
#
# @library ../common
# @build SimpleApplication ShutdownSimpleApplication
# @run shell jcmd-pid.sh
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# Start application and use PORTFILE for coordination
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication SimpleApplication "${PORTFILE}"
# all return statuses are checked in this test
set +e
failed=0
# help command
${JCMD} $appJavaPid help 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output1.awk
if [ $? != 0 ]; then failed=1; fi
# PerfCounter.list option
${JCMD} $appJavaPid PerfCounter.print 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output2.awk
if [ $? != 0 ]; then failed=1; fi
set -e
stopApplication "${PORTFILE}"
waitForApplication
exit $failed
#
BEGIN {
totallines=0; matched=0
}
# match on a main class name followed by arbitrary arguments
/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\.]*($| .*$)/ {
matched++;
}
# or match on a path name to a jar file followed by arbitraty arguments
# - note, jar files ending with ".jar" is only a convention, not a requirement.
#Theoretically, any valid file name could occur here.
/^[0-9]+ .*\.jar($| .*$)/ {
matched++;
}
# or match on the condition that the class name is not available
/^[0-9]+ -- process information unavailable$/ {
matched++;
}
{ totallines++; print $0 }
END {
if ((totallines > 0) && (matched == totallines)) {
exit 0
}
else {
exit 1
}
}
#
# section 0 = [PID]:
# section 1 = "The following commands are available:"
# section 2 = <list of commands, one command per line>
# section 3 = blank line
# section 4 = "For more information about a specific command use 'help <command>'."
BEGIN {
totallines=0; matched=0; section=0;
}
# match the first line (PID of the JVM followed by ':')
/^[0-9]+:/{
if(section==0) {
matched++;
section=1;
}
}
/^The following commands are available:$/{
if(section==1) {
matched++;
section=2;
}
}
# match a command name
/^[a-z|A-Z][a-z|A-Z|0-9|\.|_]*$/{
if(section==2) {
matched++;
}
}
/^$/{
if(section==2) {
matched++;
section=4;
}
}
/^For more information about a specific command use 'help <command>'\.$/{
if(section==4) {
matched++;
section=5;
}
}
{ totallines++; print $0 }
END {
if ((totallines > 0) && (matched == totallines)) {
exit 0
}
else {
exit 1
}
}
#
BEGIN {
totallines=0; matched=0
}
# match on counter name followed '=' and an arbitrary value
/^[a-z|A-Z][a-z|A-Z|0-9|\.|_]*=.*$/ {
matched++;
}
# or match the first line (PID of the JVM followed by ':')
/^[0-9]+:/ {
matched++;
}
{ totallines++; print $0 }
END {
if ((totallines > 0) && (matched == totallines)) {
exit 0
}
else {
exit 1
}
}
Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
or: jcmd -l
or: jcmd -h
command must be a valid jcmd command for the selected jvm.
Use the command "help" to see which commands are available.
If the pid is 0, commands will be sent to all Java processes.
The main class argument will be used to match (either partially
or fully) the class used to start Java.
If no options are given, lists Java processes (same as -p).
PerfCounter.print display the counters exposed by this process
-f read and execute commands from the file
-l list JVM processes on the local machine
-h this help
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册