package cyrille.jmx; import java.lang.reflect.Method; import java.util.Hashtable; import java.util.List; import javax.management.MBeanServer; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.log4j.Logger; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; import org.hibernate.jmx.StatisticsService; /** * Registers MBeans in Websphere's {@link MBeanServer} at web application startup * * @author <a href="mailto:cleclerc@xebia.fr">Cyrille Le Clerc</a> */ public class JmxServletContextListener implements ServletContextListener { private final static Logger logger = Logger.getLogger(JmxServletContextListener.class); protected MBeanServer mbeanServer; protected SessionFactory sessionFactory; protected List<ObjectName> registeredObjectNames; /** * Unregister MBeans */ public void contextDestroyed(ServletContextEvent servletContextEvent) { for (ObjectName objectName : this.registeredObjectNames) { try { this.mbeanServer.unregisterMBean(objectName); logger.debug("MBean successfully unregistered : " + objectName); } catch (Exception e) { logger.error("Exception unregistering " + objectName, e); } } } /** * Configures Hibernate and register its MBean * * @param servletContextEvent * @param enterpriseApplicationName * @param webModuleName * @throws Exception */ private void configureAndRegisterHibernate(ServletContextEvent servletContextEvent, String enterpriseApplicationName, String webModuleName) throws Exception { Configuration configuration = new AnnotationConfiguration(); configuration.configure(); this.sessionFactory = configuration.buildSessionFactory(); // build the ObjectName you want Hashtable<String, String> hashtable = new Hashtable<String, String>(); hashtable.put("type", "statistics"); hashtable.put("J2EEApplication", enterpriseApplicationName); hashtable.put("sessionFactory", webModuleName); ObjectName statisticsObjectName = new ObjectName("hibernate", hashtable); StatisticsService hibernateStatistics = new StatisticsService(); hibernateStatistics.setSessionFactory(this.sessionFactory); ObjectInstance objectInstance = this.mbeanServer.registerMBean(hibernateStatistics, statisticsObjectName); this.registeredObjectNames.add(objectInstance.getObjectName()); logger.debug("Hibernate StatisticsService MBean registered as " + statisticsObjectName); } public void contextInitialized(ServletContextEvent servletContextEvent) { try { /* * Use introspection instead of class to compile without Websphere jars <br/> * MBeanServer mbs = * com.ibm.websphere.management.AdminServiceFactory.getMBeanFactory().getMBeanServer(); */ Class<?> adminServiceFactoryClass = Class.forName("com.ibm.websphere.management.AdminServiceFactory"); Method getMBeanFactoryMethod = adminServiceFactoryClass.getMethod("getMBeanFactory", new Class[] {}); Object mbeanFactory = getMBeanFactoryMethod.invoke(null, new Object[] {}); Method getMBeanServerMethod = mbeanFactory.getClass().getMethod("getMBeanServer", new Class[] {}); this.mbeanServer = (MBeanServer) getMBeanServerMethod.invoke(mbeanFactory, new Object[] {}); // TODO : find enterpriseAppName from Servletcontext String enterpriseApplicationName = "ivtApp"; String webModuleName = servletContextEvent.getServletContext().getServletContextName(); configureAndRegisterHibernate(servletContextEvent, enterpriseApplicationName, webModuleName); } catch (Exception e) { // log before rethrowing because servlet container may not display clear error message logger.fatal("Exception configuring components", e); throw new RuntimeException("Exception configuring components", e); } } }