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:
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:
- Create a class extending
ServletContextListener
. We create and register ourMBean
incontextInitialized
- Create
MBeanServer
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- Get the
MBean
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); SessionStatisticsMBean mBean = (SessionStatisticsMBean) context.getBean("sessionStatistics");
- Manufacture
MBean
nameString mbeanObjectNameStr = "com.javarticles:name=" + mBean.getClass().getSimpleName();
- Get the
ObjectName
for the above created MBean nameObjectName.getInstance(mbeanObjectNameStr)
- 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
.
View MBean 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