Author: cfieber Date: Thu Sep 2 13:29:30 2004 New Revision: 37417 Modified: avalon/trunk/planet/facilities/jmx/mx4j/src/main/org/apache/avalon/jmx/mx4j/MX4JComponentRegistrationManager.java avalon/trunk/planet/facilities/jmx/spi/src/main/org/apache/avalon/jmx/spi/AbstractJMXComponentRegistrationManager.java avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/MBeanInfoBuilder.java avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Resources.properties avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Target.java Log: refactoring to use StandardMBean from JMX 1.2 for MBeans built via introspection, MBean ObjectName generation removed multiple container= elements into a single container= with . separated path name
Modified: avalon/trunk/planet/facilities/jmx/mx4j/src/main/org/apache/avalon/jmx/mx4j/MX4JComponentRegistrationManager.java ============================================================================== --- avalon/trunk/planet/facilities/jmx/mx4j/src/main/org/apache/avalon/jmx/mx4j/MX4JComponentRegistrationManager.java (original) +++ avalon/trunk/planet/facilities/jmx/mx4j/src/main/org/apache/avalon/jmx/mx4j/MX4JComponentRegistrationManager.java Thu Sep 2 13:29:30 2004 @@ -35,10 +35,7 @@ import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.parameters.Parameters; -import org.apache.avalon.framework.parameters.ParameterException; import org.apache.avalon.framework.context.Context; -import org.apache.avalon.framework.context.ContextException; -import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.jmx.spi.AbstractJMXComponentRegistrationManager; Modified: avalon/trunk/planet/facilities/jmx/spi/src/main/org/apache/avalon/jmx/spi/AbstractJMXComponentRegistrationManager.java ============================================================================== --- avalon/trunk/planet/facilities/jmx/spi/src/main/org/apache/avalon/jmx/spi/AbstractJMXComponentRegistrationManager.java (original) +++ avalon/trunk/planet/facilities/jmx/spi/src/main/org/apache/avalon/jmx/spi/AbstractJMXComponentRegistrationManager.java Thu Sep 2 13:29:30 2004 @@ -16,26 +16,21 @@ */ package org.apache.avalon.jmx.spi; -import java.lang.reflect.Constructor; import java.util.HashSet; import java.util.Iterator; import java.util.Set; + +import javax.management.DynamicMBean; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; -import javax.management.modelmbean.ModelMBean; -import javax.management.modelmbean.ModelMBeanInfo; import org.apache.avalon.composition.model.ComponentModel; - -import org.apache.avalon.framework.logger.Logger; -import org.apache.avalon.framework.logger.LogEnabled; import org.apache.avalon.framework.activity.Disposable; - +import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.jmx.ComponentRegistrationException; import org.apache.avalon.jmx.util.MBeanInfoBuilder; import org.apache.avalon.jmx.util.Target; - import org.apache.avalon.util.i18n.ResourceManager; import org.apache.avalon.util.i18n.Resources; @@ -63,12 +58,8 @@ final MBeanServer mBeanServer = createMBeanServer(); setMBeanServer( mBeanServer ); - topicBuilder = new MBeanInfoBuilder(); - - if( topicBuilder instanceof LogEnabled ) - { - ( (LogEnabled)topicBuilder).enableLogging( logger ); - } + + topicBuilder = new MBeanInfoBuilder( logger ); } public void dispose() @@ -123,7 +114,7 @@ while ( i.hasNext() ) { final ObjectName objectName = - createObjectName( name, target.getTopic( ( String ) i.next() ) ); + createObjectName( name, ( String ) i.next() ); getMBeanServer().unregisterMBean( objectName ); } } @@ -199,16 +190,20 @@ throws ComponentRegistrationException { String[] nameComponents = componentModel.getQualifiedName().split( "/" ); + String qName = componentModel.getQualifiedName(); + if ( qName.startsWith("/") ) + { + qName = qName.substring(1); + } + qName = qName.replace( '/', '.' ); + int idx = qName.lastIndexOf( '.' ); StringBuffer name = new StringBuffer(); - for ( int i = 0; i < nameComponents.length - 1; i++ ) + if ( idx != -1 ) { - String s = nameComponents[i].trim(); - if ( s.length() > 0 ) - { - name.append( "container=" ).append( nameComponents[i] ).append( ',' ); - } + name.append( "container=" ).append( qName.substring( 0, idx )).append( ',' ); } - name.append( "name=" ).append( nameComponents[nameComponents.length - 1] ); + name.append( "name=" ).append( qName.substring( idx + 1) ); + return name.toString(); } @@ -260,17 +255,9 @@ while ( i.hasNext() ) { final String topicName = ( String ) i.next(); - final ModelMBeanInfo topic = target.getTopic( topicName ); + final DynamicMBean mBean = target.getTopic( topicName ); final String targetName = target.getName(); - final Object managedResource = target.getManagedResource(); - Object targetObject = managedResource; - if ( topic.getMBeanDescriptor().getFieldValue( "proxyClassName" ) != null ) - { - targetObject = createManagementProxy( topic, managedResource ); - } - - // use a proxy adapter class to manage object - exportTopic( topic, targetObject, targetName ); + exportTopic( mBean, topicName, targetName ); } } @@ -284,96 +271,12 @@ * @throws Exception if the Topic cannot be exported * @return the mBean */ - protected Object exportTopic( final ModelMBeanInfo topic, final Object target, - final String targetName ) throws Exception + protected void exportTopic( final DynamicMBean mBean, + final String topicName, + final String targetName ) throws Exception { - final Object mBean = createMBean( topic, target ); - final ObjectName objectName = createObjectName( targetName, topic ); + final ObjectName objectName = createObjectName( targetName, topicName ); getMBeanServer().registerMBean( mBean, objectName ); - - // debugging stuff. - /* - ModelMBean modelMBean = (ModelMBean)mBean; - ModelMBeanInfo modelMBeanInfo = (ModelMBeanInfo)modelMBean.getMBeanInfo(); - MBeanAttributeInfo[] attList = modelMBeanInfo.getAttributes(); - for( int i = 0; i < attList.length; i++ ) - { - ModelMBeanAttributeInfo mbai = (ModelMBeanAttributeInfo)attList[ i ]; - Descriptor d = mbai.getDescriptor(); - String[] fieldNames = d.getFieldNames(); - for( int j = 0; j < fieldNames.length; j++ ) - { - String fieldName = fieldNames[ j ]; - System.out.println( "Field name = " + fieldName + - " / value = " + d.getFieldValue( fieldName ) + - "::" +mbai.getType() + " value " + - modelMBean.getAttribute( mbai.getName() ) + " for " + mbai.getName() ); - } - } - */ - - return mBean; - } - - /** - * Create a MBean for specified object. - * The following policy is used top create the MBean... - * - * @param topic the topic - * @param target the object to create MBean for - * @return the MBean to be exported - * @throws ComponentRegistrationException if an error occurs - */ - private Object createMBean( final ModelMBeanInfo topic, final Object target ) throws - ComponentRegistrationException - { - final String className = topic.getClassName(); - // Load the ModelMBean implementation class - Class clazz; - try - { - clazz = Class.forName( className ); - } - catch ( Exception e ) - { - final String message = - REZ.getString( "jmxmanager.error.mbean.load.class", className ); - getLogger().error( message, e ); - throw new ComponentRegistrationException( message, e ); - } - - // Create a new ModelMBean instance - ModelMBean mbean = null; - try - { - mbean = ( ModelMBean ) clazz.newInstance(); - mbean.setModelMBeanInfo( topic ); - } - catch ( final Exception e ) - { - final String message = - REZ.getString( "jmxmanager.error.mbean.instantiate", className ); - getLogger().error( message, e ); - throw new ComponentRegistrationException( message, e ); - } - - // Set the managed resource (if any) - try - { - if ( null != target ) - { - mbean.setManagedResource( target, "ObjectReference" ); - } - } - catch ( Exception e ) - { - final String message = - REZ.getString( "jmxmanager.error.mbean.set.resource", className ); - getLogger().error( message, e ); - throw new ComponentRegistrationException( message, e ); - } - - return mbean; } /** @@ -384,34 +287,11 @@ * @return the [EMAIL PROTECTED] ObjectName} representing object * @throws MalformedObjectNameException if malformed name */ - private ObjectName createObjectName( final String name, final ModelMBeanInfo topic ) throws + private ObjectName createObjectName( final String name, final String topicName ) throws MalformedObjectNameException { - return new ObjectName( getDomain() + ":" + name + ",topic=" + topic.getDescription() ); - } - - /** - * Instantiates a proxy management object for the target object - * - * this should move out of bridge and into Registry, it isn't specifically for jmx - * - * @param topic the topic - * @param managedObject the managed object - * @throws Exception if a management proxy cannot be created - * @return the management proxy - */ - private Object createManagementProxy( final ModelMBeanInfo topic, final Object managedObject ) - throws Exception - { - final String proxyClassname = ( String ) topic.getMBeanDescriptor().getFieldValue( - "proxyClassName" ); - final ClassLoader classLoader = managedObject.getClass().getClassLoader(); - final Class proxyClass = classLoader.loadClass( proxyClassname ); - final Class[] argTypes = new Class[] - {Object.class}; - final Object[] argValues = new Object[] - {managedObject}; - final Constructor constructor = proxyClass.getConstructor( argTypes ); - return constructor.newInstance( argValues ); + final String objectName = getDomain() + ":" + name + ",topic=" + topicName; + getLogger().debug("ObjectName=" + objectName); + return new ObjectName( objectName ); } } Modified: avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/MBeanInfoBuilder.java ============================================================================== --- avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/MBeanInfoBuilder.java (original) +++ avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/MBeanInfoBuilder.java Thu Sep 2 13:29:30 2004 @@ -21,29 +21,27 @@ import java.beans.MethodDescriptor; import java.beans.ParameterDescriptor; import java.beans.PropertyDescriptor; - import java.io.InputStream; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; import javax.management.Descriptor; +import javax.management.DynamicMBean; import javax.management.MBeanParameterInfo; - +import javax.management.StandardMBean; +import javax.management.modelmbean.ModelMBean; import javax.management.modelmbean.ModelMBeanAttributeInfo; import javax.management.modelmbean.ModelMBeanConstructorInfo; +import javax.management.modelmbean.ModelMBeanInfo; import javax.management.modelmbean.ModelMBeanInfoSupport; import javax.management.modelmbean.ModelMBeanNotificationInfo; import javax.management.modelmbean.ModelMBeanOperationInfo; import javax.management.modelmbean.RequiredModelMBean; -import org.apache.avalon.util.i18n.ResourceManager; -import org.apache.avalon.util.i18n.Resources; - import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.avalon.framework.logger.AbstractLogEnabled; - +import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.util.i18n.ResourceManager; +import org.apache.avalon.util.i18n.Resources; import org.xml.sax.InputSource; /** @@ -58,11 +56,23 @@ * TODO: update JavaDoc */ -public class MBeanInfoBuilder extends AbstractLogEnabled +public class MBeanInfoBuilder { private static final Resources REZ = ResourceManager.getPackageResources( MBeanInfoBuilder.class ); private static final String REQ_MODEL_MBEAN = RequiredModelMBean.class.getName(); + private Logger m_logger; + + public MBeanInfoBuilder( Logger logger ) + { + m_logger = logger; + } + + protected Logger getLogger() + { + return m_logger; + } + /** * Builds MBeans for the management interfaces of a class. * @@ -139,20 +149,98 @@ final Configuration[] topicsConfig = config.getChildren( "topic" ); for ( int i = 0; i < topicsConfig.length; i++ ) { - final ModelMBeanInfoSupport topic = buildTopic( topicsConfig[i], beanInfo ); - target.addTopic( topic ); + final ModelMBeanInfo topic = buildTopic( topicsConfig[i], beanInfo ); + try + { + final DynamicMBean mbean = createMBean( topic, target.getManagedResource() ); + target.addTopic( topicsConfig[i].getAttribute( "name" ), mbean ); + } + catch ( final Exception e) + { + final String message = REZ.getString( "mxinfo.error.mbean", topic.getDescription() ); + throw new ConfigurationException( message, e ); + } } // load each proxy final Configuration[] proxysConfig = config.getChildren( "proxy" ); for ( int i = 0; i < proxysConfig.length; i++ ) { - final ModelMBeanInfoSupport topic = buildProxyTopic( proxysConfig[i], managedClass ); - target.addTopic( topic ); + final ModelMBeanInfo topic = buildProxyTopic( proxysConfig[i], managedClass ); + try + { + final DynamicMBean mbean = createMBean( topic, target.getManagedResource() ); + target.addTopic( proxysConfig[i].getAttribute( "name" ), mbean ); + } + catch ( final Exception e) + { + final String message = REZ.getString( "mxinfo.error.mbean", topic.getDescription() ); + throw new ConfigurationException( message, e ); + } } } + private DynamicMBean createMBean( final ModelMBeanInfo topic, final Object target ) throws Exception + { + final String className = topic.getClassName(); + // Load the ModelMBean implementation class + final ClassLoader cl = Thread.currentThread().getContextClassLoader(); + + final Class clazz; + try + { + if ( null == cl ) + { + clazz = Class.forName( className ); + } + else + { + clazz = cl.loadClass( className ); + } + } + catch ( Exception e ) + { + final String message = + REZ.getString( "jmxmanager.error.mbean.load.class", className ); + getLogger().error( message, e ); + throw new Exception( message, e ); + } + + // Create a new ModelMBean instance + ModelMBean mbean = null; + try + { + mbean = ( ModelMBean ) clazz.newInstance(); + mbean.setModelMBeanInfo( topic ); + } + catch ( final Exception e ) + { + final String message = + REZ.getString( "jmxmanager.error.mbean.instantiate", className ); + getLogger().error( message, e ); + throw new Exception( message, e ); + } + + // Set the managed resource (if any) + try + { + if ( null != target ) + { + mbean.setManagedResource( target, "ObjectReference" ); + } + } + catch ( Exception e ) + { + final String message = + REZ.getString( "jmxmanager.error.mbean.set.resource", className ); + getLogger().error( message, e ); + throw new Exception( message, e ); + } + + return mbean; + } + /** * Builds a topic based on introspection of the interface. * @@ -165,56 +253,10 @@ { try { - final BeanInfo beanInfo = Introspector.getBeanInfo( interfaceClass ); - - // do the methods - final MethodDescriptor[] methods = beanInfo.getMethodDescriptors(); - final List operations = new ArrayList(); - - for ( int j = 0; j < methods.length; j++ ) - { - // skip getters and setters - final String name = methods[j].getName(); - if ( !( name.startsWith( "get" ) || name.startsWith( "set" ) - || name.startsWith( "is" ) ) ) - { - operations.add( buildOperationInfo( methods[j], null ) ); - } - } - - final ModelMBeanOperationInfo[] operationList = ( ModelMBeanOperationInfo[] ) - operations.toArray( new - ModelMBeanOperationInfo[0] ); - - // do the attributes - final PropertyDescriptor[] propertys = beanInfo.getPropertyDescriptors(); - final List attributesList = new ArrayList(); - - for ( int j = 0; j < propertys.length; j++ ) - { - final ModelMBeanAttributeInfo attribute = buildAttributeInfo( propertys[j], null ); - //could be null for indexed properties - if (null != attribute) - { - attributesList.add( attribute ); - } - } - final ModelMBeanAttributeInfo[] attributes = - (ModelMBeanAttributeInfo[]) attributesList.toArray( new ModelMBeanAttributeInfo[0] ); - - final ModelMBeanConstructorInfo[] constructors = new ModelMBeanConstructorInfo[0]; - - final ModelMBeanNotificationInfo[] notifications = new ModelMBeanNotificationInfo[0]; - - final String shortName = getShortName( interfaceClass.getName() ); - final ModelMBeanInfoSupport topic = new ModelMBeanInfoSupport( REQ_MODEL_MBEAN, - shortName, attributes, constructors, operationList, notifications ); - - // add it to target - final String message = REZ.getString( "mxinfo.debug.adding.topic", topic.getDescription() ); - getLogger().debug( message ); - - target.addTopic( topic ); + StandardMBean mbean = new StandardMBean( target.getManagedResource(), interfaceClass ); + String name = interfaceClass.getName(); + name = name.substring(name.lastIndexOf('.') + 1); + target.addTopic( name, mbean ); } catch ( final Exception e ) { @@ -232,7 +274,7 @@ * @return the created ModelMBeanInfoSupport * @throws ConfigurationException if an error occurs */ - private ModelMBeanInfoSupport buildTopic( final Configuration config, final BeanInfo beanInfo ) throws + private ModelMBeanInfo buildTopic( final Configuration config, final BeanInfo beanInfo ) throws ConfigurationException { final ModelMBeanAttributeInfo[] attributes = buildAttributeInfos( config, beanInfo ); @@ -258,8 +300,8 @@ * @return the created ModelMBeanInfoSupport * @throws ConfigurationException if there is a problem generating the Proxy */ - private ModelMBeanInfoSupport buildProxyTopic( final Configuration proxyTagConfig, - final Class managedClass ) throws + private ModelMBeanInfo buildProxyTopic( final Configuration proxyTagConfig, + final Class managedClass ) throws ConfigurationException { try @@ -272,7 +314,7 @@ final Configuration classConfig = loadMxInfo( proxyClass ); final Configuration topicConfig = classConfig.getChild( "topic" ); final BeanInfo info = Introspector.getBeanInfo( proxyClass ); - final ModelMBeanInfoSupport topic = buildTopic( topicConfig, info ); + final ModelMBeanInfo topic = buildTopic( topicConfig, info ); final Descriptor mBeanDescriptor = topic.getMBeanDescriptor(); mBeanDescriptor.setField( "proxyClassName", proxyName ); topic.setMBeanDescriptor( mBeanDescriptor ); Modified: avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Resources.properties ============================================================================== --- avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Resources.properties (original) +++ avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Resources.properties Thu Sep 2 13:29:30 2004 @@ -2,6 +2,7 @@ mxinfo.debug.found.mxinfo=mxinfo found for {0}. mxinfo.error.target=Failed to create topics for target {0}. mxinfo.error.introspect=Can't introspect class {0}. +mxinfo.error.mbean=Can't create MBean for {0}. mxinfo.debug.adding.topic=Adding topic {0}. mxinfo.error.topic=Failed to create topic for {0}. mxinfo.debug.building.proxy.topic=Building proxyTopic {0}. Modified: avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Target.java ============================================================================== --- avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Target.java (original) +++ avalon/trunk/planet/facilities/jmx/util/src/main/org/apache/avalon/jmx/util/Target.java Thu Sep 2 13:29:30 2004 @@ -18,7 +18,8 @@ import java.util.HashMap; import java.util.Set; -import javax.management.modelmbean.ModelMBeanInfo; + +import javax.management.DynamicMBean; /** * It reprensents a managed object in the managegement space. It is a container for @@ -73,9 +74,9 @@ * * @param topic the topic */ - public void addTopic( final ModelMBeanInfo topic ) + public void addTopic( final String name, final DynamicMBean topic ) { - m_topics.put( topic.getDescription(), topic ); + m_topics.put( name, topic ); } /** @@ -93,9 +94,9 @@ * @param name the name of the topic * @return the topic of that name */ - public ModelMBeanInfo getTopic( final String name ) + public DynamicMBean getTopic( final String name ) { - return ( ModelMBeanInfo ) m_topics.get( name ); + return ( DynamicMBean ) m_topics.get( name ); } /** --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]