# HG changeset patch
# User fparain
# Date 1305559698 -7200
# Node ID e0c3fd538f1f703a64f9267a8e83a06e1530faa3
# Parent cecfcb4dbcaa751d2cc3d00f3a889ac2cfcd8fb1
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
Summary: Add a JMX notification to GarbageCollectorMXBeans
Reviewed-by: acorn, mchung
diff -r cecfcb4dbcaa -r e0c3fd538f1f make/java/management/mapfile-vers
--- a/make/java/management/mapfile-vers Mon May 16 13:10:59 2011 +0100
+++ b/make/java/management/mapfile-vers Mon May 16 17:28:18 2011 +0200
@@ -49,6 +49,7 @@
Java_sun_management_Flag_setStringValue;
Java_sun_management_GarbageCollectorImpl_getCollectionCount;
Java_sun_management_GarbageCollectorImpl_getCollectionTime;
+ Java_sun_management_GarbageCollectorImpl_setNotificationEnabled;
Java_sun_management_GcInfoBuilder_fillGcAttributeInfo;
Java_sun_management_GcInfoBuilder_getLastGcInfo0;
Java_sun_management_GcInfoBuilder_getNumGcExtAttributes;
diff -r cecfcb4dbcaa -r e0c3fd538f1f src/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java Mon May 16 17:28:18 2011 +0200
@@ -0,0 +1,237 @@
+/*
+ * 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 javax.management.Notification;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataView;
+import javax.management.openmbean.CompositeType;
+import java.util.Collection;
+import java.util.Collections;
+import sun.management.GarbageCollectionNotifInfoCompositeData;
+
+/**
+ * The information about a garbage collection
+ *
+ *
+ * A garbage collection notification is emitted by {@link GarbageCollectorMXBean}
+ * when the Java virtual machine completes a garbage collection action
+ * The notification emitted will contain the garbage collection notification
+ * information about the status of the memory:
+ *
+ *
The name of the garbage collector used perform the collection.
+ *
The action performed by the garbage collector.
+ *
The cause of the garbage collection action.
+ *
A {@link GcInfo} object containing some statistics about the GC cycle
+ (start time, end time) and the memory usage before and after
+ the GC cycle.
+ *
+ *
+ *
+ * A {@link CompositeData CompositeData} representing
+ * the {@code GarbageCollectionNotificationInfo} object
+ * is stored in the
+ * {@linkplain javax.management.Notification#setUserData userdata}
+ * of a {@linkplain javax.management.Notification notification}.
+ * The {@link #from from} method is provided to convert from
+ * a {@code CompositeData} to a {@code GarbageCollectionNotificationInfo}
+ * object. For example:
+ *
+ *
+ * Notification notif;
+ *
+ * // receive the notification emitted by a GarbageCollectorMXBean and set to notif
+ * ...
+ *
+ * String notifType = notif.getType();
+ * if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
+ * // retrieve the garbage collection notification information
+ * CompositeData cd = (CompositeData) notif.getUserData();
+ * GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
+ * ....
+ * }
+ *
+ *
+ *
+ * The type of the notification emitted by a {@code GarbageCollectorMXBean} is:
+ *
+ *
A {@linkplain #GARBAGE_COLLECTION_NOTIFICATION garbage collection notification}.
+ * Used by every notification emitted by the garbage collector, the details about
+ * the notification are provided in the {@linkplain #getGcAction action} String
+ *
+ *
+ **/
+
+public class GarbageCollectionNotificationInfo implements CompositeDataView {
+
+ private final String gcName;
+ private final String gcAction;
+ private final String gcCause;
+ private final GcInfo gcInfo;
+ private final CompositeData cdata;
+
+ /**
+ * Notification type denoting that
+ * the Java virtual machine has completed a garbage collection cycle.
+ * This notification is emitted by a {@link GarbageCollectorMXBean}.
+ * The value of this notification type is
+ * {@code com.sun.management.gc.notification}.
+ */
+ public static final String GARBAGE_COLLECTION_NOTIFICATION =
+ "com.sun.management.gc.notification";
+
+ /**
+ * Constructs a {@code GarbageCollectionNotificationInfo} object.
+ *
+ * @param gcName The name of the garbage collector used to perform the collection
+ * @param gcAction The name of the action performed by the garbage collector
+ * @param gcCause The cause the garbage collection action
+ * @param gcInfo a GcInfo object providing statistics about the GC cycle
+ */
+ public GarbageCollectionNotificationInfo(String gcName,
+ String gcAction,
+ String gcCause,
+ GcInfo gcInfo) {
+ if (gcName == null) {
+ throw new NullPointerException("Null gcName");
+ }
+ if (gcAction == null) {
+ throw new NullPointerException("Null gcAction");
+ }
+ if (gcCause == null) {
+ throw new NullPointerException("Null gcCause");
+ }
+ this.gcName = gcName;
+ this.gcAction = gcAction;
+ this.gcCause = gcCause;
+ this.gcInfo = gcInfo;
+ this.cdata = new GarbageCollectionNotifInfoCompositeData(this);
+ }
+
+ GarbageCollectionNotificationInfo(CompositeData cd) {
+ GarbageCollectionNotifInfoCompositeData.validateCompositeData(cd);
+
+ this.gcName = GarbageCollectionNotifInfoCompositeData.getGcName(cd);
+ this.gcAction = GarbageCollectionNotifInfoCompositeData.getGcAction(cd);
+ this.gcCause = GarbageCollectionNotifInfoCompositeData.getGcCause(cd);
+ this.gcInfo = GarbageCollectionNotifInfoCompositeData.getGcInfo(cd);
+ this.cdata = cd;
+ }
+
+ /**
+ * Returns the name of the garbage collector used to perform the collection
+ *
+ * @return the name of the garbage collector used to perform the collection
+ */
+ public String getGcName() {
+ return gcName;
+ }
+
+ /**
+ * Returns the action of the performed by the garbage collector
+ *
+ * @return the the action of the performed by the garbage collector
+ */
+ public String getGcAction() {
+ return gcAction;
+ }
+
+ /**
+ * Returns the cause the garbage collection
+ *
+ * @return the the cause the garbage collection
+ */
+ public String getGcCause() {
+ return gcCause;
+ }
+
+ /**
+ * Returns the GC information related to the last garbage collection
+ *
+ * @return the GC information related to the
+ * last garbage collection
+ */
+ public GcInfo getGcInfo() {
+ return gcInfo;
+ }
+
+ /**
+ * Returns a {@code GarbageCollectionNotificationInfo} object represented by the
+ * given {@code CompositeData}.
+ * The given {@code CompositeData} must contain
+ * the following attributes:
+ *
+ *
+ *
+ *
Attribute Name
+ *
Type
+ *
+ *
+ *
gcName
+ *
{@code java.lang.String}
+ *
+ *
+ *
gcAction
+ *
{@code java.lang.String}
+ *
+ *
+ *
gcCause
+ *
{@code java.lang.String}
+ *
+ *
+ *
gcInfo
+ *
{@code javax.management.openmbean.CompositeData}
+ *
+ *
+ *
+ *
+ * @param cd {@code CompositeData} representing a
+ * {@code GarbageCollectionNotificationInfo}
+ *
+ * @throws IllegalArgumentException if {@code cd} does not
+ * represent a {@code GarbaageCollectionNotificationInfo} object.
+ *
+ * @return a {@code GarbageCollectionNotificationInfo} object represented
+ * by {@code cd} if {@code cd} is not {@code null};
+ * {@code null} otherwise.
+ */
+ public static GarbageCollectionNotificationInfo from(CompositeData cd) {
+ if (cd == null) {
+ return null;
+ }
+
+ if (cd instanceof GarbageCollectionNotifInfoCompositeData) {
+ return ((GarbageCollectionNotifInfoCompositeData) cd).getGarbageCollectionNotifInfo();
+ } else {
+ return new GarbageCollectionNotificationInfo(cd);
+ }
+ }
+
+ public CompositeData toCompositeData(CompositeType ct) {
+ return cdata;
+ }
+
+}
diff -r cecfcb4dbcaa -r e0c3fd538f1f src/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java Mon May 16 17:28:18 2011 +0200
@@ -0,0 +1,219 @@
+/*
+ * 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.management;
+
+import com.sun.management.GarbageCollectionNotificationInfo;
+import com.sun.management.GcInfo;
+import java.lang.reflect.Method;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+
+/**
+ * A CompositeData for GarbageCollectionNotificationInfo for the local management support.
+ * This class avoids the performance penalty paid to the
+ * construction of a CompositeData use in the local case.
+ */
+public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData {
+ private final GarbageCollectionNotificationInfo gcNotifInfo;
+
+ public GarbageCollectionNotifInfoCompositeData(GarbageCollectionNotificationInfo info) {
+ this.gcNotifInfo = info;
+ }
+
+ public GarbageCollectionNotificationInfo getGarbageCollectionNotifInfo() {
+ return gcNotifInfo;
+ }
+
+ public static CompositeData toCompositeData(GarbageCollectionNotificationInfo info) {
+ GarbageCollectionNotifInfoCompositeData gcnicd =
+ new GarbageCollectionNotifInfoCompositeData(info);
+ return gcnicd.getCompositeData();
+ }
+
+ private CompositeType getCompositeTypeByBuilder() {
+ final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction() {
+ public GcInfoBuilder run() {
+ try {
+ Class cl = Class.forName("com.sun.management.GcInfo");
+ Field f = cl.getDeclaredField("builder");
+ f.setAccessible(true);
+ return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo());
+ } catch(ClassNotFoundException e) {
+ return null;
+ } catch(NoSuchFieldException e) {
+ return null;
+ } catch(IllegalAccessException e) {
+ return null;
+ }
+ }
+ });
+ CompositeType gict = null;
+ synchronized(compositeTypeByBuilder) {
+ gict = compositeTypeByBuilder.get(builder);
+ if(gict == null) {
+ OpenType[] gcNotifInfoItemTypes = new OpenType[] {
+ SimpleType.STRING,
+ SimpleType.STRING,
+ SimpleType.STRING,
+ builder.getGcInfoCompositeType(),
+ };
+ try {
+ final String typeName =
+ "sun.management.GarbageCollectionNotifInfoCompositeType";
+ gict = new CompositeType(typeName,
+ "CompositeType for GC notification info",
+ gcNotifInfoItemNames,
+ gcNotifInfoItemNames,
+ gcNotifInfoItemTypes);
+ compositeTypeByBuilder.put(builder,gict);
+ } catch (OpenDataException e) {
+ // shouldn't reach here
+ throw Util.newException(e);
+ }
+ }
+ }
+ return gict;
+ }
+
+ protected CompositeData getCompositeData() {
+ // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
+ // gcNotifInfoItemNames!
+ final Object[] gcNotifInfoItemValues;
+ gcNotifInfoItemValues = new Object[] {
+ gcNotifInfo.getGcName(),
+ gcNotifInfo.getGcAction(),
+ gcNotifInfo.getGcCause(),
+ GcInfoCompositeData.toCompositeData(gcNotifInfo.getGcInfo())
+ };
+
+ CompositeType gict = getCompositeTypeByBuilder();
+
+ try {
+ return new CompositeDataSupport(gict,
+ gcNotifInfoItemNames,
+ gcNotifInfoItemValues);
+ } catch (OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ // private static MappedMXBeanType gcInfoMapType;
+ private static final String GC_NAME = "gcName";
+ private static final String GC_ACTION = "gcAction";
+ private static final String GC_CAUSE = "gcCause";
+ private static final String GC_INFO = "gcInfo";
+ private static final String[] gcNotifInfoItemNames = {
+ GC_NAME,
+ GC_ACTION,
+ GC_CAUSE,
+ GC_INFO
+ };
+ private static HashMap compositeTypeByBuilder =
+ new HashMap();
+
+ public static String getGcName(CompositeData cd) {
+ String gcname = getString(cd, GC_NAME);
+ if (gcname == null) {
+ throw new IllegalArgumentException("Invalid composite data: " +
+ "Attribute " + GC_NAME + " has null value");
+ }
+ return gcname;
+ }
+
+ public static String getGcAction(CompositeData cd) {
+ String gcaction = getString(cd, GC_ACTION);
+ if (gcaction == null) {
+ throw new IllegalArgumentException("Invalid composite data: " +
+ "Attribute " + GC_ACTION + " has null value");
+ }
+ return gcaction;
+ }
+
+ public static String getGcCause(CompositeData cd) {
+ String gccause = getString(cd, GC_CAUSE);
+ if (gccause == null) {
+ throw new IllegalArgumentException("Invalid composite data: " +
+ "Attribute " + GC_CAUSE + " has null value");
+ }
+ return gccause;
+ }
+
+ public static GcInfo getGcInfo(CompositeData cd) {
+ CompositeData gcInfoData = (CompositeData) cd.get(GC_INFO);
+ return GcInfo.from(gcInfoData);
+ }
+
+ /** Validate if the input CompositeData has the expected
+ * CompositeType (i.e. contain all attributes with expected
+ * names and types).
+ */
+ public static void validateCompositeData(CompositeData cd) {
+ if (cd == null) {
+ throw new NullPointerException("Null CompositeData");
+ }
+
+ if (!isTypeMatched( getBaseGcNotifInfoCompositeType(), cd.getCompositeType())) {
+ throw new IllegalArgumentException(
+ "Unexpected composite type for GarbageCollectionNotificationInfo");
+ }
+ }
+
+ // This is only used for validation.
+ private static CompositeType baseGcNotifInfoCompositeType = null;
+ private static synchronized CompositeType getBaseGcNotifInfoCompositeType() {
+ if (baseGcNotifInfoCompositeType == null) {
+ try {
+ OpenType[] baseGcNotifInfoItemTypes = new OpenType[] {
+ SimpleType.STRING,
+ SimpleType.STRING,
+ SimpleType.STRING,
+ GcInfoCompositeData.getBaseGcInfoCompositeType()
+ };
+ baseGcNotifInfoCompositeType =
+ new CompositeType("sun.management.BaseGarbageCollectionNotifInfoCompositeType",
+ "CompositeType for Base GarbageCollectionNotificationInfo",
+ gcNotifInfoItemNames,
+ gcNotifInfoItemNames,
+ baseGcNotifInfoItemTypes);
+ } catch (OpenDataException e) {
+ // shouldn't reach here
+ throw Util.newException(e);
+ }
+ }
+ return baseGcNotifInfoCompositeType;
+ }
+
+ private static final long serialVersionUID = -1805123446483771292L;
+}
diff -r cecfcb4dbcaa -r e0c3fd538f1f src/share/classes/sun/management/GarbageCollectorImpl.java
--- a/src/share/classes/sun/management/GarbageCollectorImpl.java Mon May 16 13:10:59 2011 +0100
+++ b/src/share/classes/sun/management/GarbageCollectorImpl.java Mon May 16 17:28:18 2011 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -26,6 +26,7 @@
package sun.management;
import com.sun.management.GarbageCollectorMXBean;
+import com.sun.management.GarbageCollectionNotificationInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
@@ -35,9 +36,15 @@
import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.ObjectName;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ListenerNotFoundException;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
/**
* Implementation class for the garbage collector.
@@ -78,19 +85,111 @@
// Sun JDK extension
private GcInfoBuilder gcInfoBuilder;
+
+ private synchronized GcInfoBuilder getGcInfoBuilder() {
+ if(gcInfoBuilder == null) {
+ gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames());
+ }
+ return gcInfoBuilder;
+ }
+
public GcInfo getLastGcInfo() {
+ GcInfo info = getGcInfoBuilder().getLastGcInfo();
+ return info;
+ }
+
+ private final static String notifName =
+ "javax.management.Notification";
+
+ private final static String[] gcNotifTypes = {
+ GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION
+ };
+
+ private MBeanNotificationInfo[] notifInfo = null;
+ public MBeanNotificationInfo[] getNotificationInfo() {
synchronized (this) {
- if (gcInfoBuilder == null) {
- gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames());
+ if (notifInfo == null) {
+ notifInfo = new MBeanNotificationInfo[1];
+ notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes,
+ notifName,
+ "GC Notification");
}
}
+ return notifInfo;
+ }
- GcInfo info = gcInfoBuilder.getLastGcInfo();
- return info;
+ private static long seqNumber = 0;
+ private static long getNextSeqNumber() {
+ return ++seqNumber;
+ }
+
+ void createGCNotification(long timestamp,
+ String gcName,
+ String gcAction,
+ String gcCause,
+ GcInfo gcInfo) {
+
+ if (!hasListeners()) {
+ return;
+ }
+
+ Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION,
+ getObjectName(),
+ getNextSeqNumber(),
+ timestamp,
+ gcName);
+ GarbageCollectionNotificationInfo info =
+ new GarbageCollectionNotificationInfo(gcName,
+ gcAction,
+ gcCause,
+ gcInfo);
+
+ CompositeData cd =
+ GarbageCollectionNotifInfoCompositeData.toCompositeData(info);
+ notif.setUserData(cd);
+ sendNotification(notif);
+ }
+
+ 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(this, true);
+ }
+ }
+
+ public synchronized void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener);
+ boolean after = hasListeners();
+ if (before && !after) {
+ setNotificationEnabled(this,false);
+ }
+ }
+
+ 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(this,false);
+ }
}
public ObjectName getObjectName() {
return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName());
}
+ native void setNotificationEnabled(GarbageCollectorMXBean gc,
+ boolean enabled);
+
}
diff -r cecfcb4dbcaa -r e0c3fd538f1f src/share/classes/sun/management/GcInfoCompositeData.java
--- a/src/share/classes/sun/management/GcInfoCompositeData.java Mon May 16 13:10:59 2011 +0100
+++ b/src/share/classes/sun/management/GcInfoCompositeData.java Mon May 16 17:28:18 2011 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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,6 +27,7 @@
import java.lang.management.MemoryUsage;
import java.lang.reflect.Method;
+import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
@@ -41,6 +42,9 @@
import javax.management.openmbean.OpenType;
import javax.management.openmbean.OpenDataException;
import com.sun.management.GcInfo;
+import com.sun.management.GarbageCollectionNotificationInfo;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/**
* A CompositeData for GcInfo for the local management support.
@@ -64,6 +68,44 @@
return info;
}
+ public static CompositeData toCompositeData(final GcInfo info) {
+ final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction() {
+ public GcInfoBuilder run() {
+ try {
+ Class cl = Class.forName("com.sun.management.GcInfo");
+ Field f = cl.getDeclaredField("builder");
+ f.setAccessible(true);
+ return (GcInfoBuilder)f.get(info);
+ } catch(ClassNotFoundException e) {
+ return null;
+ } catch(NoSuchFieldException e) {
+ return null;
+ } catch(IllegalAccessException e) {
+ return null;
+ }
+ }
+ });
+ final Object[] extAttr = AccessController.doPrivileged (new PrivilegedAction