1651 lines · 57.7 KB · Java
RawDownload
/* * 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.