The diagnostic command framework is fully implemented in native code
and relies on the HotSpot's internal exception mechanism.
The rational of a pure native implementation is to be able to execute
diagnostic commands even in critical situations like an OutOfMemory
error. All diagnostic commands are registered in a single list, and two
flags control the way a user can interact with them. The "hidden" flag
prevents a diagnostic command from appearing in the list of available
commands returned by the "help" command. However, it's still possible to
get the detailed help message for a hidden command with the "help
<command name>" syntax (but it requires to know the name of the hidden
command). The second flag is "enabled" and it controls if a command can
be invoked or not. When listed with the "help" commands, disabled
commands appear with a "[disabled]" label in their description. If the
user tries to invoke a disabled command, an error message is returned
and the command is not run. This error message can be customized on a
per command base. The framework just provides these two flags with their
semantic, it doesn't provide any policy or mechanism to set or modify
these flags. These actions will be delegated to the JVM or special
The DCmdParser class is an optional framework to help development of
argument parsers. It provides many features required by the diagnostic
command framework (generation of the help message or the argument
descriptions for the JMX interface) but all these features can easily be
re-implemented if a developer decides not to use the DCmdParser framework.
The DCmdParser class is relying on the DCmdArgument template. This
template must be used to define the different types of argument the
parser will have to handle. When a new specialization of the template is
done, three methods have to be provided:
void parse_value(const char *str,size_t len,TRAPS);
The parse_value() method is used to convert a string into an argument
value. The print_value() method is used to display the default value
(support for the detailed help message). The init_value() method is used
to initialize or reset the argument value. The destroy_value() method is
a clean-up method (useful when the argument has allocated some C-Heap
memory to store its value and this memory has to be freed before
destroying the DCmdArgument instance).
The DCmdParser makes a distinction between options and arguments.
Options are identified by a key name that must appear on the command
line, while argument are identified just by the position of the argument
on the command line. Options use the <key>=<value> syntax. In case of
boolean options, the '=<value>' part of the syntax can be omitted to set
the option to true. Arguments are just sequences characters delimited by
a separator character. This separator can be specified at runtime when
invoking the diagnostic command framework. If an argument contain a
character that could be used as a delimiter, it's possible to enclose
the argument between single or double quotes. Options are arguments are
instantiated using the same DCmdArgument class but they're registered
differently to the DCmdParser.
The JCmd interface
Diagnostic commands can also be invoked from outside the JVM process,
using the new 'jcmd' utility. The jcmd program uses the attach API
to connect to the JVM, send requests and receive results. The
jcmd utility must be launched on the same machine than the one running
the JVM (its a local tool). Launched without arguments, jcmd displays a
list of all JVMs running on the machine. The jcmd source code is in
the jdk repository like other existing j* tools.
To execute a diagnostic command in a particular JVM, the generic syntax is:
jcmd <pid_of_the_jvm> <command_name> [arguments]
The attachListener has been modified to recognized the jcmd requests.
When a jcmd request is identified, it is parsed to extract the command
name. The JVM performs a look up of this command in a list of registered
commands. To be executable by an external request, a diagnostic command
has to be registered. The registration is performed with the DCmdFactory
class (see services/management.cpp).
The JMX interface
The framework provides a JMX based interface to the diagnostic commands.
This interface allows remote invocation of diagnostic commands through a
The information related to the diagnostic commands are accessible
through new methods added to the com.sun.management.HotspotDiagnosticMXBean:
public List<String> getDiagnosticCommands();
public DiagnosticCommandInfo getDiagnosticCommandInfo(String command);
public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(List<String>
public List<DiagnosticCommandInfo> getDiagnosticCommandInfo();
public String execute(String commandLine) throws IllegalArgumentException ;
public String execute(String cmd, String... arguments)
If the DiagnosticCommandArgumentInfo instance describes an option,
isOption() returns true and getPosition() returns -1. Otherwise, when
the DiagnosticCommandArgumentInfo instance describes an argument,
isOption() returns false and getPosition() returns the expected position
for this argument. The position of an argument is defined relatively to
all arguments passed on the command line, options are not considered
when defining an argument position. The getDefault() method returns the
default value of the argument if a default has been defined, otherwise
it returns null.
The Diagnostic Commands
To avoid name collisions between diagnostic commands coming from
different projects, use of a flat name space should be avoided and
a more structured organization is recommended. The framework itself
doesn't depend on this organization, so it will be a set of rules
defining a convention in the way commands are named.
Diagnostic commands can easily organized in a hierarchical way, so the
template for a command name can be:
This template can be extended with sub-sub-domains and so on.
A special set of commands without domain will be reserved for the
commands related to the diagnostic framework itself, like the "help"