Here's a simple application that illustrates exposing internals using JMX.
Description
Application contains:
- Web deployment descriptor (e.g. WEB-INF/web.xml) that describes the application (optional)
- JSP views: home.jsp and WEB-INF/views/view.jsp
- A counter (e.g. example.jmx.web.MyCounter) that can increment, get current count, reset counter and reset to a specific value.
- A servlet (e.g. example.jmx.web.CounterServlet) that calls counter and forwards to a view (e.g. WEB-INF/views/view.jsp)
- A servlet listener (e.g. example.jmx.web.RegisterMBeansListener), that registers the MBean to JMX MBeanServer
- An MBean interface (e.g. example.jmx.mbean.CounterMBean) that defines JMX attributes and operations, e.g. name, resetCounter, getCurrentCount, getCurrentTime
- An MBean implementation (e.g. example.jmx.mbean.Counter) that implements MBean interface
Code Examples
example.jmx.web.MyCounter
No Format |
---|
package example.jmx.web;
import java.util.concurrent.atomic.AtomicInteger;
public class MyCounter {
private static AtomicInteger counter = new AtomicInteger(0);
public static int incrementAndGet() {
return counter.incrementAndGet();
}
public static int getCurrentCount() {
return counter.get();
}
public static void resetCounter() {
resetCounter(0);
}
public static void resetCounter(int start) {
counter = new AtomicInteger(start);
}
}
|
example.jmx.web.CounterServlet servlet
No Format |
---|
package example.jmx.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/count")
public class CounterServlet extends HttpServlet {
private static final long serialVersionUID = 886395215542306826L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("COUNT", MyCounter.incrementAndGet());
request.getRequestDispatcher("/WEB-INF/views/view.jsp").forward(request, response);
}
}
|
example.jmx.web.RegisterMBeansListener web listener
No Format |
---|
package example.jmx.web;
import java.lang.management.ManagementFactory;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import example.jmx.mbean.CounterMBean;
import example.jmx.mbean.Counter;
@WebListener
public class RegisterMBeansListener implements ServletContextListener {
private ObjectName objectName;
public RegisterMBeansListener() {
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Registering MBean...");
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
objectName = new ObjectName("JmxExampleApp:type=Counter");
final CounterMBean mbean = new Counter();
server.registerMBean(mbean, objectName);
System.out.println("MBean registered: " + objectName);
} catch (MalformedObjectNameException mone) {
mone.printStackTrace();
} catch (InstanceAlreadyExistsException iaee) {
iaee.printStackTrace();
} catch (MBeanRegistrationException mbre) {
mbre.printStackTrace();
} catch (NotCompliantMBeanException ncmbe) {
ncmbe.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Unregistering MBean...");
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
objectName = new ObjectName("JmxExampleApp:type=Counter");
server.unregisterMBean(objectName);
System.out.println("MBean unregistered: " + objectName);
} catch (MalformedObjectNameException mone) {
mone.printStackTrace();
} catch (MBeanRegistrationException mbre) {
mbre.printStackTrace();
} catch (InstanceNotFoundException infe) {
infe.printStackTrace();
}
}
}
|
example.jmx.mbean.CounterMBean interface
No Format |
---|
package example.jmx.mbean;
import java.util.Date;
public interface CounterMBean {
void resetCounter();
void resetCounter(int start);
int getCurrentCount();
Date getCurrentTime();
long getCurrentTimeMilis();
}
|
example.jmx.mbean.Counter implementation
No Format |
---|
package example.jmx.mbean;
import java.util.Date;
import example.jmx.web.MyCounter;
public class Counter implements CounterMBean {
private String name;
public Counter() {
this.name = "InitialName";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void resetCounter() {
MyCounter.resetCounter();
}
@Override
public void resetCounter(int start) {
MyCounter.resetCounter(start);
}
@Override
public int getCurrentCount() {
return MyCounter.getCurrentCount();
}
@Override
public Date getCurrentTime() {
return new Date();
}
@Override
public long getCurrentTimeMilis() {
return System.currentTimeMillis();
}
}
|
Download
Download JmxExample.war (with source code).