/* * Copyright (c) 1999, 2008, 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 javax.management.monitor; import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER;import com.sun.jmx.mbeanserver.GetPropertyAction;import com.sun.jmx.mbeanserver.Introspector;import java.io.IOException;import java.security.AccessControlContext;import java.security.AccessController;import java.security.PrivilegedAction;import java.security.ProtectionDomain;import java.util.List;import java.util.Map;import java.util.WeakHashMap;import java.util.concurrent.CopyOnWriteArrayList;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.ScheduledFuture;import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicLong;import java.util.logging.Level;import javax.management.AttributeNotFoundException;import javax.management.InstanceNotFoundException;import javax.management.IntrospectionException;import javax.management.MBeanAttributeInfo;import javax.management.MBeanException;import javax.management.MBeanInfo;import javax.management.MBeanRegistration;import javax.management.MBeanServer;import javax.management.MBeanServerConnection;import javax.management.NotificationBroadcasterSupport;import javax.management.ObjectName;import javax.management.ReflectionException;import static javax.management.monitor.MonitorNotification.*; /** * Defines the part common to all monitor MBeans. * A monitor MBean monitors values of an attribute common to a set of observed * MBeans. The observed attribute is monitored at intervals specified by the * granularity period. A gauge value (derived gauge) is derived from the values * of the observed attribute. * * * @since 1.5 */public abstract class Monitor extends NotificationBroadcasterSupport implements MonitorMBean, MBeanRegistration { /* * ------------------------------------------ * PACKAGE CLASSES * ------------------------------------------ */ static class ObservedObject { public ObservedObject(ObjectName observedObject) { this.observedObject = observedObject; } public final ObjectName getObservedObject() { return observedObject; } public final synchronized int getAlreadyNotified() { return alreadyNotified; } public final synchronized void setAlreadyNotified(int alreadyNotified) { this.alreadyNotified = alreadyNotified; } public final synchronized Object getDerivedGauge() { return derivedGauge; } public final synchronized void setDerivedGauge(Object derivedGauge) { this.derivedGauge = derivedGauge; } public final synchronized long getDerivedGaugeTimeStamp() { return derivedGaugeTimeStamp; } public final synchronized void setDerivedGaugeTimeStamp( long derivedGaugeTimeStamp) { this.derivedGaugeTimeStamp = derivedGaugeTimeStamp; } private final ObjectName observedObject; private int alreadyNotified; private Object derivedGauge; private long derivedGaugeTimeStamp; } /* * ------------------------------------------ * PRIVATE VARIABLES * ------------------------------------------ */ /** * Attribute to observe. */ private String observedAttribute; /** * Monitor granularity period (in milliseconds). * The default value is set to 10 seconds. */ private long granularityPeriod = 10000; /** * Monitor state. * The default value is set to <CODE>false</CODE>. */ private boolean isActive = false; /** * Monitor sequence number. * The default value is set to 0. */ private final AtomicLong sequenceNumber = new AtomicLong(); /** * Complex type attribute flag. * The default value is set to <CODE>false</CODE>. */ private boolean isComplexTypeAttribute = false; /** * First attribute name extracted from complex type attribute name. */ private String firstAttribute; /** * Remaining attribute names extracted from complex type attribute name. */ private final List<String> remainingAttributes = new CopyOnWriteArrayList<String>(); /** * AccessControlContext of the Monitor.start() caller. */ private static final AccessControlContext noPermissionsACC = new AccessControlContext( new ProtectionDomain[] {new ProtectionDomain(null, null)}); private volatile AccessControlContext acc = noPermissionsACC; /** * Scheduler Service. */ private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( new DaemonThreadFactory("Scheduler")); /** * Map containing the thread pool executor per thread group. */ private static final Map<ThreadPoolExecutor, Void> executors = new WeakHashMap<ThreadPoolExecutor, Void>(); /** * Lock for executors map. */ private static final Object executorsLock = new Object(); /** * Maximum Pool Size */ private static final int maximumPoolSize; static { final String maximumPoolSizeSysProp = "jmx.x.monitor.maximum.pool.size"; final String maximumPoolSizeStr = AccessController.doPrivileged( new GetPropertyAction(maximumPoolSizeSysProp)); if (maximumPoolSizeStr == null || maximumPoolSizeStr.trim().length() == 0) { maximumPoolSize = 10; } else { int maximumPoolSizeTmp = 10; try { maximumPoolSizeTmp = Integer.parseInt(maximumPoolSizeStr); } catch (NumberFormatException e) { if (MONITOR_LOGGER.isLoggable(Level.FINER)) { MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "<static initializer>", "Wrong value for " + maximumPoolSizeSysProp + " system property", e); MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "<static initializer>", maximumPoolSizeSysProp + " defaults to 10"); } maximumPoolSizeTmp = 10; } if (maximumPoolSizeTmp < 1) { maximumPoolSize = 1; } else { maximumPoolSize = maximumPoolSizeTmp; } } } /** * Future associated to the current monitor task. */ private Future<?> monitorFuture; /** * Scheduler task to be executed by the Scheduler Service. */ private final SchedulerTask schedulerTask = new SchedulerTask(); /** * ScheduledFuture associated to the current scheduler task. */ private ScheduledFuture<?> schedulerFuture; /* * ------------------------------------------ * PROTECTED VARIABLES * ------------------------------------------ */ /** * The amount by which the capacity of the monitor arrays are * automatically incremented when their size becomes greater than * their capacity. */ protected final static int capacityIncrement = 16; /** * The number of valid components in the vector of observed objects. * */ protected int elementCount = 0; /** * Monitor errors that have already been notified. * @deprecated equivalent to {@link #alreadyNotifieds}[0]. */ @Deprecated protected int alreadyNotified = 0; /** * <p>Selected monitor errors that have already been notified.</p> * * <p>Each element in this array corresponds to an observed object * in the vector. It contains a bit mask of the flags {@link * #OBSERVED_OBJECT_ERROR_NOTIFIED} etc, indicating whether the * corresponding notification has already been sent for the MBean * being monitored.</p> * */ protected int alreadyNotifieds[] = new int[capacityIncrement]; /** * Reference to the MBean server. This reference is null when the * monitor MBean is not registered in an MBean server. This * reference is initialized before the monitor MBean is registered * in the MBean server. * @see #preRegister(MBeanServer server, ObjectName name) */ protected MBeanServer server; // Flags defining possible monitor errors. // /** * This flag is used to reset the {@link #alreadyNotifieds * alreadyNotifieds} monitor attribute. */ protected static final int RESET_FLAGS_ALREADY_NOTIFIED = 0; /** * Flag denoting that a notification has occurred after changing * the observed object. This flag is used to check that the new * observed object is registered in the MBean server at the time * of the first notification. */ protected static final int OBSERVED_OBJECT_ERROR_NOTIFIED = 1; /** * Flag denoting that a notification has occurred after changing * the observed attribute. This flag is used to check that the * new observed attribute belongs to the observed object at the * time of the first notification. */ protected static final int OBSERVED_ATTRIBUTE_ERROR_NOTIFIED = 2; /** * Flag denoting that a notification has occurred after changing * the observed object or the observed attribute. This flag is * used to check that the observed attribute type is correct * (depending on the monitor in use) at the time of the first * notification. */ protected static final int OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 4; /** * Flag denoting that a notification has occurred after changing * the observed object or the observed attribute. This flag is * used to notify any exception (except the cases described above) * when trying to get the value of the observed attribute at the * time of the first notification. */ protected static final int RUNTIME_ERROR_NOTIFIED = 8; /** * This field is retained for compatibility but should not be referenced. * * @deprecated No replacement. */ @Deprecated protected String dbgTag = Monitor.class.getName(); /* * ------------------------------------------ * PACKAGE VARIABLES * ------------------------------------------ */ /** * List of ObservedObjects to which the attribute to observe belongs. */ final List<ObservedObject> observedObjects = new CopyOnWriteArrayList<ObservedObject>(); /** * Flag denoting that a notification has occurred after changing * the threshold. This flag is used to notify any exception * related to invalid thresholds settings. */ static final int THRESHOLD_ERROR_NOTIFIED = 16; /** * Enumeration used to keep trace of the derived gauge type * in counter and gauge monitors. */ enum NumericalType { BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE }; /** * Constant used to initialize all the numeric values. */ static final Integer INTEGER_ZERO = 0; /* * ------------------------------------------ * PUBLIC METHODS * ------------------------------------------ */ /** * Allows the monitor MBean to perform any operations it needs * before being registered in the MBean server. * <P> * Initializes the reference to the MBean server. * * @param server The MBean server in which the monitor MBean will * be registered. * @param name The object name of the monitor MBean. * * @return The name of the monitor MBean registered. * * @exception Exception */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "preRegister(MBeanServer, ObjectName)", "initialize the reference on the MBean server"); this.server = server; return name; } /** * Allows the monitor MBean to perform any operations needed after * having been registered in the MBean server or after the * registration has failed. * <P> * Not used in this context. */ public void postRegister(Boolean registrationDone) { } /** * Allows the monitor MBean to perform any operations it needs * before being unregistered by the MBean server. * <P> * Stops the monitor. * * @exception Exception */ public void preDeregister() throws Exception { MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "preDeregister()", "stop the monitor"); // Stop the Monitor. // stop(); } /** * Allows the monitor MBean to perform any operations needed after * having been unregistered by the MBean server. * <P> * Not used in this context. */ public void postDeregister() { } /** * Starts the monitor. */ public abstract void start(); /** * Stops the monitor. */ public abstract void stop(); // GETTERS AND SETTERS //-------------------- /** * Returns the object name of the first object in the set of observed * MBeans, or <code>null</code> if there is no such object. * * @return The object being observed. * * @see #setObservedObject(ObjectName) * * @deprecated As of JMX 1.2, replaced by {@link #getObservedObjects} */ @Deprecated public synchronized ObjectName getObservedObject() { if (observedObjects.isEmpty()) { return null; } else { return observedObjects.get(0).getObservedObject(); } } /** * Removes all objects from the set of observed objects, and then adds the * specified object. * * @param object The object to observe. * @exception IllegalArgumentException The specified * object is null. * * @see #getObservedObject() * * @deprecated As of JMX 1.2, replaced by {@link #addObservedObject} */ @Deprecated public synchronized void setObservedObject(ObjectName object) throws IllegalArgumentException { if (object == null) throw new IllegalArgumentException("Null observed object"); if (observedObjects.size() == 1 && containsObservedObject(object)) return; observedObjects.clear(); addObservedObject(object); } /** * Adds the specified object in the set of observed MBeans, if this object * is not already present. * * @param object The object to observe. * @exception IllegalArgumentException The specified object is null. *Lines 1–500 of 1651. Load more
/* * Copyright (c) 1999, 2008, 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 javax.management.monitor; import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER; import com.sun.jmx.mbeanserver.GetPropertyAction; import com.sun.jmx.mbeanserver.Introspector; import java.io.IOException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; import javax.management.ReflectionException; import static javax.management.monitor.MonitorNotification.*; /** * Defines the part common to all monitor MBeans. * A monitor MBean monitors values of an attribute common to a set of observed * MBeans. The observed attribute is monitored at intervals specified by the * granularity period. A gauge value (derived gauge) is derived from the values * of the observed attribute. * * * @since 1.5 */ public abstract class Monitor extends NotificationBroadcasterSupport implements MonitorMBean, MBeanRegistration { /* * ------------------------------------------ * PACKAGE CLASSES * ------------------------------------------ */ static class ObservedObject { public ObservedObject(ObjectName observedObject) { this.observedObject = observedObject; } public final ObjectName getObservedObject() { return observedObject; } public final synchronized int getAlreadyNotified() { return alreadyNotified; } public final synchronized void setAlreadyNotified(int alreadyNotified) { this.alreadyNotified = alreadyNotified; } public final synchronized Object getDerivedGauge() { return derivedGauge; } public final synchronized void setDerivedGauge(Object derivedGauge) { this.derivedGauge = derivedGauge; } public final synchronized long getDerivedGaugeTimeStamp() { return derivedGaugeTimeStamp; } public final synchronized void setDerivedGaugeTimeStamp( long derivedGaugeTimeStamp) { this.derivedGaugeTimeStamp = derivedGaugeTimeStamp; } private final ObjectName observedObject; private int alreadyNotified; private Object derivedGauge; private long derivedGaugeTimeStamp; } /* * ------------------------------------------ * PRIVATE VARIABLES * ------------------------------------------ */ /** * Attribute to observe. */ private String observedAttribute; /** * Monitor granularity period (in milliseconds). * The default value is set to 10 seconds. */ private long granularityPeriod = 10000; /** * Monitor state. * The default value is set to <CODE>false</CODE>. */ private boolean isActive = false; /** * Monitor sequence number. * The default value is set to 0. */ private final AtomicLong sequenceNumber = new AtomicLong(); /** * Complex type attribute flag. * The default value is set to <CODE>false</CODE>. */ private boolean isComplexTypeAttribute = false; /** * First attribute name extracted from complex type attribute name. */ private String firstAttribute; /** * Remaining attribute names extracted from complex type attribute name. */ private final List<String> remainingAttributes = new CopyOnWriteArrayList<String>(); /** * AccessControlContext of the Monitor.start() caller. */ private static final AccessControlContext noPermissionsACC = new AccessControlContext( new ProtectionDomain[] {new ProtectionDomain(null, null)}); private volatile AccessControlContext acc = noPermissionsACC; /** * Scheduler Service. */ private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( new DaemonThreadFactory("Scheduler")); /** * Map containing the thread pool executor per thread group. */ private static final Map<ThreadPoolExecutor, Void> executors = new WeakHashMap<ThreadPoolExecutor, Void>(); /** * Lock for executors map. */ private static final Object executorsLock = new Object(); /** * Maximum Pool Size */ private static final int maximumPoolSize; static { final String maximumPoolSizeSysProp = "jmx.x.monitor.maximum.pool.size"; final String maximumPoolSizeStr = AccessController.doPrivileged( new GetPropertyAction(maximumPoolSizeSysProp)); if (maximumPoolSizeStr == null || maximumPoolSizeStr.trim().length() == 0) { maximumPoolSize = 10; } else { int maximumPoolSizeTmp = 10; try { maximumPoolSizeTmp = Integer.parseInt(maximumPoolSizeStr); } catch (NumberFormatException e) { if (MONITOR_LOGGER.isLoggable(Level.FINER)) { MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "<static initializer>", "Wrong value for " + maximumPoolSizeSysProp + " system property", e); MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "<static initializer>", maximumPoolSizeSysProp + " defaults to 10"); } maximumPoolSizeTmp = 10; } if (maximumPoolSizeTmp < 1) { maximumPoolSize = 1; } else { maximumPoolSize = maximumPoolSizeTmp; } } } /** * Future associated to the current monitor task. */ private Future<?> monitorFuture; /** * Scheduler task to be executed by the Scheduler Service. */ private final SchedulerTask schedulerTask = new SchedulerTask(); /** * ScheduledFuture associated to the current scheduler task. */ private ScheduledFuture<?> schedulerFuture; /* * ------------------------------------------ * PROTECTED VARIABLES * ------------------------------------------ */ /** * The amount by which the capacity of the monitor arrays are * automatically incremented when their size becomes greater than * their capacity. */ protected final static int capacityIncrement = 16; /** * The number of valid components in the vector of observed objects. * */ protected int elementCount = 0; /** * Monitor errors that have already been notified. * @deprecated equivalent to {@link #alreadyNotifieds}[0]. */ @Deprecated protected int alreadyNotified = 0; /** * <p>Selected monitor errors that have already been notified.</p> * * <p>Each element in this array corresponds to an observed object * in the vector. It contains a bit mask of the flags {@link * #OBSERVED_OBJECT_ERROR_NOTIFIED} etc, indicating whether the * corresponding notification has already been sent for the MBean * being monitored.</p> * */ protected int alreadyNotifieds[] = new int[capacityIncrement]; /** * Reference to the MBean server. This reference is null when the * monitor MBean is not registered in an MBean server. This * reference is initialized before the monitor MBean is registered * in the MBean server. * @see #preRegister(MBeanServer server, ObjectName name) */ protected MBeanServer server; // Flags defining possible monitor errors. // /** * This flag is used to reset the {@link #alreadyNotifieds * alreadyNotifieds} monitor attribute. */ protected static final int RESET_FLAGS_ALREADY_NOTIFIED = 0; /** * Flag denoting that a notification has occurred after changing * the observed object. This flag is used to check that the new * observed object is registered in the MBean server at the time * of the first notification. */ protected static final int OBSERVED_OBJECT_ERROR_NOTIFIED = 1; /** * Flag denoting that a notification has occurred after changing * the observed attribute. This flag is used to check that the * new observed attribute belongs to the observed object at the * time of the first notification. */ protected static final int OBSERVED_ATTRIBUTE_ERROR_NOTIFIED = 2; /** * Flag denoting that a notification has occurred after changing * the observed object or the observed attribute. This flag is * used to check that the observed attribute type is correct * (depending on the monitor in use) at the time of the first * notification. */ protected static final int OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 4; /** * Flag denoting that a notification has occurred after changing * the observed object or the observed attribute. This flag is * used to notify any exception (except the cases described above) * when trying to get the value of the observed attribute at the * time of the first notification. */ protected static final int RUNTIME_ERROR_NOTIFIED = 8; /** * This field is retained for compatibility but should not be referenced. * * @deprecated No replacement. */ @Deprecated protected String dbgTag = Monitor.class.getName(); /* * ------------------------------------------ * PACKAGE VARIABLES * ------------------------------------------ */ /** * List of ObservedObjects to which the attribute to observe belongs. */ final List<ObservedObject> observedObjects = new CopyOnWriteArrayList<ObservedObject>(); /** * Flag denoting that a notification has occurred after changing * the threshold. This flag is used to notify any exception * related to invalid thresholds settings. */ static final int THRESHOLD_ERROR_NOTIFIED = 16; /** * Enumeration used to keep trace of the derived gauge type * in counter and gauge monitors. */ enum NumericalType { BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE }; /** * Constant used to initialize all the numeric values. */ static final Integer INTEGER_ZERO = 0; /* * ------------------------------------------ * PUBLIC METHODS * ------------------------------------------ */ /** * Allows the monitor MBean to perform any operations it needs * before being registered in the MBean server. * <P> * Initializes the reference to the MBean server. * * @param server The MBean server in which the monitor MBean will * be registered. * @param name The object name of the monitor MBean. * * @return The name of the monitor MBean registered. * * @exception Exception */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "preRegister(MBeanServer, ObjectName)", "initialize the reference on the MBean server"); this.server = server; return name; } /** * Allows the monitor MBean to perform any operations needed after * having been registered in the MBean server or after the * registration has failed. * <P> * Not used in this context. */ public void postRegister(Boolean registrationDone) { } /** * Allows the monitor MBean to perform any operations it needs * before being unregistered by the MBean server. * <P> * Stops the monitor. * * @exception Exception */ public void preDeregister() throws Exception { MONITOR_LOGGER.logp(Level.FINER, Monitor.class.getName(), "preDeregister()", "stop the monitor"); // Stop the Monitor. // stop(); } /** * Allows the monitor MBean to perform any operations needed after * having been unregistered by the MBean server. * <P> * Not used in this context. */ public void postDeregister() { } /** * Starts the monitor. */ public abstract void start(); /** * Stops the monitor. */ public abstract void stop(); // GETTERS AND SETTERS //-------------------- /** * Returns the object name of the first object in the set of observed * MBeans, or <code>null</code> if there is no such object. * * @return The object being observed. * * @see #setObservedObject(ObjectName) * * @deprecated As of JMX 1.2, replaced by {@link #getObservedObjects} */ @Deprecated public synchronized ObjectName getObservedObject() { if (observedObjects.isEmpty()) { return null; } else { return observedObjects.get(0).getObservedObject(); } } /** * Removes all objects from the set of observed objects, and then adds the * specified object. * * @param object The object to observe. * @exception IllegalArgumentException The specified * object is null. * * @see #getObservedObject() * * @deprecated As of JMX 1.2, replaced by {@link #addObservedObject} */ @Deprecated public synchronized void setObservedObject(ObjectName object) throws IllegalArgumentException { if (object == null) throw new IllegalArgumentException("Null observed object"); if (observedObjects.size() == 1 && containsObservedObject(object)) return; observedObjects.clear(); addObservedObject(object); } /** * Adds the specified object in the set of observed MBeans, if this object * is not already present. * * @param object The object to observe. * @exception IllegalArgumentException The specified object is null. *