On Tue, 2004-04-20 at 10:32, Niclas Hedhman wrote:
> On Monday 19 April 2004 21:46, Mina Meitsi wrote:
> > Third, I currently have my own JMX component, where I
> > register the methods I want to expose (the component
> > generates interfaces and proxies dynamically for JMX).
> 
> JMX is also something that is included in the upcoming 3.3 release. We have so 
> far only done a Name-based system, where the management interface must reside 
> in a separate interface class called <component-name>MBean, for instance 
> MyComponentMBean.
> This is far from optimal, but was contributed by a user for quick adoption. 
> The goal is to extend this to meta-info tags in the component.
> Any help, at any level would be greatly appreciated.

Sorry - I've been a little behind reading this list.

I'm using JMX fairly extensively with Merlin 3.2.5 - I rolled my own bit
of magic using an @avalon.extension component. The extension creates an
mbean server, an HTTP adaptor, and a remote connector.

Basically, if you mark a class as being "manageable" (i.e., mark it as
using the extension), then the manager will automatically register the
mbean with the mbeanServer when the component is deployed and then
unregisters it when it's deployed.

It automatically assigns ObjectNames based on the implementation package
of the deployed component and the component's block name (i.e.,
"com.mycompany.myproject.mypackage:block=myBlockName"). Alternatively,
the component can implement a Manageable interface that the management
extension will use to get a name for the object.

Currently, there's no effort to make ObjectNames unique to support
non-singleton component lifestyles - I haven't needed it for my project,
so I didn't build it. Someone with a better understanding of Merlin's
innards might be able to do that quite easily.

If anyone thinks this code would be useful, I'll happily contribute it.

Here you go...

/**
 * @avalon.stage id='urn:flashtalk.com:manageable'
 */
public interface Manageable {
        String getManagementName();
}

import java.io.File;
import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import mx4j.adaptor.http.HttpAdaptor;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.lifecycle.Creator;

import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;

/**
 * @avalon.component name='managementServer' lifestyle='singleton'
 * @avalon.extension id='urn:flashtalk.com:manageable'
 */
public class ManagementServer implements Creator, LogEnabled,
Configurable, Initializable, Startable, Disposable {
        private Logger logger;

        public static final int DEFAULT_PORT = 9999;

        private MBeanServer mbeanServer;
        private HttpAdaptor httpAdaptor;
        private JMXConnectorServer connectorServer;

        private int port;

        public void enableLogging( Logger logger) { this.logger = logger; }

        public void configure( Configuration configuration) throws
ConfigurationException {
                port = configuration.getChild( "port").getValueAsInteger(
DEFAULT_PORT);
        }

        public void initialize() throws Exception {
                mbeanServer = MBeanServerFactory.createMBeanServer();
                httpAdaptor = new HttpAdaptor();
                ObjectName name = new ObjectName( "Server:name=HttpAdaptor");
                mbeanServer.registerMBean( httpAdaptor, name);
                httpAdaptor.setPort( port);

                ObjectName processorName = new ObjectName(
"Server:name=XSLTProcessor");
                mbeanServer.createMBean( "mx4j.adaptor.http.XSLTProcessor",
processorName, null);
                mbeanServer.setAttribute( name, new Attribute( "ProcessorName",
processorName));
                mbeanServer.setAttribute( processorName, new Attribute( "File",
System.getProperty( "user.home") + File.separator +
"merlin/repository/mx4j/jars/mx4j-tools.1.1.1.jar"));
                mbeanServer.setAttribute( processorName, new Attribute( "PathInJar",
"mx4j/adaptor/http/xsl"));
                mbeanServer.setAttribute( processorName, new Attribute( "UseCache",
Boolean.FALSE));

                logger.info( "creating RMI connector server");
                JMXServiceURL url = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://localhost/server");
                connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(
url, null, mbeanServer);
                logger.info( "created RMI connector server");
        }

        public void start() throws Exception {
                httpAdaptor.start();
                logger.info( "starting RMI connector server");
                connectorServer.start();
                logger.info( "started RMI connector server");
        }

        public void stop() throws Exception {
                httpAdaptor.stop();
                logger.info( "stopping RMI connector server");
                connectorServer.stop();
                logger.info( "stopped RMI connector server");
        }

        public void dispose() {
                MBeanServerFactory.releaseMBeanServer( mbeanServer);
        }

        public void create( Object object, Context context) throws Exception {
                String name = generateName( object, ( String) context.get(
"urn:avalon:name"));
                if ( logger.isDebugEnabled()) logger.debug( "Registering " + object +
" (" + name + ")");
                ObjectName objectName = new ObjectName( name);
                if ( !mbeanServer.isRegistered( objectName))
mbeanServer.registerMBean( object, objectName);
        }

        private String generateName( Object object, String blockName) {
                if ( object instanceof Manageable) {
                        Manageable manageable = ( Manageable) object;
                        return manageable.getManagementName();
                }
                Class c = object.getClass();
                return c.getPackage().getName() + ":block=" + blockName;
        }

        public void destroy( Object object, Context context) {
                String name;
                try {
                        name = generateName( object, ( String) context.get(
"urn:avalon:name"));
                } catch ( ContextException e) {
                        assert false;
                        name = null;
                }
                if ( logger.isDebugEnabled()) logger.debug( "Releasing " + object + "
(" + name + ")");
                try {
                        mbeanServer.unregisterMBean( new ObjectName( name));
                } catch ( MalformedObjectNameException e) {
                        if ( logger.isWarnEnabled()) logger.warn( "releasing " + name, 
e);
                } catch ( InstanceNotFoundException e) {
                        if ( logger.isWarnEnabled()) logger.warn( "releasing " + name, 
e);
                } catch ( MBeanRegistrationException e) {
                        if ( logger.isWarnEnabled()) logger.warn( "releasing " + name, 
e);
                }
        }
}




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to