adam bien's blog

@Singleton - The Simplest Possible JMX MXBean 📎

You will need an interface:
public interface MonitoringResourceMXBean {
    Map getDiagnostics();
}
...and and a @Singleton implementation:
@Singleton
@Startup
public class MonitoringResource implements MonitoringResourceMXBean {


    private ConcurrentHashMap diagnostics = new ConcurrentHashMap();

    private MBeanServer platformMBeanServer;
    private ObjectName objectName = null;


    @PostConstruct
    public void registerInJMX() {
        this.exceptionCount = new AtomicLong();
        try {
            objectName = new ObjectName("XRayMonitoring:type=" + this.getClass().getName());
            platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
            platformMBeanServer.registerMBean(this, objectName);
        } catch (Exception e) {
            throw new IllegalStateException("Problem during registration of Monitoring into JMX:" + e);
        }
    }
//bookkeeping methods omitted

    @Override
    public Map getDiagnostics() {
        return diagnostics;
    }

    @PreDestroy
    public void unregisterFromJMX() {
        try {
            platformMBeanServer.unregisterMBean(this.objectName);
        } catch (Exception e) {
            throw new IllegalStateException("Problem during unregistration of Monitoring into JMX:" + e);
        }
    }
}

With the MXBean naming convention the contents of the exposed java.util.Map will be nicely rendered in JConsole / visualVM as a table. Exposed accessors will appear as fields and remaining methods as buttons...

A Singleton is a perfect MXBean, because:
  1. Its automatic (@Startup) registration and unregistration at the MBeanServer. This solves the redeployment issues like multiple registrations of the same bean
  2. Singleton is able to cache diagnostic state and expose it on demand
  3. Singleton can be injected to other components like Interceptors
  4. A Singleton can also receive events
  5. A Singleton can be exposed as a REST-resource

@Singleton is also a perfect cache (facade)...

The code above is an excerpt from the X-ray code. In X-ray JMX almost entirely replaced logging. Diagnostic events are fired from various components and aggregated in the MonitoringResource singleton. The MonitoringResource EJB is also exposed with JAX-RS what makes the statistics also accessible via HTTP. [See also page 77, section "Who Reads Logs—Or How to Monitor Your Application" in Real World Java EE Night Hacks--Dissecting the Business Tier. You will find the entire code in the GIT repo]