From b9caed41574b898c6f31876374e0ea9ca9ff946b Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Sat, 25 Apr 2009 09:52:07 -0700 Subject: [PATCH 01/20] getrusage on NetBSD may not return monotonically increasing values for CPU time. See: http://archives.devshed.com/forums/bsd-93/kern-30115-getrusage-returns-bogus-ru-utime-values-220800.html --- src/os/darwin/darwin_sigar.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/os/darwin/darwin_sigar.c b/src/os/darwin/darwin_sigar.c index 182df5f0..c17e16c6 100644 --- a/src/os/darwin/darwin_sigar.c +++ b/src/os/darwin/darwin_sigar.c @@ -1905,7 +1905,7 @@ int sigar_thread_cpu_get(sigar_t *sigar, sigar_uint64_t id, sigar_thread_cpu_t *cpu) { -#ifdef DARWIN +#if defined(DARWIN) mach_port_t self = mach_thread_self(); thread_basic_info_data_t info; mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; @@ -1922,6 +1922,8 @@ int sigar_thread_cpu_get(sigar_t *sigar, cpu->user = tval2nsec(info.user_time); cpu->sys = tval2nsec(info.system_time); cpu->total = cpu->user + cpu->sys; +#elif defined(__NetBSD__) + return SIGAR_ENOTIMPL; /* http://tinyurl.com/chbvln */ #else /* XXX this is not per-thread, it is for the whole-process. * just want to use for the shell time command at the moment. From ec3fbe993c84015778a273a18a9c732f931f44e1 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 10:04:59 -0700 Subject: [PATCH 02/20] remove unused code --- .../org/hyperic/sigar/jmx/SigarRegistry.java | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index ac31af0e..5bab68d9 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -74,19 +74,12 @@ public class SigarRegistry extends AbstractMBean { 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(), @@ -149,28 +142,6 @@ public class SigarRegistry extends AbstractMBean { 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) */ From 3e0e08f0886f8867f1219a3637d35782987f5a3b Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 10:17:58 -0700 Subject: [PATCH 03/20] rename SigarVersion -> Version --- bindings/java/build.xml | 2 +- bindings/java/src/org/hyperic/sigar/Sigar.java | 6 +++--- .../hyperic/sigar/{SigarVersion.java.in => Version.java.in} | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename bindings/java/src/org/hyperic/sigar/{SigarVersion.java.in => Version.java.in} (90%) diff --git a/bindings/java/build.xml b/bindings/java/build.xml index 1493fb67..890ba1c7 100644 --- a/bindings/java/build.xml +++ b/bindings/java/build.xml @@ -184,7 +184,7 @@ + value="src/org/hyperic/sigar/Version.java"/> diff --git a/bindings/java/src/org/hyperic/sigar/Sigar.java b/bindings/java/src/org/hyperic/sigar/Sigar.java index b7037e37..c927bb15 100644 --- a/bindings/java/src/org/hyperic/sigar/Sigar.java +++ b/bindings/java/src/org/hyperic/sigar/Sigar.java @@ -48,7 +48,7 @@ public class Sigar implements SigarProxy { * The Sigar java version. */ public static final String VERSION_STRING = - SigarVersion.VERSION_STRING; + Version.VERSION_STRING; /** * The Sigar native version. @@ -59,7 +59,7 @@ public class Sigar implements SigarProxy { * The scm (svn) revision from which sigar.jar was built. */ public static final String SCM_REVISION = - SigarVersion.SCM_REVISION; + Version.SCM_REVISION; /** * The scm (svn) revision from which the sigar native binary was built. @@ -70,7 +70,7 @@ public class Sigar implements SigarProxy { * The date on which sigar.jar was built. */ public static final String BUILD_DATE = - SigarVersion.BUILD_DATE; + Version.BUILD_DATE; /** * The date on which the sigar native binary was built. diff --git a/bindings/java/src/org/hyperic/sigar/SigarVersion.java.in b/bindings/java/src/org/hyperic/sigar/Version.java.in similarity index 90% rename from bindings/java/src/org/hyperic/sigar/SigarVersion.java.in rename to bindings/java/src/org/hyperic/sigar/Version.java.in index de9ea078..630bf60f 100644 --- a/bindings/java/src/org/hyperic/sigar/SigarVersion.java.in +++ b/bindings/java/src/org/hyperic/sigar/Version.java.in @@ -1,6 +1,6 @@ package org.hyperic.sigar; -class SigarVersion { +class Version { static final String BUILD_DATE = "@@BUILD_DATE@@"; From a84788f1a0736b73eba0a7ad862bbfd2963fbe3c Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 10:51:32 -0700 Subject: [PATCH 04/20] encapsulate version attributes --- .../src/org/hyperic/sigar/SigarVersion.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 bindings/java/src/org/hyperic/sigar/SigarVersion.java diff --git a/bindings/java/src/org/hyperic/sigar/SigarVersion.java b/bindings/java/src/org/hyperic/sigar/SigarVersion.java new file mode 100644 index 00000000..d861573d --- /dev/null +++ b/bindings/java/src/org/hyperic/sigar/SigarVersion.java @@ -0,0 +1,53 @@ +package org.hyperic.sigar; + +public class SigarVersion { + + /** + * @return Version number of the Java sigar.jar library + */ + public String getJarVersion() { + return Sigar.VERSION_STRING; + } + + /** + * @return Version number of the native sigar library + */ + public String getNativeVersion() { + return Sigar.NATIVE_VERSION_STRING; + } + + /** + * @return Build date of the Java sigar.jar library + */ + public String getJarBuildDate() { + return Sigar.BUILD_DATE; + } + + /** + * @return Build date of the native sigar library + */ + public String getNativeBuildDate() { + return Sigar.NATIVE_BUILD_DATE; + } + + /** + * @return Source code revision of the Java sigar.jar library + */ + public String getJarSourceRevision() { + return Sigar.SCM_REVISION; + } + + /** + * @return Source code revision of the native sigar library + */ + public String getNativeSourceRevision() { + return Sigar.NATIVE_SCM_REVISION; + } + + /** + * @return Name of the loaded native sigar library file + */ + public String getNativeLibraryName() { + return SigarLoader.getNativeLibraryName(); + } +} From 96ca3970e1d7506715f46eacb9ef5b330ead7182 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 10:51:55 -0700 Subject: [PATCH 05/20] add SigarVersion getter --- bindings/java/src/org/hyperic/sigar/Sigar.java | 4 ++++ bindings/java/src/org/hyperic/sigar/SigarProxy.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/bindings/java/src/org/hyperic/sigar/Sigar.java b/bindings/java/src/org/hyperic/sigar/Sigar.java index c927bb15..a83914d2 100644 --- a/bindings/java/src/org/hyperic/sigar/Sigar.java +++ b/bindings/java/src/org/hyperic/sigar/Sigar.java @@ -959,6 +959,10 @@ public class Sigar implements SigarProxy { */ public native String getFQDN() throws SigarException; + public SigarVersion getSigarVersion() { + return new SigarVersion(); + } + /** * Enabling logging in the native Sigar code. * This method will hook log4j into the Sigar diff --git a/bindings/java/src/org/hyperic/sigar/SigarProxy.java b/bindings/java/src/org/hyperic/sigar/SigarProxy.java index 5f4ea007..ae23a915 100644 --- a/bindings/java/src/org/hyperic/sigar/SigarProxy.java +++ b/bindings/java/src/org/hyperic/sigar/SigarProxy.java @@ -172,5 +172,7 @@ public interface SigarProxy { public NetInfo getNetInfo() throws SigarException; + public SigarVersion getSigarVersion(); + public String getFQDN() throws SigarException; } From 0a1a3de69fcee6f984f4553eeeff8de827bc0c05 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 10:53:07 -0700 Subject: [PATCH 06/20] use SigarVersion bean --- .../org/hyperic/sigar/jmx/SigarRegistry.java | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index 5bab68d9..ac04c0a7 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -19,12 +19,10 @@ 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; @@ -37,7 +35,6 @@ 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 @@ -87,7 +84,7 @@ public class SigarRegistry extends AbstractMBean { + "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(), + null /*new MBeanAttributeInfo[0] */, new MBeanConstructorInfo[] { MBEAN_CONSTR_DEFAULT }, null /*new MBeanOperationInfo[0] */, null /*new MBeanNotificationInfo[0]*/); @@ -97,33 +94,6 @@ public class SigarRegistry extends AbstractMBean { 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. @@ -277,6 +247,8 @@ public class SigarRegistry extends AbstractMBean { registerMBean(new SigarLoadAverage(sigarImpl)); //global process stats registerMBean(new ReflectedMBean(sigarImpl, "ProcStat")); + //sigar version + registerMBean(new ReflectedMBean(sigarImpl, "SigarVersion")); } /** From 6ef73dcbcb23712d12d3c43cba2338ae3dd6e321 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 10:56:14 -0700 Subject: [PATCH 07/20] use SigarVersion bean --- .../java/src/org/hyperic/sigar/jmx/SigarRegistry.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index ac04c0a7..eb26d986 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -19,8 +19,6 @@ package org.hyperic.sigar.jmx; import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.Map; import javax.management.AttributeNotFoundException; import javax.management.MBeanConstructorInfo; @@ -65,8 +63,6 @@ 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; @@ -116,11 +112,7 @@ public class SigarRegistry extends AbstractMBean { * @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; + throw new AttributeNotFoundException(attr); } /* (non-Javadoc) From 0eb3672642882a1aea333b7f4b1a223caf13df1e Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 12:19:40 -0700 Subject: [PATCH 08/20] add mx -jconsole option --- .../java/src/org/hyperic/sigar/cmd/Mx.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java index 554fddf9..642464ae 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java @@ -79,18 +79,38 @@ public class Mx extends SigarCommandBase { } } + private void jconsole() { + String pid = String.valueOf(this.sigar.getPid()); + String[] argv = { "jconsole", pid }; + println("exec(jconsole, " + pid + ")"); + try { + Process p = Runtime.getRuntime().exec(argv); + p.waitFor(); + println("jconsole exited"); + } catch (Exception e) { + println(e.getMessage()); + } + } + public void output(String[] args) throws SigarException { MBeanServer server = getMBeanServer(); register(server); - boolean hasQuery = args.length != 0; - try { - String query; - if (hasQuery) { - query = args[0]; + boolean hasQuery = false; + boolean launchJconsole = false; + String query = "sigar:*"; + + for (int i=0; i Date: Wed, 29 Apr 2009 12:58:45 -0700 Subject: [PATCH 09/20] leave SigarProxy impl to the caller --- .../java/src/org/hyperic/sigar/cmd/Mx.java | 2 +- .../org/hyperic/sigar/jmx/AbstractMBean.java | 72 ++----------------- .../org/hyperic/sigar/jmx/ReflectedMBean.java | 8 +-- .../hyperic/sigar/jmx/SigarLoadAverage.java | 21 ++---- .../org/hyperic/sigar/jmx/SigarRegistry.java | 41 +++++------ .../src/org/hyperic/sigar/test/TestMx.java | 4 +- 6 files changed, 37 insertions(+), 111 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java index 642464ae..07ce94e4 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java @@ -68,7 +68,7 @@ public class Mx extends SigarCommandBase { if (isRegistered) { return; } - SigarRegistry registry = new SigarRegistry(); + SigarRegistry registry = new SigarRegistry(this.proxy); try { server.registerMBean(registry, null); SigarProcess proc = new SigarProcess(); diff --git a/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java b/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java index f7b0db10..fd38b172 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java @@ -31,7 +31,6 @@ 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 @@ -49,21 +48,6 @@ 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 @@ -85,59 +69,13 @@ public abstract class AbstractMBean implements DynamicMBean, MBeanRegistration { 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.

