Publishing statistics through JMX

Generality

Hibernate3 provides to the user, some statistics on a session factory. It is possible to publish them through a JMX MBean quite easily whether the application is J2EE or standalone.

There are 2 different approach for this JMX service :

  • publish a JMX MBean that query session factory statistics using the SF JNDI name
  • publish a JMX MBean for every session factory and query statistics through the appropriate MBean object name

 

Publish a per JNDI JMX MBean

.. soon

 

Publish a per session factory JMX MBean

Thus the MBean will be bound to your SessionFactory life cycle. Here is a sample of code that register the MBean

//build your SF
SessionFactory sf = (new Configuration()).addClass(Simple.class).buildSessionFactory();
//get the available MBean servers
ArrayList list = MBeanServerFactory.findMBeanServer(null);
//take the first one
MBeanServer server = (MBeanServer) list.get(0);

//build the MBean name
ObjectName on = new ObjectName("Hibernate:type=statistics,application=sample");
StatisticsService mBean = new StatisticsService();
mBean.setSessionFactory(sf);
server.registerMBean(mBean, on);

 

When the SessionFactory is closed, we need to unregister the MBean

//get the available MBean servers
ArrayList list = MBeanServerFactory.findMBeanServer(null);
//take the first one
MBeanServer server = (MBeanServer) list.get(0);
server.unregisterMBean(on);

 

You can add this code to you HibernateUtil like class.

 

Having a JMX infrastructure when the application is standalone

J2EE servers such as JBoss or Weblogic came with a bundled and activated JMX implementation, but you can easily have yours on your standalone apps. This is very easy, you just need a JMX implemetation in your CP:

  • JBossJMX (jboss-jmx.jar and jboss-common.jar)
  • MX4J (mx4j.jar)
//create a MBean Server named Hibernate
MBeanServerFactory.createMBeanServer("Hibernate");
//that's it :-)

 

JMX clients for the statistics MBean

Here is the simpliest client you can find, this is an intra-JVM request

MBeanServer server = ...;
Long openedSession = (Long) server.getAttribute(on, "SessionOpenCount");

 

Enable RMI publishing of JMX beans in standalone application

The following shows the code that enables RMI publishing of the JMX beans, thus allowing

you to use MC4J console directly on your standalone app. (Note: derived from the examples in MX4J and dependent on MX4J)

//create a MBean Server named Hibernate
MBeanServerFactory.createMBeanServer("Hibernate");

// Register and start the tnameserv MBean, needed by JSR 160 RMIConnectorServer over IIOP
ObjectName namingName = ObjectName.getInstance("naming:type=tnameserv");
server.createMBean("mx4j.tools.naming.CosNamingService", namingName, null);
// Standard port for the COS naming service is 900, but that's a restricted port on Unix/Linux systems
int namingPort = 1199;
server.setAttribute(namingName, new javax.management.Attribute("Port", new Integer(namingPort)));
server.invoke(namingName, "start", null, null);

String jndiPath = "/jmxconnector";
JMXServiceURL url = new JMXServiceURL("service:jmx:iiop://localhost/jndi/iiop://localhost:" + namingPort + jndiPath);

// Create and start the RMIConnectorServer over IIOP
JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
connectorServer.start();
              
//build the MBean name
ObjectName on = new ObjectName("Hibernate:type=statistics,application=sample");
            
StatisticsService mBean = new StatisticsService();
mBean.setSessionFactory(sf);
server.registerMBean(mBean, on);

...and now you just use MC4J to connect via the JSR160 spec and uses "service:jmx:iiop://localhost/jndi/iiop://localhost:1199/jmxconnector" as the Server url.