--- a/jdk/make/java/management/Exportedfiles.gmk Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/make/java/management/Exportedfiles.gmk Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2013, 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
@@ -29,6 +29,7 @@
FILES_export = \
sun/management/ClassLoadingImpl.java \
+ sun/management/DiagnosticCommandImpl.java \
sun/management/FileSystemImpl.java \
sun/management/Flag.java \
sun/management/GarbageCollectorImpl.java \
--- a/jdk/make/java/management/FILES_c.gmk Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/make/java/management/FILES_c.gmk Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2013, 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,6 +25,7 @@
FILES_c = \
ClassLoadingImpl.c \
+ DiagnosticCommandImpl.c \
FileSystemImpl.c \
Flag.c \
GarbageCollectorImpl.c \
--- a/jdk/make/java/management/mapfile-vers Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/make/java/management/mapfile-vers Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2013, 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
@@ -39,6 +39,10 @@
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
Java_com_sun_management_UnixOperatingSystem_initialize;
Java_sun_management_ClassLoadingImpl_setVerboseClass;
+ Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
+ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
+ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
+ Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_Flag_getAllFlagNames;
Java_sun_management_Flag_getFlags;
--- a/jdk/makefiles/mapfiles/libmanagement/mapfile-vers Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/makefiles/mapfiles/libmanagement/mapfile-vers Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2013, 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
@@ -39,6 +39,10 @@
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
Java_com_sun_management_UnixOperatingSystem_initialize;
Java_sun_management_ClassLoadingImpl_setVerboseClass;
+ Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
+ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
+ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
+ Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_Flag_getAllFlagNames;
Java_sun_management_Flag_getFlags;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/management/DiagnosticCommandMBean.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2013, 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.lang.management.PlatformManagedObject;
+import javax.management.DynamicMBean;
+
+/**
+ * Management interface for the diagnostic commands for the HotSpot Virtual Machine.
+ *
+ * <p>The {code DiagnosticCommandMBean} is registered to the
+ * {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
+ * platform MBeanServer} as are other platform MBeans.
+ *
+ * <p>The {@link javax.management.ObjectName ObjectName} for uniquely identifying
+ * the diagnostic MBean within an MBeanServer is:
+ * <blockquote>
+ * {@code com.sun.management:type=DiagnosticCommand}
+ * </blockquote>
+ *
+ * <p>This MBean is a {@link javax.management.DynamicMBean DynamicMBean}
+ * and also a {@link javax.management.NotificationEmitter}.
+ * The {@code DiagnosticCommandMBean} is generated at runtime and is subject to
+ * modifications during the lifetime of the Java virtual machine.
+ *
+ * A <em>diagnostic command</em> is represented as an operation of
+ * the {@code DiagnosticCommandMBean} interface. Each diagnostic command has:
+ * <ul>
+ * <li>the diagnostic command name which is the name being referenced in
+ * the HotSpot Virtual Machine</li>
+ * <li>the MBean operation name which is the
+ * {@linkplain javax.management.MBeanOperationInfo#getName() name}
+ * generated for the diagnostic command operation invocation.
+ * The MBean operation name is implementation dependent</li>
+ * </ul>
+ *
+ * The recommended way to transform a diagnostic command name into a MBean
+ * operation name is as follows:
+ * <ul>
+ * <li>All characters from the first one to the first dot are set to be
+ * lower-case characters</li>
+ * <li>Every dot or underline character is removed and the following
+ * character is set to be an upper-case character</li>
+ * <li>All other characters are copied without modification</li>
+ * </ul>
+ *
+ * <p>The diagnostic command name is always provided with the meta-data on the
+ * operation in a field named {@code dcmd.name} (see below).
+ *
+ * <p>A diagnostic command may or may not support options or arguments.
+ * All the operations return {@code String} and either take
+ * no parameter for operations that do not support any option or argument,
+ * or take a {@code String[]} parameter for operations that support at least
+ * one option or argument.
+ * Each option or argument must be stored in a single String.
+ * Options or arguments split across several String instances are not supported.
+ *
+ * <p>The distinction between options and arguments: options are identified by
+ * the option name while arguments are identified by their position in the
+ * command line. Options and arguments are processed in the order of the array
+ * passed to the invocation method.
+ *
+ * <p>Like any operation of a dynamic MBean, each of these operations is
+ * described by {@link javax.management.MBeanOperationInfo MBeanOperationInfo}
+ * instance. Here's the values returned by this object:
+ * <ul>
+ * <li>{@link javax.management.MBeanOperationInfo#getName() getName()}
+ * returns the operation name generated from the diagnostic command name</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getDescription() getDescription()}
+ * returns the diagnostic command description
+ * (the same as the one return in the 'help' command)</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getImpact() getImpact()}
+ * returns <code>ACTION_INFO</code></li>
+ * <li>{@link javax.management.MBeanOperationInfo#getReturnType() getReturnType()}
+ * returns {@code java.lang.String}</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getDescriptor() getDescriptor()}
+ * returns a Descriptor instance (see below)</li>
+ * </ul>
+ *
+ * <p>The {@link javax.management.Descriptor Descriptor}
+ * is a collection of fields containing additional
+ * meta-data for a JMX element. A field is a name and an associated value.
+ * The additional meta-data provided for an operation associated with a
+ * diagnostic command are described in the table below:
+ * <p>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr>
+ * <th>Name</th><th>Type</th><th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>dcmd.name</td><td>String</td>
+ * <td>The original diagnostic command name (not the operation name)</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.description</td><td>String</td>
+ * <td>The diagnostic command description</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.help</td><td>String</td>
+ * <td>The full help message for this diagnostic command (same output as
+ * the one produced by the 'help' command)</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.vmImpact</td><td>String</td>
+ * <td>The impact of the diagnostic command,
+ * this value is the same as the one printed in the 'impact'
+ * section of the help message of the diagnostic command, and it
+ * is different from the getImpact() of the MBeanOperationInfo</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.enabled</td><td>boolean</td>
+ * <td>True if the diagnostic command is enabled, false otherwise</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.permissionClass</td><td>String</td>
+ * <td>Some diagnostic command might require a specific permission to be
+ * executed, in addition to the MBeanPermission to invoke their
+ * associated MBean operation. This field returns the fully qualified
+ * name of the permission class or null if no permission is required
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.permissionName</td><td>String</td>
+ * <td>The fist argument of the permission required to execute this
+ * diagnostic command or null if no permission is required</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.permissionAction</td><td>String</td>
+ * <td>The second argument of the permission required to execute this
+ * diagnostic command or null if the permission constructor has only
+ * one argument (like the ManagementPermission) or if no permission
+ * is required</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arguments</td><td>Descriptor</td>
+ * <td>A Descriptor instance containing the descriptions of options and
+ * arguments supported by the diagnostic command (see below)</td>
+ * </tr>
+ * </table>
+ * <p>
+ *
+ * <p>The description of parameters (options or arguments) of a diagnostic
+ * command is provided within a Descriptor instance. In this Descriptor,
+ * each field name is a parameter name, and each field value is itself
+ * a Descriptor instance. The fields provided in this second Descriptor
+ * instance are described in the table below:
+ *
+ * <table border="1" cellpadding="5">
+ * <tr>
+ * <th>Name</th><th>Type</th><th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.name</td><td>String</td>
+ * <td>The name of the parameter</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.type</td><td>String</td>
+ * <td>The type of the parameter. The returned String is the name of a type
+ * recognized by the diagnostic command parser. These types are not
+ * Java types and are implementation dependent.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.description</td><td>String</td>
+ * <td>The parameter description</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.isMandatory</td><td>boolean</td>
+ * <td>True if the parameter is mandatory, false otherwise</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.isOption</td><td>boolean</td>
+ * <td>True if the parameter is an option, false if it is an argument</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.isMultiple</td><td>boolean</td>
+ * <td>True if the parameter can be specified several times, false
+ * otherwise</td>
+ * </tr>
+ * </table>
+ *
+ * <p>When the set of diagnostic commands currently supported by the Java
+ * Virtual Machine is modified, the {@code DiagnosticCommandMBean} emits
+ * a {@link javax.management.Notification} with a
+ * {@linkplain javax.management.Notification#getType() type} of
+ * <a href="{@docRoot}/../../../../api/javax/management/MBeanInfo.html#info-changed">
+ * {@code "jmx.mbean.info.changed"}</a> and a
+ * {@linkplain javax.management.Notification#getUserData() userData} that
+ * is the new {@code MBeanInfo}.
+ *
+ * @since 8
+ */
+public interface DiagnosticCommandMBean extends DynamicMBean
+{
+
+}
--- a/jdk/src/share/classes/java/lang/management/ManagementFactory.java Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/src/share/classes/java/lang/management/ManagementFactory.java Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -42,7 +42,9 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
@@ -482,6 +484,11 @@
}
}
}
+ HashMap<ObjectName, DynamicMBean> dynmbeans =
+ ManagementFactoryHelper.getPlatformDynamicMBeans();
+ for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
+ addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
+ }
}
return platformMBeanServer;
}
@@ -825,4 +832,24 @@
}
}
+ /**
+ * Registers a DynamicMBean.
+ */
+ private static void addDynamicMBean(final MBeanServer mbs,
+ final DynamicMBean dmbean,
+ final ObjectName on) {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ NotCompliantMBeanException {
+ mbs.registerMBean(dmbean, on);
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw new RuntimeException(e.getException());
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/DiagnosticCommandArgumentInfo.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013, 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.management;
+
+/**
+ * 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>
+ * <command name> [<option>=<value>] [<argument_value>]
+ * </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.
+ *
+ * @since 8
+ */
+
+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 boolean multiple;
+ private final int position;
+
+ /**
+ * Returns the argument name.
+ *
+ * @return the argument name
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the argument description.
+ *
+ * @return the argument description
+ */
+ String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the argument type.
+ *
+ * @return the argument type
+ */
+ 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.
+ */
+ 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
+ */
+ boolean isMandatory() {
+ return mandatory;
+ }
+
+ /**
+ * Returns {@code true} if the argument is an option,
+ * {@code false} otherwise. Options have to be specified using the
+ * <key>=<value> syntax on the command line, while other
+ * arguments are specified with a single <value> field and are
+ * identified by their position on command line.
+ *
+ * @return {@code true} if the argument is an option,
+ * {@code false} otherwise
+ */
+ boolean isOption() {
+ return option;
+ }
+
+ /**
+ * Returns {@code true} if the argument can be specified multiple times,
+ * {@code false} otherwise.
+ *
+ * @return {@code true} if the argument can be specified multiple times,
+ * {@code false} otherwise
+ */
+ boolean isMultiple() {
+ return multiple;
+ }
+
+ /**
+ * 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.
+ */
+ int getPosition() {
+ return position;
+ }
+
+ DiagnosticCommandArgumentInfo(String name, String description,
+ String type, String defaultValue,
+ boolean mandatory, boolean option,
+ boolean multiple, int position) {
+ this.name = name;
+ this.description = description;
+ this.type = type;
+ this.defaultValue = defaultValue;
+ this.mandatory = mandatory;
+ this.option = option;
+ this.multiple = multiple;
+ this.position = position;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/DiagnosticCommandImpl.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2013, 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.management;
+
+import com.sun.management.DiagnosticCommandMBean;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.Permission;
+import java.util.*;
+import javax.management.*;
+
+/**
+ * Implementation class for the diagnostic commands subsystem.
+ *
+ * @since 8
+ */
+class DiagnosticCommandImpl extends NotificationEmitterSupport
+ implements DiagnosticCommandMBean {
+
+ private final VMManagement jvm;
+ private volatile Map<String, Wrapper> wrappers = null;
+ private static final String strClassName = "".getClass().getName();
+ private static final String strArrayClassName = String[].class.getName();
+ private final boolean isSupported;
+
+ @Override
+ public Object getAttribute(String attribute) throws AttributeNotFoundException,
+ MBeanException, ReflectionException {
+ throw new AttributeNotFoundException(attribute);
+ }
+
+ @Override
+ public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException {
+ throw new AttributeNotFoundException(attribute.getName());
+ }
+
+ @Override
+ public AttributeList getAttributes(String[] attributes) {
+ return new AttributeList();
+ }
+
+ @Override
+ public AttributeList setAttributes(AttributeList attributes) {
+ return new AttributeList();
+ }
+
+ private class Wrapper {
+
+ String name;
+ String cmd;
+ DiagnosticCommandInfo info;
+ Permission permission;
+
+ Wrapper(String name, String cmd, DiagnosticCommandInfo info)
+ throws InstantiationException {
+ this.name = name;
+ this.cmd = cmd;
+ this.info = info;
+ this.permission = null;
+ Exception cause = null;
+ if (info.getPermissionClass() != null) {
+ try {
+ Class c = Class.forName(info.getPermissionClass());
+ if (info.getPermissionAction() == null) {
+ try {
+ Constructor constructor = c.getConstructor(String.class);
+ permission = (Permission) constructor.newInstance(info.getPermissionName());
+
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException ex) {
+ cause = ex;
+ }
+ }
+ if (permission == null) {
+ try {
+ Constructor constructor = c.getConstructor(String.class, String.class);
+ permission = (Permission) constructor.newInstance(
+ info.getPermissionName(),
+ info.getPermissionAction());
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException ex) {
+ cause = ex;
+ }
+ }
+ } catch (ClassNotFoundException ex) { }
+ if (permission == null) {
+ InstantiationException iex =
+ new InstantiationException("Unable to instantiate required permission");
+ iex.initCause(cause);
+ }
+ }
+ }
+
+ public String execute(String[] args) {
+ if (permission != null) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(permission);
+ }
+ }
+ if(args == null) {
+ return executeDiagnosticCommand(cmd);
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(cmd);
+ for(int i=0; i<args.length; i++) {
+ if(args[i] == null) {
+ throw new IllegalArgumentException("Invalid null argument");
+ }
+ sb.append(" ");
+ sb.append(args[i]);
+ }
+ return executeDiagnosticCommand(sb.toString());
+ }
+ }
+ }
+
+ DiagnosticCommandImpl(VMManagement jvm) {
+ this.jvm = jvm;
+ isSupported = jvm.isRemoteDiagnosticCommandsSupported();
+ }
+
+ private static class OperationInfoComparator implements Comparator<MBeanOperationInfo> {
+ @Override
+ public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ }
+
+ @Override
+ public MBeanInfo getMBeanInfo() {
+ SortedSet<MBeanOperationInfo> operations = new TreeSet<>(new OperationInfoComparator());
+ Map<String, Wrapper> wrappersmap;
+ if (!isSupported) {
+ wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
+ } else {
+ try {
+ String[] command = getDiagnosticCommands();
+ DiagnosticCommandInfo[] info = getDiagnosticCommandInfo(command);
+ MBeanParameterInfo stringArgInfo[] = new MBeanParameterInfo[]{
+ new MBeanParameterInfo("arguments", strArrayClassName,
+ "Array of Diagnostic Commands Arguments and Options")
+ };
+ wrappersmap = new HashMap<>();
+ for (int i = 0; i < command.length; i++) {
+ String name = transform(command[i]);
+ try {
+ Wrapper w = new Wrapper(name, command[i], info[i]);
+ wrappersmap.put(name, w);
+ operations.add(new MBeanOperationInfo(
+ w.name,
+ w.info.getDescription(),
+ (w.info.getArgumentsInfo() == null
+ || w.info.getArgumentsInfo().isEmpty())
+ ? null : stringArgInfo,
+ strClassName,
+ MBeanOperationInfo.ACTION_INFO,
+ commandDescriptor(w)));
+ } catch (InstantiationException ex) {
+ // If for some reasons the creation of a diagnostic command
+ // wrappers fails, the diagnostic command is just ignored
+ // and won't appear in the DynamicMBean
+ }
+ }
+ } catch (IllegalArgumentException | UnsupportedOperationException e) {
+ wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
+ }
+ }
+ wrappers = Collections.unmodifiableMap(wrappersmap);
+ HashMap<String, Object> map = new HashMap<>();
+ map.put("immutableInfo", "false");
+ map.put("interfaceClassName","com.sun.management.DiagnosticCommandMBean");
+ map.put("mxbean", "false");
+ Descriptor desc = new ImmutableDescriptor(map);
+ return new MBeanInfo(
+ this.getClass().getName(),
+ "Diagnostic Commands",
+ null, // attributes
+ null, // constructors
+ operations.toArray(new MBeanOperationInfo[operations.size()]), // operations
+ getNotificationInfo(), // notifications
+ desc);
+ }
+
+ @Override
+ public Object invoke(String actionName, Object[] params, String[] signature)
+ throws MBeanException, ReflectionException {
+ if (!isSupported) {
+ throw new UnsupportedOperationException();
+ }
+ if (wrappers == null) {
+ getMBeanInfo();
+ }
+ Wrapper w = wrappers.get(actionName);
+ if (w != null) {
+ if (w.info.getArgumentsInfo().isEmpty()
+ && (params == null || params.length == 0)
+ && (signature == null || signature.length == 0)) {
+ return w.execute(null);
+ } else if((params != null && params.length == 1)
+ && (signature != null && signature.length == 1
+ && signature[0] != null
+ && signature[0].compareTo(strArrayClassName) == 0)) {
+ return w.execute((String[]) params[0]);
+ }
+ }
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+
+ private static String transform(String name) {
+ StringBuilder sb = new StringBuilder();
+ boolean toLower = true;
+ boolean toUpper = false;
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if (c == '.' || c == '_') {
+ toLower = false;
+ toUpper = true;
+ } else {
+ if (toUpper) {
+ toUpper = false;
+ sb.append(Character.toUpperCase(c));
+ } else if(toLower) {
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException {
+ HashMap<String, Object> map = new HashMap<>();
+ map.put("dcmd.name", w.info.getName());
+ map.put("dcmd.description", w.info.getDescription());
+ map.put("dcmd.vmImpact", w.info.getImpact());
+ map.put("dcmd.permissionClass", w.info.getPermissionClass());
+ map.put("dcmd.permissionName", w.info.getPermissionName());
+ map.put("dcmd.permissionAction", w.info.getPermissionAction());
+ map.put("dcmd.enabled", w.info.isEnabled());
+ StringBuilder sb = new StringBuilder();
+ sb.append("help ");
+ sb.append(w.info.getName());
+ map.put("dcmd.help", executeDiagnosticCommand(sb.toString()));
+ if (w.info.getArgumentsInfo() != null && !w.info.getArgumentsInfo().isEmpty()) {
+ HashMap<String, Object> allargmap = new HashMap<>();
+ for (DiagnosticCommandArgumentInfo arginfo : w.info.getArgumentsInfo()) {
+ HashMap<String, Object> argmap = new HashMap<>();
+ argmap.put("dcmd.arg.name", arginfo.getName());
+ argmap.put("dcmd.arg.type", arginfo.getType());
+ argmap.put("dcmd.arg.description", arginfo.getDescription());
+ argmap.put("dcmd.arg.isMandatory", arginfo.isMandatory());
+ argmap.put("dcmd.arg.isMultiple", arginfo.isMultiple());
+ boolean isOption = arginfo.isOption();
+ argmap.put("dcmd.arg.isOption", isOption);
+ if(!isOption) {
+ argmap.put("dcmd.arg.position", arginfo.getPosition());
+ } else {
+ argmap.put("dcmd.arg.position", -1);
+ }
+ allargmap.put(arginfo.getName(), new ImmutableDescriptor(argmap));
+ }
+ map.put("dcmd.arguments", new ImmutableDescriptor(allargmap));
+ }
+ return new ImmutableDescriptor(map);
+ }
+
+ private final static String notifName =
+ "javax.management.Notification";
+
+ private final static String[] diagFramNotifTypes = {
+ "jmx.mbean.info.changed"
+ };
+
+ private MBeanNotificationInfo[] notifInfo = null;
+
+ @Override
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ synchronized (this) {
+ if (notifInfo == null) {
+ notifInfo = new MBeanNotificationInfo[1];
+ notifInfo[0] =
+ new MBeanNotificationInfo(diagFramNotifTypes,
+ notifName,
+ "Diagnostic Framework Notification");
+ }
+ }
+ return notifInfo;
+ }
+
+ private static long seqNumber = 0;
+ private static long getNextSeqNumber() {
+ return ++seqNumber;
+ }
+
+ private void createDiagnosticFrameworkNotification() {
+
+ if (!hasListeners()) {
+ return;
+ }
+ ObjectName on = null;
+ try {
+ on = ObjectName.getInstance(ManagementFactoryHelper.HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME);
+ } catch (MalformedObjectNameException e) { }
+ Notification notif = new Notification("jmx.mbean.info.changed",
+ on,
+ getNextSeqNumber());
+ notif.setUserData(getMBeanInfo());
+ sendNotification(notif);
+ }
+
+ @Override
+ public synchronized void addNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback) {
+ boolean before = hasListeners();
+ super.addNotificationListener(listener, filter, handback);
+ boolean after = hasListeners();
+ if (!before && after) {
+ setNotificationEnabled(true);
+ }
+ }
+
+ @Override
+ public synchronized void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener);
+ boolean after = hasListeners();
+ if (before && !after) {
+ setNotificationEnabled(false);
+ }
+ }
+
+ @Override
+ public synchronized void removeNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws ListenerNotFoundException {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener, filter, handback);
+ boolean after = hasListeners();
+ if (before && !after) {
+ setNotificationEnabled(false);
+ }
+ }
+
+ private native void setNotificationEnabled(boolean enabled);
+ private native String[] getDiagnosticCommands();
+ private native DiagnosticCommandInfo[] getDiagnosticCommandInfo(String[] commands);
+ private native String executeDiagnosticCommand(String command);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/DiagnosticCommandInfo.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2013, 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.management;
+
+import java.util.List;
+
+/**
+ * Diagnostic command information. It contains the description of a
+ * diagnostic command.
+ *
+ * @since 8
+ */
+
+class DiagnosticCommandInfo {
+ private final String name;
+ private final String description;
+ private final String impact;
+ private final String permissionClass;
+ private final String permissionName;
+ private final String permissionAction;
+ private final boolean enabled;
+ private final List<DiagnosticCommandArgumentInfo> arguments;
+
+ /**
+ * Returns the diagnostic command name.
+ *
+ * @return the diagnostic command name
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the diagnostic command description.
+ *
+ * @return the diagnostic command description
+ */
+ 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
+ */
+ String getImpact() {
+ return impact;
+ }
+
+ /**
+ * Returns the name of the permission class required to be allowed
+ * to invoke the diagnostic command, or null if no permission
+ * is required.
+ *
+ * @return the name of the permission class name required to be allowed
+ * to invoke the diagnostic command, or null if no permission
+ * is required
+ */
+ String getPermissionClass() {
+ return permissionClass;
+ }
+
+ /**
+ * Returns the permission name required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required.
+ *
+ * @return the permission name required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required
+ */
+ String getPermissionName() {
+ return permissionName;
+ }
+
+ /**
+ * Returns the permission action required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required or
+ * if the permission has no action specified.
+ *
+ * @return the permission action required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required or
+ * if the permission has no action specified
+ */
+ String getPermissionAction() {
+ return permissionAction;
+ }
+
+ /**
+ * 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
+ */
+ 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
+ */
+ List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
+ return arguments;
+ }
+
+ DiagnosticCommandInfo(String name, String description,
+ String impact, String permissionClass,
+ String permissionName, String permissionAction,
+ boolean enabled,
+ List<DiagnosticCommandArgumentInfo> arguments)
+ {
+ this.name = name;
+ this.description = description;
+ this.impact = impact;
+ this.permissionClass = permissionClass;
+ this.permissionName = permissionName;
+ this.permissionAction = permissionAction;
+ this.enabled = enabled;
+ this.arguments = arguments;
+ }
+}
--- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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,6 +27,7 @@
import java.lang.management.*;
+import javax.management.DynamicMBean;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
@@ -42,7 +43,9 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import com.sun.management.DiagnosticCommandMBean;
import com.sun.management.OSMBeanFactory;
import com.sun.management.HotSpotDiagnosticMXBean;
@@ -263,6 +266,7 @@
private static HotspotThread hsThreadMBean = null;
private static HotspotCompilation hsCompileMBean = null;
private static HotspotMemory hsMemoryMBean = null;
+ private static DiagnosticCommandImpl hsDiagCommandMBean = null;
public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
if (hsDiagMBean == null) {
@@ -311,6 +315,14 @@
return hsMemoryMBean;
}
+ public static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() {
+ // Remote Diagnostic Commands may not be supported
+ if (hsDiagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) {
+ hsDiagCommandMBean = new DiagnosticCommandImpl(jvm);
+ }
+ return hsDiagCommandMBean;
+ }
+
/**
* This method is for testing only.
*/
@@ -365,6 +377,18 @@
private final static String HOTSPOT_THREAD_MBEAN_NAME =
"sun.management:type=HotspotThreading";
+ final static String HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME =
+ "com.sun.management:type=DiagnosticCommand";
+
+ public static HashMap<ObjectName, DynamicMBean> getPlatformDynamicMBeans() {
+ HashMap<ObjectName, DynamicMBean> map = new HashMap<>();
+ DiagnosticCommandMBean diagMBean = getDiagnosticCommandMBean();
+ if (diagMBean != null) {
+ map.put(Util.newObjectName(HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME), diagMBean);
+ }
+ return map;
+ }
+
static void registerInternalMBeans(MBeanServer mbs) {
// register all internal MBeans if not registered
// No exception is thrown if a MBean with that object name
--- a/jdk/src/share/classes/sun/management/VMManagement.java Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/src/share/classes/sun/management/VMManagement.java Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -46,6 +46,7 @@
public boolean isThreadAllocatedMemorySupported();
public boolean isThreadAllocatedMemoryEnabled();
public boolean isGcNotificationSupported();
+ public boolean isRemoteDiagnosticCommandsSupported();
// Class Loading Subsystem
public long getTotalClassCount();
--- a/jdk/src/share/classes/sun/management/VMManagementImpl.java Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/src/share/classes/sun/management/VMManagementImpl.java Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -57,6 +57,7 @@
private static boolean synchronizerUsageSupport;
private static boolean threadAllocatedMemorySupport;
private static boolean gcNotificationSupport;
+ private static boolean remoteDiagnosticCommandsSupport;
static {
@@ -106,6 +107,10 @@
return gcNotificationSupport;
}
+ public boolean isRemoteDiagnosticCommandsSupported() {
+ return remoteDiagnosticCommandsSupport;
+ }
+
public native boolean isThreadContentionMonitoringEnabled();
public native boolean isThreadCpuTimeEnabled();
public native boolean isThreadAllocatedMemoryEnabled();
--- a/jdk/src/share/javavm/export/jmm.h Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/src/share/javavm/export/jmm.h Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -49,7 +49,8 @@
JMM_VERSION_1_1 = 0x20010100, // JDK 6
JMM_VERSION_1_2 = 0x20010200, // JDK 7
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
- JMM_VERSION = 0x20010202
+ JMM_VERSION_1_2_2 = 0x20010202,
+ JMM_VERSION = 0x20010203
};
typedef struct {
@@ -62,7 +63,8 @@
unsigned int isObjectMonitorUsageSupported : 1;
unsigned int isSynchronizerUsageSupported : 1;
unsigned int isThreadAllocatedMemorySupported : 1;
- unsigned int : 23;
+ unsigned int isRemoteDiagnosticCommandsSupported : 1;
+ unsigned int : 22;
} jmmOptionalSupport;
typedef enum {
@@ -190,21 +192,27 @@
} jmmGCStat;
typedef struct {
- const char* name;
- const char* description;
- const char* impact;
- int num_arguments;
- jboolean enabled;
+ const char* name; /* Name of the diagnostic command */
+ const char* description; /* Short description */
+ const char* impact; /* Impact on the JVM */
+ const char* permission_class; /* Class name of the required permission if any */
+ const char* permission_name; /* Permission name of the required permission if any */
+ const char* permission_action; /* Action name of the required permission if any*/
+ int num_arguments; /* Number of supported options or arguments */
+ jboolean enabled; /* True if the diagnostic command can be invoked, false otherwise*/
} dcmdInfo;
typedef struct {
- const char* name;
- const char* description;
- const char* type;
- const char* default_string;
- jboolean mandatory;
- jboolean option;
- int position;
+ const char* name; /* Option/Argument name*/
+ const char* description; /* Short description */
+ const char* type; /* Type: STRING, BOOLEAN, etc. */
+ const char* default_string; /* Default value in a parsable string */
+ jboolean mandatory; /* True if the option/argument is mandatory */
+ jboolean option; /* True if it is an option, false if it is an argument */
+ /* (see diagnosticFramework.hpp for option/argument definitions) */
+ jboolean multiple; /* True is the option can be specified several time */
+ int position; /* Expected position for this argument (this field is */
+ /* meaningless for options) */
} dcmdArgInfo;
typedef struct jmmInterface_1_ {
@@ -327,6 +335,9 @@
jstring (JNICALL *ExecuteDiagnosticCommand)
(JNIEnv *env,
jstring command);
+ void (JNICALL *SetDiagnosticFrameworkNotificationEnabled)
+ (JNIEnv *env,
+ jboolean enabled);
} JmmInterface;
#ifdef __cplusplus
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#include <jni.h>
+#include "management.h"
+#include "sun_management_DiagnosticCommandImpl.h"
+
+JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
+(JNIEnv *env, jobject dummy, jboolean enabled) {
+ if(jmm_version > JMM_VERSION_1_2_2) {
+ jmm_interface->SetDiagnosticFrameworkNotificationEnabled(env, enabled);
+ } else {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "JMX interface to diagnostic framework notifications is not supported by this VM");
+ }
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands
+ (JNIEnv *env, jobject dummy)
+{
+ return jmm_interface->GetDiagnosticCommands(env);
+}
+
+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,
+ "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,
+ "sun/management/DiagnosticCommandArgumentInfo",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)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].multiple,
+ 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 of the diagnostic command
+ * passed in argument is not supported by the JVM
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo
+(JNIEnv *env, jobject dummy, jobjectArray commands)
+{
+ int i;
+ jclass dcmdInfoCls;
+ jobject result;
+ jobjectArray args;
+ jobject obj;
+ jmmOptionalSupport mos;
+ jint ret = jmm_interface->GetOptionalSupport(env, &mos);
+ jsize num_commands;
+ dcmdInfo* dcmd_info_array;
+
+ if (commands == NULL) {
+ JNU_ThrowNullPointerException(env, "Invalid String Array");
+ return NULL;
+ }
+ num_commands = (*env)->GetArrayLength(env, commands);
+ 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,
+ "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,
+ "sun/management/DiagnosticCommandInfo",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;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].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
+ dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
+ dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
+ 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;
+}
+
+/* Throws IllegalArgumentException if the diagnostic command
+ * passed in argument is not supported by the JVM
+ */
+JNIEXPORT jstring JNICALL
+Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand
+(JNIEnv *env, jobject dummy, jstring command) {
+ return jmm_interface->ExecuteDiagnosticCommand(env, command);
+}
--- a/jdk/src/share/native/sun/management/VMManagementImpl.c Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/src/share/native/sun/management/VMManagementImpl.c Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -24,6 +24,7 @@
*/
#include <jni.h>
+#include <stdlib.h>
#include "jvm.h"
#include "management.h"
#include "sun_management_VMManagementImpl.h"
@@ -96,6 +97,9 @@
value = mos.isThreadAllocatedMemorySupported;
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
+ value = mos.isRemoteDiagnosticCommandsSupported;
+ setStaticBooleanField(env, cls, "remoteDiagnosticCommandsSupport", value);
+
if ((jmm_version > JMM_VERSION_1_2) ||
(jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) {
setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanDoubleInvocationTest.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013, 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 7150256
+ * @summary Basic Test for the DiagnosticCommandMBean
+ * @author Frederic Parain
+ *
+ * @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8125 DcmdMBeanDoubleInvocationTest
+ */
+
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.Descriptor;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.*;
+import javax.management.remote.*;
+
+public class DcmdMBeanDoubleInvocationTest {
+
+ private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ "com.sun.management:type=DiagnosticCommand";
+
+ public static void main(String[] args) {
+ MBeanServerConnection mbs = null;
+ try {
+ JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8125/jmxrmi");
+ JMXConnector connector = JMXConnectorFactory.connect(url);
+ mbs = connector.getMBeanServerConnection();
+ } catch(Throwable t) {
+ t.printStackTrace();
+ }
+ ObjectName name;
+ try {
+ name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
+ MBeanInfo info = mbs.getMBeanInfo(name);
+ String[] helpArgs = {"-all", "\n", "VM.version"};
+ Object[] dcmdArgs = {helpArgs};
+ String[] signature = {String[].class.getName()};
+ String result = (String) mbs.invoke(name, "help", dcmdArgs, signature);
+ System.out.println(result);
+ } catch (RuntimeMBeanException ex) {
+ if (ex.getCause() instanceof IllegalArgumentException) {
+ System.out.println("Test passed");
+ return;
+ } else {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ } catch (InstanceNotFoundException | IntrospectionException
+ | ReflectionException | MalformedObjectNameException
+ | MBeanException|IOException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ System.out.println("Double commands have not been detected");
+ throw new RuntimeException("TEST FAILED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanInvocationTest.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, 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 7150256
+ * @summary Basic Test for the DiagnosticCommandMBean
+ * @author Frederic Parain
+ *
+ * @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8129 DcmdMBeanInvocationTest
+ */
+
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.Descriptor;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.*;
+import javax.management.remote.*;
+
+public class DcmdMBeanInvocationTest {
+
+ private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ "com.sun.management:type=DiagnosticCommand";
+
+ public static void main(String[] args) {
+ MBeanServerConnection mbs = null;
+ try {
+ JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8129/jmxrmi");
+ JMXConnector connector = JMXConnectorFactory.connect(url);
+ mbs = connector.getMBeanServerConnection();
+ } catch(Throwable t) {
+ t.printStackTrace();
+ }
+ ObjectName name;
+ try {
+ name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
+ MBeanInfo info = mbs.getMBeanInfo(name);
+ String[] helpArgs = {"-all"};
+ Object[] dcmdArgs = {helpArgs};
+ String[] signature = {String[].class.getName()};
+ String result = (String) mbs.invoke(name, "help", dcmdArgs, signature);
+ System.out.println(result);
+ } catch (InstanceNotFoundException | IntrospectionException
+ | ReflectionException | MalformedObjectNameException
+ | MBeanException|IOException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ System.out.println("Test passed");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanPermissionsTest.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2013, 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 7150256
+ * @summary Permissions Tests for the DiagnosticCommandMBean
+ * @author Frederic Parain
+ *
+ * @run main/othervm DcmdMBeanPermissionsTest
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.ReflectPermission;
+import java.security.Permission;
+import java.util.HashSet;
+import java.util.Iterator;
+import javax.management.Descriptor;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanPermission;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeMBeanException;
+
+/**
+ *
+ * @author fparain
+ */
+public class DcmdMBeanPermissionsTest {
+
+ private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ "com.sun.management:type=DiagnosticCommand";
+
+ static public class CustomSecurityManager extends SecurityManager {
+
+ private HashSet<Permission> grantedPermissions;
+
+ public CustomSecurityManager() {
+ grantedPermissions = new HashSet<Permission>();
+ }
+
+ public final void grantPermission(final Permission perm) {
+ grantedPermissions.add(perm);
+ }
+
+ public final void denyPermission(final Permission perm) {
+ Iterator<Permission> it = grantedPermissions.iterator();
+ while (it.hasNext()) {
+ Permission p = it.next();
+ if (p.equals(perm)) {
+ it.remove();
+ }
+ }
+ }
+
+ public final void checkPermission(final Permission perm) {
+ for (Permission p : grantedPermissions) {
+ if (p.implies(perm)) {
+ return;
+ }
+ }
+ throw new SecurityException(perm.toString());
+ }
+ };
+
+ static Permission createPermission(String classname, String name,
+ String action) {
+ Permission permission = null;
+ try {
+ Class c = Class.forName(classname);
+ if (action == null) {
+ try {
+ Constructor constructor = c.getConstructor(String.class);
+ permission = (Permission) constructor.newInstance(name);
+
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ }
+ if (permission == null) {
+ try {
+ Constructor constructor = c.getConstructor(String.class,
+ String.class);
+ permission = (Permission) constructor.newInstance(
+ name,
+ action);
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ }
+ } catch (ClassNotFoundException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ if (permission == null) {
+ throw new RuntimeException("TEST FAILED");
+ }
+ return permission;
+ }
+
+ // return true if invokation triggered a SecurityException
+ static boolean invokeOperation(MBeanServer mbs, ObjectName on,
+ MBeanOperationInfo opInfo) {
+ try {
+ if (opInfo.getSignature().length == 0) {
+ mbs.invoke(on, opInfo.getName(),
+ new Object[0], new String[0]);
+ } else {
+ mbs.invoke(on, opInfo.getName(),
+ new Object[1], new String[]{ String[].class.getName()});
+ }
+ } catch (SecurityException ex) {
+ ex.printStackTrace();
+ return true;
+ } catch (RuntimeMBeanException ex) {
+ if (ex.getCause() instanceof SecurityException) {
+ //ex.printStackTrace();
+ return true;
+ }
+ } catch (MBeanException | InstanceNotFoundException
+ | ReflectionException ex) {
+ throw new RuntimeException("TEST FAILED");
+ }
+ return false;
+ }
+
+ static void testOperation(MBeanServer mbs, CustomSecurityManager sm,
+ ObjectName on, MBeanOperationInfo opInfo) {
+ System.out.println("Testing " + opInfo.getName());
+ Descriptor desc = opInfo.getDescriptor();
+ if (desc.getFieldValue("dcmd.permissionClass") == null) {
+ // No special permission required, execution should not trigger
+ // any security exception
+ if (invokeOperation(mbs, on, opInfo)) {
+ throw new RuntimeException("TEST FAILED");
+ }
+ } else {
+ // Building the required permission
+ Permission reqPerm = createPermission(
+ (String)desc.getFieldValue("dcmd.permissionClass"),
+ (String)desc.getFieldValue("dcmd.permissionName"),
+ (String)desc.getFieldValue("dcmd.permissionAction"));
+ // Paranoid mode: check that the SecurityManager has not already
+ // been granted the permission
+ sm.denyPermission(reqPerm);
+ // A special permission is required for this operation,
+ // invoking it without the permission granted must trigger
+ // a security exception
+ if(!invokeOperation(mbs, on, opInfo)) {
+ throw new RuntimeException("TEST FAILED");
+ }
+ // grant the permission and re-try invoking the operation
+ sm.grantPermission(reqPerm);
+ if(invokeOperation(mbs, on, opInfo)) {
+ throw new RuntimeException("TEST FAILED");
+ }
+ // Clean up
+ sm.denyPermission(reqPerm);
+ }
+ }
+
+ public static void main(final String[] args) {
+ final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName on = null;
+ try {
+ on = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
+ } catch (MalformedObjectNameException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ MBeanInfo info = null;
+ try {
+ info = mbs.getMBeanInfo(on);
+ } catch (InstanceNotFoundException | IntrospectionException
+ | ReflectionException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("TEST FAILED");
+ }
+ CustomSecurityManager sm = new CustomSecurityManager();
+ System.setSecurityManager(sm);
+ // Set of permission required to run the test cleanly
+ // Some permissions are required by the MBeanServer and other
+ // platform services (RuntimePermission("createClassLoader"),
+ // ReflectPermission("suppressAccessChecks"),
+ // java.util.logging.LoggingPermission("control"),
+ // RuntimePermission("exitVM.97")).
+ // Other permissions are required by commands being invoked
+ // in the test (for instance, RuntimePermission("modifyThreadGroup")
+ // and RuntimePermission("modifyThread") are checked when
+ // runFinalization() is invoked by the gcRunFinalization command.
+ sm.grantPermission(new RuntimePermission("createClassLoader"));
+ sm.grantPermission(new ReflectPermission("suppressAccessChecks"));
+ sm.grantPermission(new java.util.logging.LoggingPermission("control", ""));
+ sm.grantPermission(new java.lang.RuntimePermission("exitVM.97"));
+ sm.grantPermission(new java.lang.RuntimePermission("modifyThreadGroup"));
+ sm.grantPermission(new java.lang.RuntimePermission("modifyThread"));
+ for(MBeanOperationInfo opInfo : info.getOperations()) {
+ Permission opPermission = new MBeanPermission(info.getClassName(),
+ opInfo.getName(),
+ on,
+ "invoke");
+ sm.grantPermission(opPermission);
+ testOperation(mbs, sm, on, opInfo);
+ sm.denyPermission(opPermission);
+ }
+ System.out.println("TEST PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTest.java Wed Jun 05 08:41:02 2013 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, 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 7150256
+ * @summary Basic Test for the DiagnosticCommandMBean
+ * @author Frederic Parain
+ *
+ * @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8127 DcmdMBeanTest
+ */
+
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.Descriptor;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.*;
+import javax.management.remote.*;
+
+public class DcmdMBeanTest {
+
+ private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ "com.sun.management:type=DiagnosticCommand";
+
+ public static void main(String[] args) {
+ MBeanServerConnection mbs = null;
+ try {
+ JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8127/jmxrmi");
+ JMXConnector connector = JMXConnectorFactory.connect(url);
+ mbs = connector.getMBeanServerConnection();
+ } catch(Throwable t) {
+ t.printStackTrace();
+ }
+ ObjectName name;
+ try {
+ name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
+ MBeanInfo info = mbs.getMBeanInfo(name);
+ // the test should check that the MBean doesn't have any
+ // Attribute, notification or constructor. Current version only
+ // check operations
+ System.out.println("Class Name:"+info.getClassName());
+ System.out.println("Description:"+info.getDescription());
+ MBeanOperationInfo[] opInfo = info.getOperations();
+ System.out.println("Operations:");
+ for(int i=0; i<opInfo.length; i++) {
+ printOperation(opInfo[i]);
+ System.out.println("\n@@@@@@\n");
+ }
+ } catch (InstanceNotFoundException|IntrospectionException|ReflectionException
+ |MalformedObjectNameException|IOException ex) {
+ Logger.getLogger(DcmdMBeanTest.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ static void printOperation(MBeanOperationInfo info) {
+ System.out.println("Name: "+info.getName());
+ System.out.println("Description: "+info.getDescription());
+ System.out.println("Return Type: "+info.getReturnType());
+ System.out.println("Impact: "+info.getImpact());
+ Descriptor desc = info.getDescriptor();
+ System.out.println("Descriptor");
+ for(int i=0; i<desc.getFieldNames().length; i++) {
+ if(desc.getFieldNames()[i].compareTo("dcmd.arguments") == 0) {
+ System.out.println("\t"+desc.getFieldNames()[i]+":");
+ Descriptor desc2 =
+ (Descriptor)desc.getFieldValue(desc.getFieldNames()[i]);
+ for(int j=0; j<desc2.getFieldNames().length; j++) {
+ System.out.println("\t\t"+desc2.getFieldNames()[j]+"=");
+ Descriptor desc3 =
+ (Descriptor)desc2.getFieldValue(desc2.getFieldNames()[j]);
+ for(int k=0; k<desc3.getFieldNames().length; k++) {
+ System.out.println("\t\t\t"+desc3.getFieldNames()[k]+"="
+ +desc3.getFieldValue(desc3.getFieldNames()[k]));
+ }
+ }
+ } else {
+ System.out.println("\t"+desc.getFieldNames()[i]+"="
+ +desc.getFieldValue(desc.getFieldNames()[i]));
+ }
+ }
+ }
+}
+
--- a/jdk/test/java/lang/management/MXBean/MXBeanBehavior.java Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/test/java/lang/management/MXBean/MXBeanBehavior.java Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 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
@@ -36,6 +36,10 @@
import javax.management.*;
public class MXBeanBehavior {
+ // Exclude list: list of platform MBeans that are not MXBeans
+ public static final HashSet<String> excludeList = new HashSet<>(
+ Arrays.asList("com.sun.management:type=DiagnosticCommand"));
+
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
@@ -92,6 +96,10 @@
by generic MXBean tests.
*/
private static void test(MBeanServer mbs, ObjectName name) throws Exception {
+ if(excludeList.contains(name.getCanonicalName())) {
+ // Skipping not MXBean objects.
+ return;
+ }
System.out.println("Testing: " + name);
MBeanInfo mbi = mbs.getMBeanInfo(name);
--- a/jdk/test/java/lang/management/ManagementFactory/MBeanServerMXBeanUnsupportedTest.java Wed Jun 05 16:23:23 2013 +0100
+++ b/jdk/test/java/lang/management/ManagementFactory/MBeanServerMXBeanUnsupportedTest.java Wed Jun 05 08:41:02 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013 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
@@ -36,6 +36,8 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.HashSet;
import javax.management.MBeanServer;
import javax.management.MBeanServerBuilder;
import javax.management.MBeanServerDelegate;
@@ -81,6 +83,9 @@
public static class MBeanServerForwarderInvocationHandler
implements InvocationHandler {
+ public static final HashSet<String> excludeList = new HashSet<String>(
+ Arrays.asList("com.sun.management:type=DiagnosticCommand"));
+
public static MBeanServerForwarder newProxyInstance() {
final InvocationHandler handler =
@@ -126,15 +131,17 @@
if (domain.equals("java.lang") ||
domain.equals("java.util.logging") ||
domain.equals("com.sun.management")) {
- String mxbean = (String)
- mbs.getMBeanInfo(name).getDescriptor().getFieldValue("mxbean");
- if (mxbean == null || !mxbean.equals("true")) {
- throw new RuntimeException(
+ if(!excludeList.contains(name.getCanonicalName())) {
+ String mxbean = (String)
+ mbs.getMBeanInfo(name).getDescriptor().getFieldValue("mxbean");
+ if (mxbean == null || !mxbean.equals("true")) {
+ throw new RuntimeException(
"Platform MBeans must be MXBeans!");
- }
- if (!(mbean instanceof StandardMBean)) {
- throw new RuntimeException(
+ }
+ if (!(mbean instanceof StandardMBean)) {
+ throw new RuntimeException(
"MXBeans must be wrapped in StandardMBean!");
+ }
}
}
return result;