Example of registering MBean

0

SessionTracker object will increment the sessions count moment a session starts and decrement when it is destroyed. In this article, we will see an example of registering MBean. We will see how we can create and register a JMX service to view the currently active sessions.
Let’s come to the setup part. We want to build and run the web application from eclipse itself so your setup consists of the below:

  1. Log4j Setup
  2. Maven Web Application Setup in Eclipse

Let’s start with our example.

Create MBean

This is our MBean interface.

SessionStatisticsMBean:

package com.javarticles.mbean;

public interface SessionStatisticsMBean {
    String getDescription();

    Long getActiveSessions();
    
    String getAttributeAsString(String inFieldId);
}

Implement the bean.

SessionStatistics:

package com.javarticles.mbean;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.javarticles.servlet.SessionTracker;

public class SessionStatistics implements SessionStatisticsMBean {

    public String getDescription() {        
        return "MBean Example to track sessions";
    }

    public Long getActiveSessions() {
        return sessionTracker.getSessionCount();
    }
    
    public String getAttributeAsString(String inFieldId) {
        String results = "";
        try {
            results = BeanUtils.getProperty(this, inFieldId);
        } catch (Throwable t) {
            results = "Error getting attribute: " + t;
        }
        return results;
    }
    
    @Autowired
    private SessionTracker sessionTracker;
}

As you see from the above implementation, it depends on SessionTracker bean.

SessionTracker:

package com.javarticles.servlet;

import java.util.concurrent.atomic.AtomicLong;

import org.apache.log4j.Logger;

public class SessionTracker {
    private AtomicLong sessionCount = new AtomicLong(0);

    void incrementSessionCount() {
        LOGGER.warn("Increment the session count");
        sessionCount.incrementAndGet();
    }

    public long getSessionCount() {
        LOGGER.warn("Current session count " + sessionCount.get());
        return sessionCount.get();
    }

    void decrementSessionCount() {
        sessionCount.decrementAndGet();
    }

    private static final Logger LOGGER = Logger.getLogger(SessionTracker.class);
}

The session count is incremented/decremented in HttpSessionListener thus as users access the web application, the Session Tracking is managed.

SessionTrackerHttpSessionListener:

package com.javarticles.servlet;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SessionTrackerHttpSessionListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent event) {
        LOGGER.warn("In SessionTrackerHttpSessionListener. In SessionCreated");
        WebApplicationContext context = WebApplicationContextUtils
                .getWebApplicationContext(event.getSession()
                        .getServletContext());
        SessionTracker sessionTracker = (SessionTracker) context
                .getBean("sessionTracker");
        sessionTracker.incrementSessionCount();
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        WebApplicationContext context = WebApplicationContextUtils
                .getWebApplicationContext(event.getSession()
                        .getServletContext());
        SessionTracker sessionTracker = (SessionTracker) context
                .getBean("sessionTracker");
        sessionTracker.decrementSessionCount();
    }

    private static final Logger LOGGER = Logger
            .getLogger(SessionTrackerHttpSessionListener.class);
}

Create and Register MBean in ServletContextListener

Steps are:

  1. Create a class extending ServletContextListener. We create and register our MBean in contextInitialized
  2. Create MBeanServer
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
  3. Get the MBean
    WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
            SessionStatisticsMBean mBean = (SessionStatisticsMBean) context.getBean("sessionStatistics");
  4. Manufacture MBean name
    String mbeanObjectNameStr = "com.javarticles:name=" + mBean.getClass().getSimpleName();
  5. Get the ObjectName for the above created MBean name
    ObjectName.getInstance(mbeanObjectNameStr)
  6. Register MBean
    MBeanServer.registerMBean(mBean, mbeanObjectName)

We will load the spring context file in web.xml, you may want to ready my Spring Web Application Context Example to know more about it.

MBeanRegistrationServletContextListener:

package com.javarticles.servlet;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.javarticles.mbean.SessionStatisticsMBean;
import org.apache.log4j.Logger;

public class MBeanRegistrationServletContextListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {
        LOGGER.warn("In MBeanRegistrationServletContextListener");
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
        SessionStatisticsMBean mBean = (SessionStatisticsMBean) context.getBean("sessionStatistics");
        String mbeanObjectNameStr = "com.javarticles:name=" + mBean.getClass().getSimpleName();
        LOGGER.warn("MBean Name: " + mbeanObjectNameStr);
        ObjectName mbeanObjectName;
        try {
            mbeanObjectName = ObjectName.getInstance(mbeanObjectNameStr);
            server.registerMBean(mBean, mbeanObjectName);
        } catch (Throwable e) {   
            LOGGER.warn("MBean Registration Exception: " + e);
            e.printStackTrace();
        }  
    }
    
    public void contextDestroyed(ServletContextEvent event) {    
    }

    private static final Logger LOGGER = Logger.getLogger(MBeanRegistrationServletContextListener.class);
}

Add the beans in spring applicationContext.xml

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
	default-lazy-init="true">
	<context:annotation-config />
	<bean id="sessionTracker" class="com.javarticles.servlet.SessionTracker"
		scope="singleton"></bean>
	<bean id="sessionStatistics" class="com.javarticles.mbean.SessionStatistics" />
</beans>

Add the MBean Registration Listener in web.xml

web.xml:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>MBean Session Tracking Example</display-name>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath*:/applicationContext.xml,
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>	
	<listener>
		<listener-class>com.javarticles.servlet.SessionTrackerHttpSessionListener</listener-class>
	</listener>		
	<listener>
		<listener-class>com.javarticles.servlet.MBeanRegistrationServletContextListener</listener-class>
	</listener>	
</web-app>

Modify setenv.bat

If ${tomcat_home}/bin/setenv.bat doesn’t exist, create one and add the below:

setenv.bat:

set JMX_PARMS=-Dcom.sun.management.jmxremote ^
              -Dcom.sun.management.jmxremote.ssl=false ^
              -Dcom.sun.management.jmxremote.authenticate=false ^
              -Dcom.sun.management.jmxremote.port=9999
set JAVA_OPTS= %JAVA_OPTS% %JMX_PARMS%

Now we are all set to run the application and view JMX.

Run the application

Right click on the project. Click on ‘Maven install’. This will generate the war file. Copy the generated MBeanSessionTrackingExample.war file to the ${tomcat_home}/webapps.
Run ${tomcat_home}/startup.bat.

MBeanSessionTrackingExample

MBeanSessionTrackingExample

View MBean Active Sessions in JMX:

Connect to JMX using JConsole

Connect to JMX using JConsole

View Active Sessions in JMX

View Active Sessions in JMX

Download the source code

This was an example about creating and registering MBean service for tracking sessions. You can download the source code here: MBeanSessionTrackingExample.zip

Share.

Comments are closed.