+ *

Creates a new instance of this class. The SigarProxy instance is stored (and + * accessible) via the {@link #sigar} member. * - *

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. + * @param sigar The SigarProxy instance to use. Must not be null */ - 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); - } + protected AbstractMBean(SigarProxy sigar) { + this.sigar = sigar; } /** diff --git a/bindings/java/src/org/hyperic/sigar/jmx/ReflectedMBean.java b/bindings/java/src/org/hyperic/sigar/jmx/ReflectedMBean.java index bb62b1ab..162f4930 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/ReflectedMBean.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/ReflectedMBean.java @@ -29,7 +29,7 @@ import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.ReflectionException; -import org.hyperic.sigar.Sigar; +import org.hyperic.sigar.SigarProxy; public class ReflectedMBean extends AbstractMBean { @@ -96,15 +96,15 @@ public class ReflectedMBean extends AbstractMBean { } } - protected ReflectedMBean(Sigar sigar, String type) { - super(sigar, CACHED_5SEC); + protected ReflectedMBean(SigarProxy sigar, String type) { + super(sigar); this.type = type; this.name = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE + "=" + getType(); } - protected ReflectedMBean(Sigar sigar, String type, String arg) { + protected ReflectedMBean(SigarProxy sigar, String type, String arg) { this(sigar, type); this.name += ",Name=" + encode(arg); } diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java index a1808571..19962477 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java @@ -29,6 +29,7 @@ import javax.management.ReflectionException; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarNotImplementedException; +import org.hyperic.sigar.SigarProxy; /** * Sigar JMX MBean implementation for the LoadAverage information @@ -122,16 +123,6 @@ public class SigarLoadAverage extends AbstractMBean { */ 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. @@ -142,8 +133,8 @@ public class SigarLoadAverage extends AbstractMBean { * @throws IllegalArgumentException * If an unexpected Sigar error occurs */ - public SigarLoadAverage(Sigar sigar) throws IllegalArgumentException { - super(sigar, CACHED_30SEC); + public SigarLoadAverage(SigarProxy sigar) throws IllegalArgumentException { + super(sigar); // all fine this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE @@ -164,7 +155,7 @@ public class SigarLoadAverage extends AbstractMBean { */ public double getLastMinute() { try { - return sigarImpl.getLoadAverage()[0]; + return this.sigar.getLoadAverage()[0]; } catch (SigarNotImplementedException e) { return NOT_IMPLEMENTED_LOAD_VALUE; @@ -181,7 +172,7 @@ public class SigarLoadAverage extends AbstractMBean { */ public double getLastFiveMinutes() { try { - return sigarImpl.getLoadAverage()[1]; + return this.sigar.getLoadAverage()[1]; } catch (SigarNotImplementedException e) { return NOT_IMPLEMENTED_LOAD_VALUE; @@ -197,7 +188,7 @@ public class SigarLoadAverage extends AbstractMBean { */ public double getLast15Minutes() { try { - return sigarImpl.getLoadAverage()[2]; + return this.sigar.getLoadAverage()[2]; } catch (SigarNotImplementedException e) { return NOT_IMPLEMENTED_LOAD_VALUE; diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index eb26d986..f055b0aa 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -33,6 +33,7 @@ import org.hyperic.sigar.FileSystem; import org.hyperic.sigar.NetInterfaceConfig; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; +import org.hyperic.sigar.SigarProxy; /** *

Registry of all Sigar MBeans. Can be used as a convenient way to invoke @@ -90,12 +91,8 @@ public class SigarRegistry extends AbstractMBean { private final ArrayList managedBeans; - /** - * 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); + public SigarRegistry(SigarProxy sigar) { + super(sigar); this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE + "=" + MBEAN_TYPE; this.managedBeans = new ArrayList(); @@ -166,26 +163,26 @@ public class SigarRegistry extends AbstractMBean { for (int i=0; i Date: Wed, 29 Apr 2009 13:09:15 -0700 Subject: [PATCH 10/20] make SigarProxyCached.invoke synchronized --- bindings/java/src/org/hyperic/sigar/SigarProxyCache.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/java/src/org/hyperic/sigar/SigarProxyCache.java b/bindings/java/src/org/hyperic/sigar/SigarProxyCache.java index fdefa219..9d8fc5fd 100644 --- a/bindings/java/src/org/hyperic/sigar/SigarProxyCache.java +++ b/bindings/java/src/org/hyperic/sigar/SigarProxyCache.java @@ -123,7 +123,7 @@ public class SigarProxyCache * The java.lang.reflect.InvocationHandler used by the Proxy. * This method handles caching of all Sigar type objects. */ - public Object invoke(Object proxy, Method method, Object[] args) + public synchronized Object invoke(Object proxy, Method method, Object[] args) throws SigarException, SigarNotImplementedException { SigarCacheObject cacheVal = null; From b3603f44891f88127995d4e6ae39d064b8473378 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 14:34:40 -0700 Subject: [PATCH 11/20] SigarProcess.close only applies to SigarProcess(void) constructor --- bindings/java/src/org/hyperic/sigar/cmd/Mx.java | 2 +- .../src/org/hyperic/sigar/jmx/SigarProcess.java | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java index 07ce94e4..0fb5271a 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java @@ -71,7 +71,7 @@ public class Mx extends SigarCommandBase { SigarRegistry registry = new SigarRegistry(this.proxy); try { server.registerMBean(registry, null); - SigarProcess proc = new SigarProcess(); + SigarProcess proc = new SigarProcess(this.sigar); server.registerMBean(proc, new ObjectName(proc.getObjectName())); isRegistered = true; } catch (Exception e) { diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java index 2690566d..1af9a22e 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarProcess.java @@ -40,16 +40,18 @@ public class SigarProcess implements SigarProcessMBean { private long pid = -1; public SigarProcess() { - this(new Sigar()); - } - - public SigarProcess(Sigar sigar) { - this.sigarImpl = sigar; + this.sigarImpl = new Sigar(); this.sigar = SigarProxyCache.newInstance(sigarImpl); } + public SigarProcess(SigarProxy sigar) { + this.sigar = sigar; + } + public void close() { - this.sigarImpl.close(); + if (this.sigarImpl != null) { + this.sigarImpl.close(); + } } private RuntimeException unexpectedError(String type, From ad8325e616f400131fee4279a658ad75953b6fe9 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 14:42:42 -0700 Subject: [PATCH 12/20] remove MBeanConstructorInfo --- .../src/org/hyperic/sigar/jmx/SigarRegistry.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index f055b0aa..b13d8274 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -21,9 +21,7 @@ package org.hyperic.sigar.jmx; import java.util.ArrayList; import javax.management.AttributeNotFoundException; -import javax.management.MBeanConstructorInfo; import javax.management.MBeanInfo; -import javax.management.MBeanParameterInfo; import javax.management.MBeanServer; import javax.management.ObjectInstance; import javax.management.ObjectName; @@ -31,7 +29,6 @@ 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.SigarProxy; @@ -66,15 +63,7 @@ public class SigarRegistry extends AbstractMBean { private static final MBeanInfo MBEAN_INFO; - private static final MBeanConstructorInfo MBEAN_CONSTR_DEFAULT; - 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_INFO = new MBeanInfo( SigarRegistry.class.getName(), "Sigar MBean registry. Provides a central point for creation " @@ -82,7 +71,7 @@ public class SigarRegistry extends AbstractMBean { + "this instance will automatically be cleaned up when this " + "instance is deregistered from the MBean server.", null /*new MBeanAttributeInfo[0] */, - new MBeanConstructorInfo[] { MBEAN_CONSTR_DEFAULT }, + null /*new MBeanConstructorInfo[0]*/, null /*new MBeanOperationInfo[0] */, null /*new MBeanNotificationInfo[0]*/); } From f6e85761d2378f1108d60ba09824a0bc033e07e6 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 14:55:47 -0700 Subject: [PATCH 13/20] SigarProxy must implement InvocationHandler --- .../java/src/org/hyperic/sigar/jmx/SigarInvokerJMX.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarInvokerJMX.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarInvokerJMX.java index 22675964..5b426151 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarInvokerJMX.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarInvokerJMX.java @@ -18,13 +18,16 @@ package org.hyperic.sigar.jmx; +import java.lang.reflect.InvocationHandler; import java.util.Map; import java.util.StringTokenizer; +import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarInvoker; import org.hyperic.sigar.SigarNotImplementedException; import org.hyperic.sigar.SigarProxy; +import org.hyperic.sigar.SigarProxyCache; import org.hyperic.sigar.util.ReferenceMap; /** @@ -61,6 +64,10 @@ public class SigarInvokerJMX extends SigarInvoker { SigarInvokerJMX invoker; + if (!(proxy instanceof InvocationHandler) && (proxy instanceof Sigar)) { + proxy = SigarProxyCache.newInstance((Sigar)proxy); + } + int ix = name.indexOf(":"); if (ix > 0) { //skip domain name From 25241fcc7afe0ce4b2fff4526f14fb9dd0b341b0 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 15:02:11 -0700 Subject: [PATCH 14/20] remove generated comments --- .../java/src/org/hyperic/sigar/jmx/SigarRegistry.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index b13d8274..80b08f63 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -87,23 +87,14 @@ public class SigarRegistry extends AbstractMBean { this.managedBeans = new ArrayList(); } - /* (non-Javadoc) - * @see AbstractMBean#getObjectName() - */ public String getObjectName() { return this.objectName; } - /* (non-Javadoc) - * @see javax.management.DynamicMBean#getAttribute(java.lang.String) - */ public Object getAttribute(String attr) throws AttributeNotFoundException { throw new AttributeNotFoundException(attr); } - /* (non-Javadoc) - * @see javax.management.DynamicMBean#getMBeanInfo() - */ public MBeanInfo getMBeanInfo() { return MBEAN_INFO; } From 448b595e30dcdad76a5bf80a9f93c5fea621f465 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 15:16:17 -0700 Subject: [PATCH 15/20] only SigarRegistry needs to implement MBeanRegistration --- .../org/hyperic/sigar/jmx/AbstractMBean.java | 67 +------------------ .../org/hyperic/sigar/jmx/SigarRegistry.java | 16 +++-- 2 files changed, 12 insertions(+), 71 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java b/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java index fd38b172..96d876af 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/AbstractMBean.java @@ -24,8 +24,6 @@ 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; @@ -43,7 +41,7 @@ import org.hyperic.sigar.SigarProxy; * @author Bjoern Martin * @since 1.5 */ -public abstract class AbstractMBean implements DynamicMBean, MBeanRegistration { +public abstract class AbstractMBean implements DynamicMBean { public static final String MBEAN_DOMAIN = SigarInvokerJMX.DOMAIN_NAME; public static final String MBEAN_ATTR_TYPE = SigarInvokerJMX.PROP_TYPE; @@ -58,16 +56,6 @@ public abstract class AbstractMBean implements DynamicMBean, MBeanRegistration { */ 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 SigarProxy instance is stored (and * accessible) via the {@link #sigar} member. @@ -145,59 +133,6 @@ public abstract class AbstractMBean implements DynamicMBean, MBeanRegistration { 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()); } diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index 80b08f63..e93927d9 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import javax.management.AttributeNotFoundException; import javax.management.MBeanInfo; +import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.ObjectInstance; import javax.management.ObjectName; @@ -57,7 +58,7 @@ import org.hyperic.sigar.SigarProxy; * @author Bjoern Martin * @since 1.5 */ -public class SigarRegistry extends AbstractMBean { +public class SigarRegistry extends AbstractMBean implements MBeanRegistration { private static final String MBEAN_TYPE = "SigarRegistry"; @@ -79,6 +80,7 @@ public class SigarRegistry extends AbstractMBean { private final String objectName; private final ArrayList managedBeans; + private MBeanServer mbeanServer; public SigarRegistry(SigarProxy sigar) { super(sigar); @@ -117,6 +119,11 @@ public class SigarRegistry extends AbstractMBean { // ------- // Implementation of the MBeanRegistration interface // ------- + public ObjectName preRegister(MBeanServer server, ObjectName name) + throws Exception { + this.mbeanServer = server; + return new ObjectName(getObjectName()); + } /** * Registers the default set of Sigar MBeans. Before doing so, a super call @@ -127,8 +134,6 @@ public class SigarRegistry extends AbstractMBean { public void postRegister(Boolean success) { ReflectedMBean mbean; - super.postRegister(success); - if (!success.booleanValue()) return; @@ -239,8 +244,9 @@ public class SigarRegistry extends AbstractMBean { } } } + } - // do the super call - super.preDeregister(); + public void postDeregister() { + this.mbeanServer = null; } } From b004072d487b957e0764cd362d25f9fadf11ad57 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 16:32:36 -0700 Subject: [PATCH 16/20] Object wrapper of double[] Sigar.getLoadAverage() for use in bean patterns (JMX) --- .../src/org/hyperic/sigar/LoadAverage.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 bindings/java/src/org/hyperic/sigar/LoadAverage.java diff --git a/bindings/java/src/org/hyperic/sigar/LoadAverage.java b/bindings/java/src/org/hyperic/sigar/LoadAverage.java new file mode 100644 index 00000000..9a39abc5 --- /dev/null +++ b/bindings/java/src/org/hyperic/sigar/LoadAverage.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) [2004-2009], 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; + +import java.util.HashMap; +import java.util.Map; + +/** + * Object wrapper of double[] Sigar.getLoadAverage() for use in bean patterns (JMX). + */ +public class LoadAverage { + + private double[] average; + + public LoadAverage(double[] average) { + this.average = average; + } + + public double getOneMinute() { + return this.average[0]; + } + + public double getFiveMinute() { + return this.average[1]; + } + + public double getFifteenMinute() { + return this.average[2]; + } + + public Map toMap() { + Map map = new HashMap(); + map.put("OneMinute", new Double(getOneMinute())); + map.put("FiveMinute", new Double(getFiveMinute())); + map.put("FifteenMinute", new Double(getFifteenMinute())); + return map; + } +} From 7157234182e16c82b179581850bf100ef9bcf227 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 16:35:51 -0700 Subject: [PATCH 17/20] extend ReflectedMBean --- .../hyperic/sigar/jmx/SigarLoadAverage.java | 233 ++---------------- 1 file changed, 17 insertions(+), 216 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java index 19962477..c5a53398 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarLoadAverage.java @@ -1,5 +1,5 @@ /* - * Copyright (C) [2004, 2005, 2006, 2007], Hyperic, Inc. + * Copyright (C) [2004-2009], Hyperic, Inc. * This file is part of SIGAR. * * SIGAR is free software; you can redistribute it and/or modify @@ -18,237 +18,38 @@ 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.MBeanException; import javax.management.ReflectionException; +import org.hyperic.sigar.LoadAverage; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarNotImplementedException; import org.hyperic.sigar.SigarProxy; -/** - * 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 { +public class SigarLoadAverage extends ReflectedMBean { 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); - + public SigarLoadAverage(SigarProxy sigar) { + super(sigar, MBEAN_TYPE); } - /** - * 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 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(SigarProxy sigar) throws IllegalArgumentException { - super(sigar); - - // 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() { + public Object getAttribute(String name) + throws AttributeNotFoundException, + MBeanException, ReflectionException { try { - return this.sigar.getLoadAverage()[0]; - + Object val = + new LoadAverage(this.sigar.getLoadAverage()).toMap().get(name); + if (val == null) { + throw new AttributeNotFoundException(name); + } + return val; } catch (SigarNotImplementedException e) { - return NOT_IMPLEMENTED_LOAD_VALUE; - + return new Double(Sigar.FIELD_NOTIMPL); } catch (SigarException e) { - throw unexpectedError(MBEAN_TYPE, e); + throw new ReflectionException(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 this.sigar.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 this.sigar.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; - } } From 074d20d7b64a988f43f15c2e8ac24b7298fe3e51 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 17:41:46 -0700 Subject: [PATCH 18/20] switch from Dynamic to Standard MBean --- .../org/hyperic/sigar/jmx/SigarRegistry.java | 42 +++++-------------- .../hyperic/sigar/jmx/SigarRegistryMBean.java | 23 ++++++++++ 2 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 bindings/java/src/org/hyperic/sigar/jmx/SigarRegistryMBean.java diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index e93927d9..156aec0c 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -20,8 +20,6 @@ package org.hyperic.sigar.jmx; import java.util.ArrayList; -import javax.management.AttributeNotFoundException; -import javax.management.MBeanInfo; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.ObjectInstance; @@ -58,34 +56,22 @@ import org.hyperic.sigar.SigarProxy; * @author Bjoern Martin * @since 1.5 */ -public class SigarRegistry extends AbstractMBean implements MBeanRegistration { +public class SigarRegistry implements MBeanRegistration, SigarRegistryMBean { + public static final String MBEAN_DOMAIN = SigarInvokerJMX.DOMAIN_NAME; + public static final String MBEAN_ATTR_TYPE = SigarInvokerJMX.PROP_TYPE; private static final String MBEAN_TYPE = "SigarRegistry"; - private static final MBeanInfo MBEAN_INFO; - - static { - 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.", - null /*new MBeanAttributeInfo[0] */, - null /*new MBeanConstructorInfo[0]*/, - null /*new MBeanOperationInfo[0] */, - null /*new MBeanNotificationInfo[0]*/); - } - + private SigarProxy sigar; private final String objectName; private final ArrayList managedBeans; private MBeanServer mbeanServer; public SigarRegistry(SigarProxy sigar) { - super(sigar); - this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE - + "=" + MBEAN_TYPE; + this.sigar = sigar; + this.objectName = + MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE + "=" + MBEAN_TYPE; this.managedBeans = new ArrayList(); } @@ -93,14 +79,6 @@ public class SigarRegistry extends AbstractMBean implements MBeanRegistration { return this.objectName; } - public Object getAttribute(String attr) throws AttributeNotFoundException { - throw new AttributeNotFoundException(attr); - } - - public MBeanInfo getMBeanInfo() { - return MBEAN_INFO; - } - private void registerMBean(AbstractMBean mbean) { try { ObjectName name = @@ -142,7 +120,7 @@ public class SigarRegistry extends AbstractMBean implements MBeanRegistration { try { info = sigar.getCpuInfoList(); } catch (SigarException e) { - throw unexpectedError("CpuInfoList", e); + info = new CpuInfo[0]; //XXX log } for (int i=0; i Date: Wed, 29 Apr 2009 17:58:39 -0700 Subject: [PATCH 19/20] support no arg SigarRegistry constructor --- .../java/src/org/hyperic/sigar/cmd/Mx.java | 7 +-- .../org/hyperic/sigar/jmx/SigarRegistry.java | 46 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java index 0fb5271a..7520b503 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java @@ -29,7 +29,6 @@ import javax.management.ObjectName; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.jmx.SigarProcess; -import org.hyperic.sigar.jmx.SigarRegistry; public class Mx extends SigarCommandBase { @@ -68,13 +67,15 @@ public class Mx extends SigarCommandBase { if (isRegistered) { return; } - SigarRegistry registry = new SigarRegistry(this.proxy); + try { - server.registerMBean(registry, null); + String name = org.hyperic.sigar.jmx.SigarRegistry.class.getName(); + server.createMBean(name, null); SigarProcess proc = new SigarProcess(this.sigar); server.registerMBean(proc, new ObjectName(proc.getObjectName())); isRegistered = true; } catch (Exception e) { + e.printStackTrace(); throw new SigarException(e.getMessage()); } } diff --git a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java index 156aec0c..76e6a9c3 100644 --- a/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java +++ b/bindings/java/src/org/hyperic/sigar/jmx/SigarRegistry.java @@ -28,8 +28,10 @@ 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.SigarProxy; +import org.hyperic.sigar.SigarProxyCache; /** *

Registry of all Sigar MBeans. Can be used as a convenient way to invoke @@ -61,18 +63,26 @@ public class SigarRegistry implements MBeanRegistration, SigarRegistryMBean { public static final String MBEAN_ATTR_TYPE = SigarInvokerJMX.PROP_TYPE; private static final String MBEAN_TYPE = "SigarRegistry"; + private static final int CACHE_EXPIRE = 60 * 1000; + private Sigar sigarImpl; private SigarProxy sigar; - private final String objectName; + private String objectName; - private final ArrayList managedBeans; + private ArrayList managedBeans; private MBeanServer mbeanServer; + public SigarRegistry() {} + public SigarRegistry(SigarProxy sigar) { + init(sigar); + } + + private void init(SigarProxy sigar) { this.sigar = sigar; this.objectName = MBEAN_DOMAIN + ":" + MBEAN_ATTR_TYPE + "=" + MBEAN_TYPE; - this.managedBeans = new ArrayList(); + this.managedBeans = new ArrayList(); } public String getObjectName() { @@ -99,15 +109,24 @@ public class SigarRegistry implements MBeanRegistration, SigarRegistryMBean { // ------- public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { - this.mbeanServer = server; - return new ObjectName(getObjectName()); + + //no args constructor support + if (this.sigar == null) { + this.sigarImpl = new Sigar(); + init(SigarProxyCache.newInstance(this.sigarImpl, CACHE_EXPIRE)); + } + + this.mbeanServer = server; + if (name == null) { + return new ObjectName(getObjectName()); + } + else { + return name; + } } /** - * Registers the default set of Sigar MBeans. Before doing so, a super call - * is made to satisfy {@link AbstractMBean}. - * - * @see AbstractMBean#postRegister(Boolean) + * Registers the default set of Sigar MBeans. */ public void postRegister(Boolean success) { ReflectedMBean mbean; @@ -205,7 +224,7 @@ public class SigarRegistry implements MBeanRegistration, SigarRegistryMBean { /** * Deregisters all Sigar MBeans that were created and registered using this - * instance. After doing so, a super call is made to satisfy {@link AbstractMBean}. + * instance. * @throws Exception * * @see AbstractMBean#preDeregister() @@ -225,6 +244,11 @@ public class SigarRegistry implements MBeanRegistration, SigarRegistryMBean { } public void postDeregister() { - this.mbeanServer = null; + this.mbeanServer = null; + if (this.sigarImpl != null) { + this.sigarImpl.close(); + this.sigarImpl = null; + this.sigar = null; + } } } From f5881726fd9a6db6decfbad3130f7671dce0a6ca Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 29 Apr 2009 18:08:55 -0700 Subject: [PATCH 20/20] test unregisterMBean --- .../java/src/org/hyperic/sigar/cmd/Mx.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java index 7520b503..36e3ca07 100644 --- a/bindings/java/src/org/hyperic/sigar/cmd/Mx.java +++ b/bindings/java/src/org/hyperic/sigar/cmd/Mx.java @@ -32,7 +32,7 @@ import org.hyperic.sigar.jmx.SigarProcess; public class Mx extends SigarCommandBase { - private boolean isRegistered; + private ObjectName registryName; public Mx(Shell shell) { super(shell); @@ -64,16 +64,18 @@ public class Mx extends SigarCommandBase { } private void register(MBeanServer server) throws SigarException { - if (isRegistered) { + if (this.registryName != null) { return; } try { String name = org.hyperic.sigar.jmx.SigarRegistry.class.getName(); - server.createMBean(name, null); + this.registryName = server.createMBean(name, null).getObjectName(); SigarProcess proc = new SigarProcess(this.sigar); - server.registerMBean(proc, new ObjectName(proc.getObjectName())); - isRegistered = true; + ObjectName pname = new ObjectName(proc.getObjectName()); + if (!server.isRegistered(pname)) { + server.registerMBean(proc, pname); + } } catch (Exception e) { e.printStackTrace(); throw new SigarException(e.getMessage()); @@ -134,7 +136,14 @@ public class Mx extends SigarCommandBase { throw new SigarException(e.getMessage()); } if (launchJconsole) { + flush(); jconsole(); + try { //test unregisterMBean + server.unregisterMBean(this.registryName); + this.registryName = null; + } catch (Exception e) { + e.printStackTrace(); + } } }