Sponsored Link •
|
Summary
I am finishing up a rather large application that needs some JMX management capabilities. I've got a lot of classes that need to be MBean enabled, and I really don't want to go through and change them to inherit from StandardMBean.
Advertisement
|
Netbeans includes the ability to analyze, alter, and generate the structure of Java source code in modules. That's what I'm getting the most mileage out of.
StandardMBean bean; protected void registerMBean() { bean = new StandardMBean( this, MyInterface.class ); MBeanServer appsrvr = MBeanServerFactory.createMBeanServer(); appsrvr.registerMBean( bean, getObjectName() ); } protected ObjectName getObjectName() { return new ObjectName( getClass().getPackage().getName()+":"+ "type=name,name="+getClass().getName() ); }You can add a call to registerMBean in the classes constructor, and have a working MBean for access to your class base on the methods defined in the
MyInterface
interface definition. StandardMBean uses the JavaBean principles to find attributes by
looking for setter and getter patterns. The other methods in the interface become operations.
I created a Netbeans module that embodies this pattern.
The user of the module only needs to right click on a field name, or method name, and select the modules action from the menu. Depending on the selected object, appropriate steps are taken to process the users request.
The two support classes and the interface are always created if not present already. The two support classes and the interface are placed into the same package as the class being manipulated. This might create some redundant code. I am contemplating how to deal with this issue more easily. However, there are some customization possiblities of those two classes which I think makes it interesting to keep them in the package with the class(es) that are using them.
The second pane allows the user to select to receive notification on field value changes. It also allows the user to attach either a CounterMonitor and/or a GaugeMonitor to the fields values. Because of the monitors, a getter will be needed. If notifications on change are requested, a setter will be added to the class to centralize updates to the field, but it will not be present in the interface.
This is still a work in progress, but so far, it look like it will be useful for our needs.
/* * BreakTest.java * * Created on September 5, 2006, 4:46 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.wonderly.test2; import java.io.IOException; import java.lang.management.ManagementFactory; import java.util.logging.Level; import java.util.logging.Logger; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanNotificationInfo; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.Notification; import javax.management.ObjectName; import javax.management.StandardMBean; import javax.management.monitor.CounterMonitor; import javax.management.monitor.GaugeMonitor; /** * * @author gregg */ public class BreakTest implements IJMXBreakTest { int fld; String val; int other1; int other2; /** Creates a new instance of BreakTest */ public BreakTest() { } /** * This method is used to retrieve the current value of * theThe generated interface is shown below. Notice how the setters for minValue and maxValue are not present since I just configured those to notify on change and have gauges.fld
field. The associated MBean attribute will * be capitalized asFld
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #setFld(int) */ public synchronized int getFld() { return fld; } /** * This method is used to set the current value of * thefld
field. The associated MBean attribute will * be capitalized asFld
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #getFld() */ public synchronized void setFld(int val) throws IOException, MalformedObjectNameException { int oval = fld; fld = val; bean.notifyAttributeChange( "Fld", oval, val ); } /** * A logging instance for use by the generated code. */ private java.util.logging.Logger log = Logger.getLogger( getClass().getName() );; /** * This field refers to this instances MBean */ private EventingMBean bean; /** * This method registers the requested monitors for the *Fld
attribute. */ protected void registerMonitorsFld(EventingMBean bean, javax.management.ObjectName on) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException { log.fine("registering mbean monitors for \"Fld\""); GaugeMonitor gageMonitor = new GaugeMonitor() { public void sendNotification( Notification notif ) { notif.setUserData( getFld() ); super.sendNotification( notif ); } }; gageMonitor.setObservedAttribute( "Fld"); gageMonitor.setGranularityPeriod( 100000 ); gageMonitor.setNotifyHigh( true ); gageMonitor.setNotifyLow( true ); gageMonitor.stop(); gageMonitor.addObservedObject( bean.getObjectName() ); CounterMonitor cntMonitor = new CounterMonitor() { public void sendNotification( Notification notif ) { notif.setUserData( getFld() ); super.sendNotification( notif ); } }; cntMonitor.setObservedAttribute( "Fld"); cntMonitor.setGranularityPeriod( 100000 ); cntMonitor.stop(); cntMonitor.addObservedObject( bean.getObjectName() ); if( usePlatformServer() ) { log.finer("registering with platform mbean server"); platformMBeanServer.registerMBean( gageMonitor, bean.getObjectName("GaugeFld")); platformMBeanServer.registerMBean( cntMonitor, bean.getObjectName("CounterFld")); } log.finer("registering with application mbean server"); appMBeanServer.registerMBean( gageMonitor, bean.getObjectName("GaugeFld")); appMBeanServer.registerMBean( cntMonitor, bean.getObjectName("CounterFld")); } /** * This is the reference to the platform MBeanServer * which was used to register MBeans. * @see #appMBeanServer */ protected javax.management.MBeanServer platformMBeanServer; /** * This is the reference to the application MBeanServer * which was used to register MBeans. * @see #platformMBeanServer */ protected javax.management.MBeanServer appMBeanServer; /** * This method initializes all aspects of the JavaBeans which * are needed to support the options selected. Do not edit out the {...} * markers from comments below as they are used by the code generation * steps to find the various pieces already in place so that only the needed * new code is added. */ private void registerMBean() throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException { EventingMBean bean = new EventingMBean(this,org.wonderly.test2.IJMXBreakTest.class); ObjectName on = bean.getObjectName(); if( usePlatformServer() ) { platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); platformMBeanServer.registerMBean( bean, on ); } appMBeanServer = MBeanServerFactory.createMBeanServer(); appMBeanServer.registerMBean( bean, on ); // Do not edit the lines below with {XXXX} tags on them. // Registration of monitors will be added here {REGMON} // {REGMON-MaxValue} registerMonitorsMaxValue( bean, on); // {REGMON-MinValue} registerMonitorsMinValue( bean, on); // {REGMON-Fld} registerMonitorsFld( bean, on); // Notifications will be added here {NOTIFADD} // {NOTIFADD-MaxValue} log.fine("add notification info for MaxValue"); bean.addNotificationInfo( new MBeanNotificationInfo( new String[] { "MaxValue" }, "MaxValue", "MaxValue value change notification" )); // {NOTIFADD-MinValue} log.fine("add notification info for MinValue"); bean.addNotificationInfo( new MBeanNotificationInfo( new String[] { "MinValue" }, "MinValue", "MinValue value change notification" )); // {NOTIFADD-Val} log.fine("add notification info for Val"); bean.addNotificationInfo( new MBeanNotificationInfo( new String[] { "Val" }, "Val", "Val value change notification" )); // {NOTIFADD-Fld} log.fine("add notification info for Fld"); bean.addNotificationInfo( new MBeanNotificationInfo( new String[] { "Fld" }, "Fld", "Fld value change notification" )); } /** * This method provides the plugable place to override how the use * of the platform MBeanServer is selected. The platform server is actively used * by default in this implementation. */ private boolean usePlatformServer() { return System.getProperty( getClass().getPackage().getName()+".noplatform") == null; } /** * This method is used to retrieve the current value of * theval
field. The associated MBean attribute will * be capitalized asVal
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #setVal(java.lang.String) */ public synchronized java.lang.String getVal() { return val; } /** * This method is used to set the current value of * theval
field. The associated MBean attribute will * be capitalized asVal
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #getVal() */ public synchronized void setVal(java.lang.String val) throws IOException, MalformedObjectNameException { java.lang.String oval = val; val = val; bean.notifyAttributeChange( "Val", oval, val ); } /** * This method is used to retrieve the current value of * theminValue
field. The associated MBean attribute will * be capitalized asMinValue
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #setMinValue(int) */ public synchronized int getMinValue() { return other1; } /** * This method is used to set the current value of * theminValue
field. The associated MBean attribute will * be capitalized asMinValue
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #getMinValue() */ public synchronized void setMinValue(int val) throws IOException, MalformedObjectNameException { int oval = other1; other1 = val; bean.notifyAttributeChange( "MinValue", oval, val ); } /** * This method registers the requested monitors for the *MinValue
attribute. */ protected void registerMonitorsMinValue(EventingMBean bean, javax.management.ObjectName on) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException { log.fine("registering mbean monitors for \"MinValue\""); GaugeMonitor gageMonitor = new GaugeMonitor() { public void sendNotification( Notification notif ) { notif.setUserData( getMinValue() ); super.sendNotification( notif ); } }; gageMonitor.setObservedAttribute( "MinValue"); gageMonitor.setGranularityPeriod( 100000 ); gageMonitor.setNotifyHigh( true ); gageMonitor.setNotifyLow( true ); gageMonitor.stop(); gageMonitor.addObservedObject( bean.getObjectName() ); if( usePlatformServer() ) { log.finer("registering with platform mbean server"); platformMBeanServer.registerMBean( gageMonitor, bean.getObjectName("GaugeMinValue")); } log.finer("registering with application mbean server"); appMBeanServer.registerMBean( gageMonitor, bean.getObjectName("GaugeMinValue")); } /** * This method is used to retrieve the current value of * themaxValue
field. The associated MBean attribute will * be capitalized asMaxValue
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #setMaxValue(int) */ public synchronized int getMaxValue() { return other2; } /** * This method is used to set the current value of * themaxValue
field. The associated MBean attribute will * be capitalized asMaxValue
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #getMaxValue() */ public synchronized void setMaxValue(int val) throws IOException, MalformedObjectNameException { int oval = other2; other2 = val; bean.notifyAttributeChange( "MaxValue", oval, val ); } /** * This method registers the requested monitors for the *MaxValue
attribute. */ protected void registerMonitorsMaxValue(EventingMBean bean, javax.management.ObjectName on) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException { log.fine("registering mbean monitors for \"MaxValue\""); GaugeMonitor gageMonitor = new GaugeMonitor() { public void sendNotification( Notification notif ) { notif.setUserData( getMaxValue() ); super.sendNotification( notif ); } }; gageMonitor.setObservedAttribute( "MaxValue"); gageMonitor.setGranularityPeriod( 100000 ); gageMonitor.setNotifyHigh( true ); gageMonitor.setNotifyLow( true ); gageMonitor.stop(); gageMonitor.addObservedObject( bean.getObjectName() ); if( usePlatformServer() ) { log.finer("registering with platform mbean server"); platformMBeanServer.registerMBean( gageMonitor, bean.getObjectName("GaugeMaxValue")); } log.finer("registering with application mbean server"); appMBeanServer.registerMBean( gageMonitor, bean.getObjectName("GaugeMaxValue")); } }
/* * IJMXBreakTest.java * * Created on September 6, 2006, 12:50 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.wonderly.test2; import java.io.IOException; import java.rmi.Remote; import javax.management.MalformedObjectNameException; /** * This interface defines the MBean attributes and Operations * which the implementing class should provide. This interface is * intended to be RMI compatible. All methods throw * {@link java.io.IOException} to provide RMI compatibility without * the {@link java.rmi.RemoteException} being the limit of exceptions * thrown due to I/O or communications issues. * * This interface is machine generated and methods may be added * by subsequent development activities. It can be freely edited * but that might affect its correctness. */ public interface IJMXBreakTest extends Remote { /** * This method is used to retrieve the current value of * thefld
field. The associated MBean attribute will * be capitalized asFld
due to the * mechanisms implemented by the {@link javax.management.StandardMBean}. * @see #setFld(int) */ public int getFld() throws IOException; /** * This method is used to set the current value of * thefld
field. The associated MBean attribute will * be capitalized asFld
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #getFld() */ public void setFld(int val) throws IOException, MalformedObjectNameException; /** * This method is used to retrieve the current value of * theval
field. The associated MBean attribute will * be capitalized asVal
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #setVal(java.lang.String) */ public java.lang.String getVal() throws IOException; /** * This method is used to set the current value of * theval
field. The associated MBean attribute will * be capitalized asVal
due to themechanism implemented by the {@link javax.management.StandardMBean}. * @see #getVal() */ public void setVal(java.lang.String val) throws IOException, MalformedObjectNameException; /** * This method is used to retrieve the current value of * theminValue
field. The associated MBean attribute will * be capitalized asMinValue
due to themechanism implemented by the {@link javax.management.StandardMBean}. */ public int getMinValue() throws IOException; /** * This method is used to retrieve the current value of * themaxValue
field. The associated MBean attribute will * be capitalized asMaxValue
due to themechanism implemented by the {@link javax.management.StandardMBean}. */ public int getMaxValue() throws IOException; }
Have an opinion? Be the first to post a comment about this weblog entry.
If you'd like to be notified whenever Gregg Wonderly adds a new entry to his weblog, subscribe to his RSS feed.
Gregg Wonderly graduated from Oklahoma State University in 1988 with an MS in COMSCI. His areas of concentration include Operating Systems and Languages. His first job was at the AT&T Bell Labs facilities in Naperville IL working on software retrofit for the 5ESS switch. He designed a procedure control language in the era of the development of Java with similar motivations that the Oak and then Java language development was driven by. Language design is still at the top of his list, but his focus tends to be on application languges layered on top of programming languages such as Java. Some just consider this API design, but there really is more to it! Gregg now works for Cyte Technologies Inc., where he does software engineering and design related to distributed systems in highly available environments. |
Sponsored Links
|