diff --git a/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java b/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java index 7aab1e46..f7b0db10 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java @@ -1,273 +1,273 @@ -/* - * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. - * This file is part of SIGAR. - * - * SIGAR is free software; you can redistribute it and/or modify - * it under the terms version 2 of the GNU General Public License as - * published by the Free Software Foundation. This program 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 for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -package org.hyperic.sigar.jmx; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.DynamicMBean; -import javax.management.MBeanException; -import javax.management.MBeanRegistration; -import javax.management.MBeanServer; -import javax.management.ObjectName; -import javax.management.ReflectionException; - -import org.hyperic.sigar.Sigar; -import org.hyperic.sigar.SigarException; -import org.hyperic.sigar.SigarProxy; -import org.hyperic.sigar.SigarProxyCache; - -/** - * Base class for all Sigar JMX MBeans. Provides a skeleton which handles - * creation of the Sigar proxy instance and provides some convenience methods. - * It also enforces usage of the {@link DynamicMBean} inferface while - * implementing part of it, and it adds empty implementations for all methods of - * the {@link MBeanRegistration} interface, allowing subclasses to only - * implement subset of them. - * - * @author Bjoern Martin - * @since 1.5 - */ -public abstract class AbstractMBean implements DynamicMBean, MBeanRegistration { - - public static final String MBEAN_DOMAIN = SigarInvokerJMX.DOMAIN_NAME; - public static final String MBEAN_ATTR_TYPE = SigarInvokerJMX.PROP_TYPE; - - protected static final short CACHED_30SEC = 0; - - protected static final short CACHED_5SEC = 1; - - protected static final short CACHED_500MS = 2; - - protected static final short CACHELESS = 3; - - protected static final short DEFAULT = CACHED_30SEC; - - /** - * The Sigar implementation to be used to fetch information from the system. - */ - protected final Sigar sigarImpl; - - /** - * The Sigar proxy cache to be used in case the data does not have to be - * fetched during each call. The cache timeout is decided during - * construction. See {@link AbstractMBean#AbstractMBean(Sigar, short)} for - * details. - * - * @see AbstractMBean#AbstractMBean(Sigar, short) - */ - protected final SigarProxy sigar; - - /** - * The MBean server this MBean is registered to. Set during the MBean's - * registration to the MBean server and unset to null when - * the deregistration finished. - * - * @see #preRegister(MBeanServer, ObjectName) - * @see #postDeregister() - */ - protected MBeanServer mbeanServer; - - /** - *

Creates a new instance of this class. The Sigar instance is stored (and - * accessible) via the {@link #sigarImpl} member. A second instance is - * stored within the {@link #sigar} member which is either {@link #sigarImpl} - * or an instance of {@link SigarProxyCache} with the expiration time set to - * whatever the cacheMode parameter specifies.

- * - *

The following cache modes exist:

- * - * - * - * - * - * - * - * - *
ConstantDescription
{@link #CACHELESS}No cached instance, {@link #sigar} - * == {@link #sigarImpl}.
{@link #CACHED_500MS}500 millisecond cache, for high - * frequency queries on raw data such as reading out CPU timers each - * second. Avoids reading out multiple data sets when all attributes of - * an MBean are queried in short sequence.
{@link #CACHED_5SEC}5 second cache, for high frequency - * queries on calculated data such as CPU percentages.
{@link #CACHED_30SEC}30 second cache, for normal queries - * or data readouts such as CPU model / vendor. This is the default if - * nothing (0) is specified.
{@link #DEFAULT}Same as {@link #CACHED_30SEC}.
- * - *

Note: Only make use of the cacheless or half second mode if you - * know what you are doing. They may have impact on system performance if - * used excessively.

- * - * @param sigar The Sigar impl to use. Must not be null - * @param cacheMode The cache mode to use for {@link #sigar} or {@link #CACHELESS} - * if no separate, cached instance is to be maintained. - */ - protected AbstractMBean(Sigar sigar, short cacheMode) { - // store Sigar - this.sigarImpl = sigar; - - // create a cached instance as well - if (cacheMode == CACHELESS) { - // no cached version - this.sigar = this.sigarImpl; - - } else if (cacheMode == CACHED_500MS) { - // 500ms cached version (for 1/sec queries) - this.sigar = SigarProxyCache.newInstance(this.sigarImpl, 500); - - } else if (cacheMode == CACHED_5SEC) { - // 5sec cached version (for avg'd queries) - this.sigar = SigarProxyCache.newInstance(this.sigarImpl, 5000); - - } else /* if (cacheMode == CACHED_30SEC) */{ - // 30sec (default) cached version (for info and long term queries) - this.sigar = SigarProxyCache.newInstance(this.sigarImpl, 30000); - } - } - - /** - * Returns the object name the MBean is registered with within the - * MBeanServer. May be null in case the instance is not - * registered to an MBeanServer, but used standalone. - * - * @return The object name or null if not registered to an - * MBeanServer - */ - public abstract String getObjectName(); - - /** - * Returns a runtime exception for the type and SigarException specified. - * - * @param type - * The type that was called - * @param e - * The exception that was raised - * @return A runtime exception encapsulating the information specified - */ - protected RuntimeException unexpectedError(String type, SigarException e) { - String msg = "Unexected error in Sigar.get" + type + ": " - + e.getMessage(); - return new IllegalArgumentException(msg); - } - - /** - * Loops over all attributes and calls - * {@link DynamicMBean#getAttribute(java.lang.String)} method for each - * attribute sequentially. Any exception thrown by those methods are ignored - * and simply cause the attribute not being added to the result. - */ - public AttributeList getAttributes(String[] attrs) { - final AttributeList result = new AttributeList(); - for (int i = 0; i < attrs.length; i++) { - try { - result.add(new Attribute(attrs[i], getAttribute(attrs[i]))); - } catch (AttributeNotFoundException e) { - // ignore, as we cannot throw this exception - } catch (MBeanException e) { - // ignore, as we cannot throw this exception - } catch (ReflectionException e) { - // ignore, as we cannot throw this exception - } - } - return result; - } - - /** - * Loops over all attributes and calls - * {@link DynamicMBean#setAttribute(Attribute)} for each attribute - * sequentially. Any exception thrown by those methods are ignored and - * simply cause the attribute not being added to the result. - */ - public AttributeList setAttributes(AttributeList attrs) { - final AttributeList result = new AttributeList(); - for (int i = 0; i < attrs.size(); i++) { - try { - final Attribute next = (Attribute) attrs.get(i); - setAttribute(next); - result.add(next); - } catch (AttributeNotFoundException e) { - // ignore, as we cannot throw this exception - } - } - return result; - } - - // ------- - // Implementation of the MBeanRegistration interface - // ------- - - /** - *

Returns new ObjectName(this.getObjectName()) to guarantee - * a reliable and reproducable object name.

- * - *

Note: Make sure any subclass does a super call to this method, - * otherwise the implementation might be broken.

- * - * @see MBeanRegistration#preRegister(MBeanServer, ObjectName) - */ - public ObjectName preRegister(MBeanServer server, ObjectName name) - throws Exception { - this.mbeanServer = server; - return new ObjectName(getObjectName()); - } - - /** - * Empty implementation, allowing subclasses to ignore the interface. - * - *

Note: Make sure any subclass does a super call to this method, - * otherwise the implementation might be broken.

- * - * @see MBeanRegistration#postRegister(Boolean) - */ - public void postRegister(Boolean success) { - } - - /** - * Empty implementation, allowing subclasses to ignore the interface. - * - *

Note: Make sure any subclass does a super call to this method, - * otherwise the implementation might be broken.

- * - * @see MBeanRegistration#preDeregister() - */ - public void preDeregister() throws Exception { - } - - /** - * Empty implementation, allowing subclasses to ignore the interface. - * - *

Note: Make sure any subclass does a super call to this method, - * otherwise the implementation might be broken.

- * - * @see MBeanRegistration#postDeregister() - */ - public void postDeregister() { - this.mbeanServer = null; - } - - public void setAttribute(Attribute attr) throws AttributeNotFoundException { - throw new AttributeNotFoundException(attr.getName()); - } - - public Object invoke(String name, Object[] params, String[] signature) - throws ReflectionException { - - throw new ReflectionException(new NoSuchMethodException(name), - name); - } -} +/* + * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. + * This file is part of SIGAR. + * + * SIGAR is free software; you can redistribute it and/or modify + * it under the terms version 2 of the GNU General Public License as + * published by the Free Software Foundation. This program 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 for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package org.hyperic.sigar.jmx; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.MBeanException; +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.ReflectionException; + +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.SigarProxy; +import org.hyperic.sigar.SigarProxyCache; + +/** + * Base class for all Sigar JMX MBeans. Provides a skeleton which handles + * creation of the Sigar proxy instance and provides some convenience methods. + * It also enforces usage of the {@link DynamicMBean} inferface while + * implementing part of it, and it adds empty implementations for all methods of + * the {@link MBeanRegistration} interface, allowing subclasses to only + * implement subset of them. + * + * @author Bjoern Martin + * @since 1.5 + */ +public abstract class AbstractMBean implements DynamicMBean, MBeanRegistration { + + public static final String MBEAN_DOMAIN = SigarInvokerJMX.DOMAIN_NAME; + public static final String MBEAN_ATTR_TYPE = SigarInvokerJMX.PROP_TYPE; + + protected static final short CACHED_30SEC = 0; + + protected static final short CACHED_5SEC = 1; + + protected static final short CACHED_500MS = 2; + + protected static final short CACHELESS = 3; + + protected static final short DEFAULT = CACHED_30SEC; + + /** + * The Sigar implementation to be used to fetch information from the system. + */ + protected final Sigar sigarImpl; + + /** + * The Sigar proxy cache to be used in case the data does not have to be + * fetched during each call. The cache timeout is decided during + * construction. See {@link AbstractMBean#AbstractMBean(Sigar, short)} for + * details. + * + * @see AbstractMBean#AbstractMBean(Sigar, short) + */ + protected final SigarProxy sigar; + + /** + * The MBean server this MBean is registered to. Set during the MBean's + * registration to the MBean server and unset to null when + * the deregistration finished. + * + * @see #preRegister(MBeanServer, ObjectName) + * @see #postDeregister() + */ + protected MBeanServer mbeanServer; + + /** + *

Creates a new instance of this class. The Sigar instance is stored (and + * accessible) via the {@link #sigarImpl} member. A second instance is + * stored within the {@link #sigar} member which is either {@link #sigarImpl} + * or an instance of {@link SigarProxyCache} with the expiration time set to + * whatever the cacheMode parameter specifies.

+ * + *

The following cache modes exist:

+ * + * + * + * + * + * + * + * + *
ConstantDescription
{@link #CACHELESS}No cached instance, {@link #sigar} + * == {@link #sigarImpl}.
{@link #CACHED_500MS}500 millisecond cache, for high + * frequency queries on raw data such as reading out CPU timers each + * second. Avoids reading out multiple data sets when all attributes of + * an MBean are queried in short sequence.
{@link #CACHED_5SEC}5 second cache, for high frequency + * queries on calculated data such as CPU percentages.
{@link #CACHED_30SEC}30 second cache, for normal queries + * or data readouts such as CPU model / vendor. This is the default if + * nothing (0) is specified.
{@link #DEFAULT}Same as {@link #CACHED_30SEC}.
+ * + *

Note: Only make use of the cacheless or half second mode if you + * know what you are doing. They may have impact on system performance if + * used excessively.

+ * + * @param sigar The Sigar impl to use. Must not be null + * @param cacheMode The cache mode to use for {@link #sigar} or {@link #CACHELESS} + * if no separate, cached instance is to be maintained. + */ + protected AbstractMBean(Sigar sigar, short cacheMode) { + // store Sigar + this.sigarImpl = sigar; + + // create a cached instance as well + if (cacheMode == CACHELESS) { + // no cached version + this.sigar = this.sigarImpl; + + } else if (cacheMode == CACHED_500MS) { + // 500ms cached version (for 1/sec queries) + this.sigar = SigarProxyCache.newInstance(this.sigarImpl, 500); + + } else if (cacheMode == CACHED_5SEC) { + // 5sec cached version (for avg'd queries) + this.sigar = SigarProxyCache.newInstance(this.sigarImpl, 5000); + + } else /* if (cacheMode == CACHED_30SEC) */{ + // 30sec (default) cached version (for info and long term queries) + this.sigar = SigarProxyCache.newInstance(this.sigarImpl, 30000); + } + } + + /** + * Returns the object name the MBean is registered with within the + * MBeanServer. May be null in case the instance is not + * registered to an MBeanServer, but used standalone. + * + * @return The object name or null if not registered to an + * MBeanServer + */ + public abstract String getObjectName(); + + /** + * Returns a runtime exception for the type and SigarException specified. + * + * @param type + * The type that was called + * @param e + * The exception that was raised + * @return A runtime exception encapsulating the information specified + */ + protected RuntimeException unexpectedError(String type, SigarException e) { + String msg = "Unexected error in Sigar.get" + type + ": " + + e.getMessage(); + return new IllegalArgumentException(msg); + } + + /** + * Loops over all attributes and calls + * {@link DynamicMBean#getAttribute(java.lang.String)} method for each + * attribute sequentially. Any exception thrown by those methods are ignored + * and simply cause the attribute not being added to the result. + */ + public AttributeList getAttributes(String[] attrs) { + final AttributeList result = new AttributeList(); + for (int i = 0; i < attrs.length; i++) { + try { + result.add(new Attribute(attrs[i], getAttribute(attrs[i]))); + } catch (AttributeNotFoundException e) { + // ignore, as we cannot throw this exception + } catch (MBeanException e) { + // ignore, as we cannot throw this exception + } catch (ReflectionException e) { + // ignore, as we cannot throw this exception + } + } + return result; + } + + /** + * Loops over all attributes and calls + * {@link DynamicMBean#setAttribute(Attribute)} for each attribute + * sequentially. Any exception thrown by those methods are ignored and + * simply cause the attribute not being added to the result. + */ + public AttributeList setAttributes(AttributeList attrs) { + final AttributeList result = new AttributeList(); + for (int i = 0; i < attrs.size(); i++) { + try { + final Attribute next = (Attribute) attrs.get(i); + setAttribute(next); + result.add(next); + } catch (AttributeNotFoundException e) { + // ignore, as we cannot throw this exception + } + } + return result; + } + + // ------- + // Implementation of the MBeanRegistration interface + // ------- + + /** + *

Returns new ObjectName(this.getObjectName()) to guarantee + * a reliable and reproducable object name.

+ * + *

Note: Make sure any subclass does a super call to this method, + * otherwise the implementation might be broken.

+ * + * @see MBeanRegistration#preRegister(MBeanServer, ObjectName) + */ + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + this.mbeanServer = server; + return new ObjectName(getObjectName()); + } + + /** + * Empty implementation, allowing subclasses to ignore the interface. + * + *

Note: Make sure any subclass does a super call to this method, + * otherwise the implementation might be broken.

+ * + * @see MBeanRegistration#postRegister(Boolean) + */ + public void postRegister(Boolean success) { + } + + /** + * Empty implementation, allowing subclasses to ignore the interface. + * + *

Note: Make sure any subclass does a super call to this method, + * otherwise the implementation might be broken.

+ * + * @see MBeanRegistration#preDeregister() + */ + public void preDeregister() throws Exception { + } + + /** + * Empty implementation, allowing subclasses to ignore the interface. + * + *

Note: Make sure any subclass does a super call to this method, + * otherwise the implementation might be broken.

+ * + * @see MBeanRegistration#postDeregister() + */ + public void postDeregister() { + this.mbeanServer = null; + } + + public void setAttribute(Attribute attr) throws AttributeNotFoundException { + throw new AttributeNotFoundException(attr.getName()); + } + + public Object invoke(String name, Object[] params, String[] signature) + throws ReflectionException { + + throw new ReflectionException(new NoSuchMethodException(name), + name); + } +} diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java index 8cf920f4..a1808571 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java @@ -1,263 +1,263 @@ -/* - * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. - * This file is part of SIGAR. - * - * SIGAR is free software; you can redistribute it and/or modify - * it under the terms version 2 of the GNU General Public License as - * published by the Free Software Foundation. This program 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 for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -package org.hyperic.sigar.jmx; - -import javax.management.Attribute; -import javax.management.AttributeNotFoundException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanConstructorInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanParameterInfo; -import javax.management.ReflectionException; - -import org.hyperic.sigar.Sigar; -import org.hyperic.sigar.SigarException; -import org.hyperic.sigar.SigarNotImplementedException; - -/** - * Sigar JMX MBean implementation for the LoadAverage information - * package. Provides an OpenMBean conform implementation. - * - * @author Bjoern Martin - * @since 1.5 - */ -public class SigarLoadAverage extends AbstractMBean { - - private static final String MBEAN_TYPE = "LoadAverage"; - - /** - * Returned if {@link Sigar#getLoadAverage()}} is detected to be not - * implemented on the platform. - * - * @see #notImplemented - */ - private static final double NOT_IMPLEMENTED_LOAD_VALUE = -1.0d; - - private static final MBeanInfo MBEAN_INFO; - - private static final MBeanAttributeInfo MBEAN_ATTR_LAST1MIN; - - private static final MBeanAttributeInfo MBEAN_ATTR_LAST5MIN; - - private static final MBeanAttributeInfo MBEAN_ATTR_LAST15MIN; - - private static final MBeanConstructorInfo MBEAN_CONSTR_SIGAR; - - private static MBeanParameterInfo MBEAN_PARAM_SIGAR; - - static { - MBEAN_ATTR_LAST1MIN = new MBeanAttributeInfo( - "LastMinute", - "double", - "The load average in the last minute, as a fraction of 1, or " - + "-1.0 if the load cannot be determined on this platform", - true, false, false); - MBEAN_ATTR_LAST5MIN = new MBeanAttributeInfo( - "LastFiveMinutes", - "double", - "The load average over the last five minutes, as a fraction " - + "of 1, or -1.0 if the load cannot be determined on this platform", - true, false, false); - MBEAN_ATTR_LAST15MIN = new MBeanAttributeInfo( - "Last15Minutes", - "double", - "The load average over the last 15 minutes, as a fraction of " - + "1, or -1.0 if the load cannot be determined on this platform", - true, false, false); - - MBEAN_PARAM_SIGAR = new MBeanParameterInfo("sigar", Sigar.class - .getName(), "The Sigar instance to use to fetch data from"); - - MBEAN_CONSTR_SIGAR = new MBeanConstructorInfo( - SigarLoadAverage.class.getName(), - "Creates a new instance, using the Sigar instance specified " - + "to fetch the data. Fails if the CPU index is out of range.", - new MBeanParameterInfo[] { MBEAN_PARAM_SIGAR }); - MBEAN_INFO = new MBeanInfo( - SigarLoadAverage.class.getName(), - "Sigar load average MBean. Provides load averages of the " - + "system over the last one, five and 15 minutes. Due to the " - + "long term character of that information, the fetch is done " - + "using a Sigar proxy cache with a timeout of 30 seconds.", - new MBeanAttributeInfo[] { MBEAN_ATTR_LAST1MIN, - MBEAN_ATTR_LAST5MIN, MBEAN_ATTR_LAST15MIN }, - new MBeanConstructorInfo[] { MBEAN_CONSTR_SIGAR }, null, null); - - } - - /** - * Object name this instance will give itself when being registered to an - * MBeanServer. - */ - private final String objectName; - - /** - *

Set true when the load average fetch failed with a - * SigarException that indicates the method is not implemented. - * Any subsequent call to this instance will then be answered with - * {@link #NOT_IMPLEMENTED_LOAD_VALUE}. - *

- * - *

FIXME : This is a workaround and should be replaced by something - * more stable, as the code setting this member true relies on - * a substring being present within the exception. A proposal was made at - * issue SIGAR-52. - *

- */ - private boolean notImplemented; - - /** - * Creates a new instance, using a new Sigar instance to fetch the data. - * - * @throws IllegalArgumentException - * If an unexpected Sigar error occurs. - */ - public SigarLoadAverage() throws IllegalArgumentException { - this(new Sigar()); - } - - /** - * Creates a new instance, using the Sigar instance specified to fetch the - * data. - * - * @param sigar - * The Sigar instance to use to fetch data from - * - * @throws IllegalArgumentException - * If an unexpected Sigar error occurs - */ - public SigarLoadAverage(Sigar sigar) throws IllegalArgumentException { - super(sigar, CACHED_30SEC); - - // all fine - this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE - + "=" + MBEAN_TYPE; - } - - /** - * Object name this instance will give itself when being registered to an - * MBeanServer. - */ - public String getObjectName() { - return this.objectName; - } - - /** - * @return The load average in the last minute, as a fraction of 1, or - * -1.0d if the load cannot be determined on this platform - */ - public double getLastMinute() { - try { - return sigarImpl.getLoadAverage()[0]; - - } catch (SigarNotImplementedException e) { - return NOT_IMPLEMENTED_LOAD_VALUE; - - } catch (SigarException e) { - throw unexpectedError(MBEAN_TYPE, e); - } - } - - /** - * @return The load average over the last five minutes, as a fraction of 1, - * or -1.0d if the load cannot be determined on this - * platform - */ - public double getLastFiveMinutes() { - try { - return sigarImpl.getLoadAverage()[1]; - - } catch (SigarNotImplementedException e) { - return NOT_IMPLEMENTED_LOAD_VALUE; - - } catch (SigarException e) { - throw unexpectedError(MBEAN_TYPE, e); - } - } - - /** - * @return The load average over the last 15 minutes, as a fraction of 1, or - * -1.0d if the load cannot be determined on this platform - */ - public double getLast15Minutes() { - try { - return sigarImpl.getLoadAverage()[2]; - - } catch (SigarNotImplementedException e) { - return NOT_IMPLEMENTED_LOAD_VALUE; - - } catch (SigarException e) { - throw unexpectedError(MBEAN_TYPE, e); - } - } - - // ------- - // Implementation of the DynamicMBean interface - // ------- - - /* - * (non-Javadoc) - * - * @see DynamicMBean#getAttribute(String) - */ - public Object getAttribute(String attr) throws AttributeNotFoundException { - - if (MBEAN_ATTR_LAST1MIN.getName().equals(attr)) { - return new Double(getLastMinute()); - - } else if (MBEAN_ATTR_LAST5MIN.getName().equals(attr)) { - return new Double(getLastFiveMinutes()); - - } else if (MBEAN_ATTR_LAST15MIN.getName().equals(attr)) { - return new Double(getLast15Minutes()); - - } else { - throw new AttributeNotFoundException(attr); - } - } - - /* - * (non-Javadoc) - * - * @see DynamicMBean#setAttribute(Attribute) - */ - public void setAttribute(Attribute attr) throws AttributeNotFoundException { - throw new AttributeNotFoundException(attr.getName()); - } - - /* - * (non-Javadoc) - * - * @see DynamicMBean#invoke(String, Object[], String[]) - */ - public Object invoke(String actionName, Object[] params, String[] signature) - throws ReflectionException { - throw new ReflectionException(new NoSuchMethodException(actionName), - actionName); - } - - /* - * (non-Javadoc) - * - * @see DynamicMBean#getMBeanInfo() - */ - public MBeanInfo getMBeanInfo() { - return MBEAN_INFO; - } -} +/* + * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. + * This file is part of SIGAR. + * + * SIGAR is free software; you can redistribute it and/or modify + * it under the terms version 2 of the GNU General Public License as + * published by the Free Software Foundation. This program 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 for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package org.hyperic.sigar.jmx; + +import javax.management.Attribute; +import javax.management.AttributeNotFoundException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanParameterInfo; +import javax.management.ReflectionException; + +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.SigarNotImplementedException; + +/** + * Sigar JMX MBean implementation for the LoadAverage information + * package. Provides an OpenMBean conform implementation. + * + * @author Bjoern Martin + * @since 1.5 + */ +public class SigarLoadAverage extends AbstractMBean { + + private static final String MBEAN_TYPE = "LoadAverage"; + + /** + * Returned if {@link Sigar#getLoadAverage()}} is detected to be not + * implemented on the platform. + * + * @see #notImplemented + */ + private static final double NOT_IMPLEMENTED_LOAD_VALUE = -1.0d; + + private static final MBeanInfo MBEAN_INFO; + + private static final MBeanAttributeInfo MBEAN_ATTR_LAST1MIN; + + private static final MBeanAttributeInfo MBEAN_ATTR_LAST5MIN; + + private static final MBeanAttributeInfo MBEAN_ATTR_LAST15MIN; + + private static final MBeanConstructorInfo MBEAN_CONSTR_SIGAR; + + private static MBeanParameterInfo MBEAN_PARAM_SIGAR; + + static { + MBEAN_ATTR_LAST1MIN = new MBeanAttributeInfo( + "LastMinute", + "double", + "The load average in the last minute, as a fraction of 1, or " + + "-1.0 if the load cannot be determined on this platform", + true, false, false); + MBEAN_ATTR_LAST5MIN = new MBeanAttributeInfo( + "LastFiveMinutes", + "double", + "The load average over the last five minutes, as a fraction " + + "of 1, or -1.0 if the load cannot be determined on this platform", + true, false, false); + MBEAN_ATTR_LAST15MIN = new MBeanAttributeInfo( + "Last15Minutes", + "double", + "The load average over the last 15 minutes, as a fraction of " + + "1, or -1.0 if the load cannot be determined on this platform", + true, false, false); + + MBEAN_PARAM_SIGAR = new MBeanParameterInfo("sigar", Sigar.class + .getName(), "The Sigar instance to use to fetch data from"); + + MBEAN_CONSTR_SIGAR = new MBeanConstructorInfo( + SigarLoadAverage.class.getName(), + "Creates a new instance, using the Sigar instance specified " + + "to fetch the data. Fails if the CPU index is out of range.", + new MBeanParameterInfo[] { MBEAN_PARAM_SIGAR }); + MBEAN_INFO = new MBeanInfo( + SigarLoadAverage.class.getName(), + "Sigar load average MBean. Provides load averages of the " + + "system over the last one, five and 15 minutes. Due to the " + + "long term character of that information, the fetch is done " + + "using a Sigar proxy cache with a timeout of 30 seconds.", + new MBeanAttributeInfo[] { MBEAN_ATTR_LAST1MIN, + MBEAN_ATTR_LAST5MIN, MBEAN_ATTR_LAST15MIN }, + new MBeanConstructorInfo[] { MBEAN_CONSTR_SIGAR }, null, null); + + } + + /** + * Object name this instance will give itself when being registered to an + * MBeanServer. + */ + private final String objectName; + + /** + *

Set true when the load average fetch failed with a + * SigarException that indicates the method is not implemented. + * Any subsequent call to this instance will then be answered with + * {@link #NOT_IMPLEMENTED_LOAD_VALUE}. + *

+ * + *

FIXME : This is a workaround and should be replaced by something + * more stable, as the code setting this member true relies on + * a substring being present within the exception. A proposal was made at + * issue SIGAR-52. + *

+ */ + private boolean notImplemented; + + /** + * Creates a new instance, using a new Sigar instance to fetch the data. + * + * @throws IllegalArgumentException + * If an unexpected Sigar error occurs. + */ + public SigarLoadAverage() throws IllegalArgumentException { + this(new Sigar()); + } + + /** + * Creates a new instance, using the Sigar instance specified to fetch the + * data. + * + * @param sigar + * The Sigar instance to use to fetch data from + * + * @throws IllegalArgumentException + * If an unexpected Sigar error occurs + */ + public SigarLoadAverage(Sigar sigar) throws IllegalArgumentException { + super(sigar, CACHED_30SEC); + + // all fine + this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE + + "=" + MBEAN_TYPE; + } + + /** + * Object name this instance will give itself when being registered to an + * MBeanServer. + */ + public String getObjectName() { + return this.objectName; + } + + /** + * @return The load average in the last minute, as a fraction of 1, or + * -1.0d if the load cannot be determined on this platform + */ + public double getLastMinute() { + try { + return sigarImpl.getLoadAverage()[0]; + + } catch (SigarNotImplementedException e) { + return NOT_IMPLEMENTED_LOAD_VALUE; + + } catch (SigarException e) { + throw unexpectedError(MBEAN_TYPE, e); + } + } + + /** + * @return The load average over the last five minutes, as a fraction of 1, + * or -1.0d if the load cannot be determined on this + * platform + */ + public double getLastFiveMinutes() { + try { + return sigarImpl.getLoadAverage()[1]; + + } catch (SigarNotImplementedException e) { + return NOT_IMPLEMENTED_LOAD_VALUE; + + } catch (SigarException e) { + throw unexpectedError(MBEAN_TYPE, e); + } + } + + /** + * @return The load average over the last 15 minutes, as a fraction of 1, or + * -1.0d if the load cannot be determined on this platform + */ + public double getLast15Minutes() { + try { + return sigarImpl.getLoadAverage()[2]; + + } catch (SigarNotImplementedException e) { + return NOT_IMPLEMENTED_LOAD_VALUE; + + } catch (SigarException e) { + throw unexpectedError(MBEAN_TYPE, e); + } + } + + // ------- + // Implementation of the DynamicMBean interface + // ------- + + /* + * (non-Javadoc) + * + * @see DynamicMBean#getAttribute(String) + */ + public Object getAttribute(String attr) throws AttributeNotFoundException { + + if (MBEAN_ATTR_LAST1MIN.getName().equals(attr)) { + return new Double(getLastMinute()); + + } else if (MBEAN_ATTR_LAST5MIN.getName().equals(attr)) { + return new Double(getLastFiveMinutes()); + + } else if (MBEAN_ATTR_LAST15MIN.getName().equals(attr)) { + return new Double(getLast15Minutes()); + + } else { + throw new AttributeNotFoundException(attr); + } + } + + /* + * (non-Javadoc) + * + * @see DynamicMBean#setAttribute(Attribute) + */ + public void setAttribute(Attribute attr) throws AttributeNotFoundException { + throw new AttributeNotFoundException(attr.getName()); + } + + /* + * (non-Javadoc) + * + * @see DynamicMBean#invoke(String, Object[], String[]) + */ + public Object invoke(String actionName, Object[] params, String[] signature) + throws ReflectionException { + throw new ReflectionException(new NoSuchMethodException(actionName), + actionName); + } + + /* + * (non-Javadoc) + * + * @see DynamicMBean#getMBeanInfo() + */ + public MBeanInfo getMBeanInfo() { + return MBEAN_INFO; + } +} diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index 78a157fd..ac31af0e 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -1,334 +1,334 @@ -/* - * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. - * This file is part of SIGAR. - * - * SIGAR is free software; you can redistribute it and/or modify - * it under the terms version 2 of the GNU General Public License as - * published by the Free Software Foundation. This program 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 for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -package org.hyperic.sigar.jmx; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.management.AttributeNotFoundException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanConstructorInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanParameterInfo; -import javax.management.MBeanServer; -import javax.management.ObjectInstance; -import javax.management.ObjectName; - -import org.hyperic.sigar.CpuInfo; -import org.hyperic.sigar.FileSystem; -import org.hyperic.sigar.NetInterfaceConfig; -import org.hyperic.sigar.Sigar; -import org.hyperic.sigar.SigarException; -import org.hyperic.sigar.SigarLoader; - -/** - *

Registry of all Sigar MBeans. Can be used as a convenient way to invoke - * Sigar MBeans at a central point. This brings a bunch of advantages with - * it:

- * - * - * - *

So using this class to manage the Sigar MBeans requires one line of code - * for creation, registration and MBean spawning, and one line of code to shut - * it all down again.

- * - * @author Bjoern Martin - * @since 1.5 - */ -public class SigarRegistry extends AbstractMBean { - - private static final String MBEAN_TYPE = "SigarRegistry"; - - private static final Map VERSION_ATTRS = new LinkedHashMap(); - - private static final MBeanInfo MBEAN_INFO; - - private static final MBeanConstructorInfo MBEAN_CONSTR_DEFAULT; - -// private static final MBeanOperationInfo MBEAN_OPER_LISTPROCESSES; - - static { - MBEAN_CONSTR_DEFAULT = new MBeanConstructorInfo( - SigarRegistry.class.getName(), - "Creates a new instance of this class. Will create the Sigar " - + "instance this class uses when constructing other MBeans", - new MBeanParameterInfo[0]); -// MBEAN_OPER_LISTPROCESSES = new MBeanOperationInfo("listProcesses", -// "Executes a query returning the process IDs of all processes " + -// "found on the system.", -// null /* new MBeanParameterInfo[0] */, -// String.class.getName(), MBeanOperationInfo.INFO); - - MBEAN_INFO = new MBeanInfo( - SigarRegistry.class.getName(), - "Sigar MBean registry. Provides a central point for creation " - + "and destruction of Sigar MBeans. Any Sigar MBean created via " - + "this instance will automatically be cleaned up when this " - + "instance is deregistered from the MBean server.", - getAttributeInfo(), - new MBeanConstructorInfo[] { MBEAN_CONSTR_DEFAULT }, - null /*new MBeanOperationInfo[0] */, - null /*new MBeanNotificationInfo[0]*/); - } - - private final String objectName; - - private final ArrayList managedBeans; - - private static MBeanAttributeInfo[] getAttributeInfo() { - VERSION_ATTRS.put("JarVersion", Sigar.VERSION_STRING); - VERSION_ATTRS.put("NativeVersion", Sigar.NATIVE_VERSION_STRING); - VERSION_ATTRS.put("JarBuildDate", Sigar.BUILD_DATE); - VERSION_ATTRS.put("NativeBuildDate", Sigar.NATIVE_BUILD_DATE); - VERSION_ATTRS.put("JarSourceRevision", Sigar.SCM_REVISION); - VERSION_ATTRS.put("NativeSourceRevision", Sigar.NATIVE_SCM_REVISION); - VERSION_ATTRS.put("NativeLibraryName", SigarLoader.getNativeLibraryName()); - - MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[VERSION_ATTRS.size()]; - int i=0; - for (Iterator it=VERSION_ATTRS.entrySet().iterator(); - it.hasNext();) - { - Map.Entry entry = (Map.Entry)it.next(); - String name = (String)entry.getKey(); - attrs[i++] = - new MBeanAttributeInfo(name, - entry.getValue().getClass().getName(), - name, - true, // isReadable - false, // isWritable - false); // isIs - } - return attrs; - } - - /** - * Creates a new instance of this class. Will create the Sigar instance this - * class uses when constructing other MBeans. - */ - public SigarRegistry() { - super(new Sigar(), CACHELESS); - this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE - + "=" + MBEAN_TYPE; - this.managedBeans = new ArrayList(); - } - - /* (non-Javadoc) - * @see AbstractMBean#getObjectName() - */ - public String getObjectName() { - return this.objectName; - } - -/* public String listProcesses() { - try { - final long start = System.currentTimeMillis(); - long[] ids = sigar.getProcList(); - StringBuffer procNames = new StringBuffer(); - for (int i = 0; i < ids.length; i++) { - try { - procNames.append(ids[i] + ":" + sigar.getProcExe(ids[i]).getName()).append('\n'); - } catch (SigarException e) { - procNames.append(ids[i] + ":" + e.getMessage()).append('\n'); - } - } - - final long end = System.currentTimeMillis(); - procNames.append("-- Took " + (end-start) + "ms"); - return procNames.toString(); - - } catch (SigarException e) { - throw unexpectedError("ProcList", e); - } - } -*/ - /* (non-Javadoc) - * @see javax.management.DynamicMBean#getAttribute(java.lang.String) - */ - public Object getAttribute(String attr) throws AttributeNotFoundException { - Object obj = VERSION_ATTRS.get(attr); - if (obj == null) { - throw new AttributeNotFoundException(attr); - } - return obj; - } - - /* (non-Javadoc) - * @see javax.management.DynamicMBean#getMBeanInfo() - */ - public MBeanInfo getMBeanInfo() { - return MBEAN_INFO; - } - - private void registerMBean(AbstractMBean mbean) { - try { - ObjectName name = - new ObjectName(mbean.getObjectName()); - if (mbeanServer.isRegistered(name)) { - return; - } - ObjectInstance instance = - this.mbeanServer.registerMBean(mbean, name); - this.managedBeans.add(instance.getObjectName()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - // ------- - // Implementation of the MBeanRegistration interface - // ------- - - /** - * Registers the default set of Sigar MBeans. Before doing so, a super call - * is made to satisfy {@link AbstractMBean}. - * - * @see AbstractMBean#postRegister(Boolean) - */ - public void postRegister(Boolean success) { - ReflectedMBean mbean; - - super.postRegister(success); - - if (!success.booleanValue()) - return; - - //CPU beans - CpuInfo[] info; - try { - info = sigar.getCpuInfoList(); - } catch (SigarException e) { - throw unexpectedError("CpuInfoList", e); - } - - for (int i=0; i= 0; i--) { - ObjectName next = (ObjectName) managedBeans.remove(i); - if (mbeanServer.isRegistered(next)) { - try { - mbeanServer.unregisterMBean(next); - } catch (Exception e) { // ignore - } - } - } - - // do the super call - super.preDeregister(); - } -} +/* + * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. + * This file is part of SIGAR. + * + * SIGAR is free software; you can redistribute it and/or modify + * it under the terms version 2 of the GNU General Public License as + * published by the Free Software Foundation. This program 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 for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package org.hyperic.sigar.jmx; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.management.AttributeNotFoundException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanParameterInfo; +import javax.management.MBeanServer; +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +import org.hyperic.sigar.CpuInfo; +import org.hyperic.sigar.FileSystem; +import org.hyperic.sigar.NetInterfaceConfig; +import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.SigarLoader; + +/** + *

Registry of all Sigar MBeans. Can be used as a convenient way to invoke + * Sigar MBeans at a central point. This brings a bunch of advantages with + * it:

+ * + * + * + *

So using this class to manage the Sigar MBeans requires one line of code + * for creation, registration and MBean spawning, and one line of code to shut + * it all down again.

+ * + * @author Bjoern Martin + * @since 1.5 + */ +public class SigarRegistry extends AbstractMBean { + + private static final String MBEAN_TYPE = "SigarRegistry"; + + private static final Map VERSION_ATTRS = new LinkedHashMap(); + + private static final MBeanInfo MBEAN_INFO; + + private static final MBeanConstructorInfo MBEAN_CONSTR_DEFAULT; + +// private static final MBeanOperationInfo MBEAN_OPER_LISTPROCESSES; + + static { + MBEAN_CONSTR_DEFAULT = new MBeanConstructorInfo( + SigarRegistry.class.getName(), + "Creates a new instance of this class. Will create the Sigar " + + "instance this class uses when constructing other MBeans", + new MBeanParameterInfo[0]); +// MBEAN_OPER_LISTPROCESSES = new MBeanOperationInfo("listProcesses", +// "Executes a query returning the process IDs of all processes " + +// "found on the system.", +// null /* new MBeanParameterInfo[0] */, +// String.class.getName(), MBeanOperationInfo.INFO); + + MBEAN_INFO = new MBeanInfo( + SigarRegistry.class.getName(), + "Sigar MBean registry. Provides a central point for creation " + + "and destruction of Sigar MBeans. Any Sigar MBean created via " + + "this instance will automatically be cleaned up when this " + + "instance is deregistered from the MBean server.", + getAttributeInfo(), + new MBeanConstructorInfo[] { MBEAN_CONSTR_DEFAULT }, + null /*new MBeanOperationInfo[0] */, + null /*new MBeanNotificationInfo[0]*/); + } + + private final String objectName; + + private final ArrayList managedBeans; + + private static MBeanAttributeInfo[] getAttributeInfo() { + VERSION_ATTRS.put("JarVersion", Sigar.VERSION_STRING); + VERSION_ATTRS.put("NativeVersion", Sigar.NATIVE_VERSION_STRING); + VERSION_ATTRS.put("JarBuildDate", Sigar.BUILD_DATE); + VERSION_ATTRS.put("NativeBuildDate", Sigar.NATIVE_BUILD_DATE); + VERSION_ATTRS.put("JarSourceRevision", Sigar.SCM_REVISION); + VERSION_ATTRS.put("NativeSourceRevision", Sigar.NATIVE_SCM_REVISION); + VERSION_ATTRS.put("NativeLibraryName", SigarLoader.getNativeLibraryName()); + + MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[VERSION_ATTRS.size()]; + int i=0; + for (Iterator it=VERSION_ATTRS.entrySet().iterator(); + it.hasNext();) + { + Map.Entry entry = (Map.Entry)it.next(); + String name = (String)entry.getKey(); + attrs[i++] = + new MBeanAttributeInfo(name, + entry.getValue().getClass().getName(), + name, + true, // isReadable + false, // isWritable + false); // isIs + } + return attrs; + } + + /** + * Creates a new instance of this class. Will create the Sigar instance this + * class uses when constructing other MBeans. + */ + public SigarRegistry() { + super(new Sigar(), CACHELESS); + this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE + + "=" + MBEAN_TYPE; + this.managedBeans = new ArrayList(); + } + + /* (non-Javadoc) + * @see AbstractMBean#getObjectName() + */ + public String getObjectName() { + return this.objectName; + } + +/* public String listProcesses() { + try { + final long start = System.currentTimeMillis(); + long[] ids = sigar.getProcList(); + StringBuffer procNames = new StringBuffer(); + for (int i = 0; i < ids.length; i++) { + try { + procNames.append(ids[i] + ":" + sigar.getProcExe(ids[i]).getName()).append('\n'); + } catch (SigarException e) { + procNames.append(ids[i] + ":" + e.getMessage()).append('\n'); + } + } + + final long end = System.currentTimeMillis(); + procNames.append("-- Took " + (end-start) + "ms"); + return procNames.toString(); + + } catch (SigarException e) { + throw unexpectedError("ProcList", e); + } + } +*/ + /* (non-Javadoc) + * @see javax.management.DynamicMBean#getAttribute(java.lang.String) + */ + public Object getAttribute(String attr) throws AttributeNotFoundException { + Object obj = VERSION_ATTRS.get(attr); + if (obj == null) { + throw new AttributeNotFoundException(attr); + } + return obj; + } + + /* (non-Javadoc) + * @see javax.management.DynamicMBean#getMBeanInfo() + */ + public MBeanInfo getMBeanInfo() { + return MBEAN_INFO; + } + + private void registerMBean(AbstractMBean mbean) { + try { + ObjectName name = + new ObjectName(mbean.getObjectName()); + if (mbeanServer.isRegistered(name)) { + return; + } + ObjectInstance instance = + this.mbeanServer.registerMBean(mbean, name); + this.managedBeans.add(instance.getObjectName()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // ------- + // Implementation of the MBeanRegistration interface + // ------- + + /** + * Registers the default set of Sigar MBeans. Before doing so, a super call + * is made to satisfy {@link AbstractMBean}. + * + * @see AbstractMBean#postRegister(Boolean) + */ + public void postRegister(Boolean success) { + ReflectedMBean mbean; + + super.postRegister(success); + + if (!success.booleanValue()) + return; + + //CPU beans + CpuInfo[] info; + try { + info = sigar.getCpuInfoList(); + } catch (SigarException e) { + throw unexpectedError("CpuInfoList", e); + } + + for (int i=0; i= 0; i--) { + ObjectName next = (ObjectName) managedBeans.remove(i); + if (mbeanServer.isRegistered(next)) { + try { + mbeanServer.unregisterMBean(next); + } catch (Exception e) { // ignore + } + } + } + + // do the super call + super.preDeregister(); + } +}