This is the MBean interface for the JBoss bootstrapper:
Code:
package com.allustra.test.jmx;
/**
* @author timg
* @Copyright (c) Allustra Ltd. 2005. All rights reserved.
*/
public interface SpringContainerMBean
{
/**
* Setter for the JNDI name under which the application context will be exported as an MBean.
* @param applicationContextJndiName The JNDI name.
*/
void setApplicationContextJndiName(String applicationContextJndiName);
/**
* Getter for the JNDI name under which the application context will be exported as an MBean.
* @return The JNDI name.
*/
String getApplicationContextJndiName();
/**
* Setter for the resource locations of the XML-based Spring configuration file(s).
* @param locations The resource locations in the classpath.
*/
void setConfigLocations(String[] locations);
/**
* Getter for the resource locations of the XML-based Spring configuration file(s).
* @return The resource locations in the classpath.
*/
String[] getConfigLocations();
/**
* JMX lifecycle method.
* @throws Exception
*/
void start() throws Exception;
/**
* JMX lifecycle method.
* @throws Exception
*/
void stop() throws Exception;
}
This is the implementation:
Code:
package com.allustra.test.jmx;
import java.util.Map;
import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.jmx.export.MBeanExporter;
/**
* @author timg
* @Copyright (c) Allustra Ltd. 2005. All rights reserved.
*/
public class SpringContainer implements SpringContainerMBean
{
protected final Log m_logger = LogFactory.getLog(getClass());
private String[] m_configLocations;
private String m_applicationContextJndiName;
private ApplicationContext m_context;
private MBeanExporter m_exporter;
public void setApplicationContextJndiName(String applicationContextJndiName)
{
m_applicationContextJndiName = applicationContextJndiName;
}
public String getApplicationContextJndiName()
{
return m_applicationContextJndiName;
}
public void setConfigLocations(String[] locations)
{
if (locations != null)
{
m_configLocations = new String[locations.length];
System.arraycopy(locations, 0, m_configLocations, 0, locations.length);
}
else
{
m_configLocations = null;
}
}
public String[] getConfigLocations()
{
String[] result = null;
if (m_configLocations != null)
{
result = new String[m_configLocations.length];
System.arraycopy(m_configLocations, 0, result, 0, m_configLocations.length);
}
return result ;
}
public void start() throws Exception
{
if (!isStarted())
{
if (m_logger.isInfoEnabled())
{
m_logger.info("SpringContainer starting...");
}
if (m_configLocations != null)
{
m_context = new ClassPathXmlApplicationContext(m_configLocations);
if (m_applicationContextJndiName != null)
{
m_exporter = new MBeanExporter();
Map beans = new HashMap();
beans.put(m_applicationContextJndiName, m_context);
m_exporter.setBeans(beans);
m_exporter.afterPropertiesSet();
}
if (m_logger.isInfoEnabled())
{
m_logger.info("SpringContainer started");
}
}
else
{
if (m_logger.isInfoEnabled())
{
m_logger.info("SpringContainer - no config locations, not started");
}
}
}
}
private boolean isStarted()
{
return m_context != null;
}
public void stop() throws Exception
{
if (isStarted())
{
if (m_logger.isInfoEnabled())
{
m_logger.info("SpringContainer stopping...");
}
if (m_context instanceof DisposableBean)
{
((DisposableBean)m_context).destroy();
}
m_context = null;
if (m_exporter instanceof DisposableBean)
{
((DisposableBean)m_exporter).destroy();
}
m_exporter = null;
if (m_logger.isInfoEnabled())
{
m_logger.info("SpringContainer stopped");
}
}
}
}
You'll need this in addtion to any beans you'd like to expose via JMX:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="allustra:service=PersonGreeter"><ref bean="personGreeter"/></entry>
</map>
</property>
</bean>
</beans>
Where personGreeter is just some noddy class I wrote to demo the concept - it'd defined in another applicationContext.xml which need know nothing about your JMX stuff.
And then your jboss-service.xml will need to look something like:
Code:
<!-- The SAR META-INF/jboss-service.xml descriptor -->
<server>
<mbean code="com.allustra.test.jmx.SpringContainer"
name="allustra:service=TestSpringContainer">
<attribute name="ConfigLocations">
com/allustra/test/applicationContext.xml
com/allustra/test/jmx/applicationContext-jmx.xml
</attribute>
<attribute name="ApplicationContextJndiName">allustra:service=TestApplicationContext</attribute>
</mbean>
</server>
Knock yourselves out.