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.