30.1 JMX Modern
Expose runtime metrics and management operations via JMX for monitoring and operational control.
Creating an MBean
public interface AppStatsMXBean {
int getActiveRequests();
long getTotalRequestsProcessed();
void reset();
}
public class AppStats implements AppStatsMXBean {
private final AtomicInteger active = new AtomicInteger();
private final AtomicLong total = new AtomicLong();
public int getActiveRequests() { return active.get(); }
public long getTotalRequestsProcessed() { return total.get(); }
public void reset() { active.set(0); total.set(0); }
public void recordRequest() { active.incrementAndGet(); total.incrementAndGet(); }
public void completeRequest() { active.decrementAndGet(); }
}
Registering MBean
import java.lang.management.ManagementFactory;
import javax.management.*;
AppStats stats = new AppStats();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example:type=AppStats");
mbs.registerMBean(stats, name);
Remote JMX Access
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
MyApp
Connect with jconsole localhost:9010 or VisualVM.
Querying MBeans Programmatically
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example:type=AppStats");
int active = (Integer) mbs.getAttribute(name, "ActiveRequests");
Integration with Micrometer
For modern observability, consider Micrometer (exposes metrics to Prometheus, Grafana):
import io.micrometer.core.instrument.*;
MeterRegistry registry = new SimpleMeterRegistry();
Counter requests = registry.counter("app.requests.total");
Gauge.builder("app.requests.active", stats, AppStats::getActiveRequests)
.register(registry);
Guidance
- Use MBeans for operational metrics and admin operations.
- Secure remote JMX with authentication and SSL in production.
- Prefer modern metric libraries (Micrometer, OpenTelemetry) for cloud-native apps.
- Avoid exposing sensitive operations (restart, config changes) without authorization.