JMX

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

Subjects

Specifications

Concepts

MXBean

An MXBean is a kind of MBean. For more details see

http://docs.oracle.com/javase/7/docs/api/javax/management/MXBean.html#mxbean-def

Open Type

http://docs.oracle.com/javase/7/docs/api/javax/management/openmbean/OpenType.html

The Platform MBean Server

The platform MBean server is an MBean server that is built into the JVM. It can be accessed and shared by all managed components that are running in that JVM. It can be retrieved with java.lang.management.ManagementFactory.getPlatformMBeanServer(). The platform MBean server was introduced in Java 5. javax.management.MBeanServerFactory can be used to create a different MBean server, or look up an already existing MBean server (that is not the platform server).

For a code example of how to look up the platform MBean server and how to register an arbitrary MBean to it, see

https://github.com/NovaOrdis/playground/blob/master/http/http-server/src/main/java/io/novaordis/playground/http/server/Main.java

Platform MXBeans

A platform managed object is an JMX MXBean deployed on a JVM's platform MBean server. Platform MXBeans expose monitoring and management capabilities for components of the Java platform. Platform MXBeans only use a set of basic data types, so a JMX management application and the platform MBeanServer can interoperate without requiring classes for MXBean specific data types. The data types being transmitted between the management client and the JMX server are open types and this allows interoperation across versions.

Common platform MXBeans:

Thread Monitoring and Management

ThreadMXBean Platform MBean

Memory Monitoring and Management

Memory Monitoring and Management Platform MBeans

O/S Level Runtime Metrics

OperatingSystemMXBean Platform MBean

Classloading Metrics

ClassLoadingMXBean Platform MBean

Other Monitoring and Management Components

Remote Access to a JMX Server

The JMX specification includes built-in support for accessing JMX servers remotely. Remote access details are described in the Section III of the specifications "JMX Remote API Specification".

An application that wishes to access a remote JMX server must create a session. The session allows for multiple, successive connections. The underlying mechanism that insures the client/server communication over the network is called a connector. A connector consists of a connector client and a connector server. The connector server is attached to the MBean server and listens for connection requests from clients. The connector client exposes essentially the same interface as the MBean server serviced by the connector. The connector client usually lives in a different JVM from the connector server, on a remote host. The connector client is connected to exactly one server. The connector client is represented by an object that implements JMXConnector.

The standard implementation required by the specification involves RMI (Remote Method Invocation). For an implementation to be spec-compliant, must expose an RMI-based remoting implementation. Optional protocols can be supported.

The JMX session does not have state on the server, each request is independent from the previous one.

The client obtains an object that implements MBeanServerConnection interface. The interface is similar to MBeanServer, which would be used if the client code was collocated with the MBean server in the same JVM. MBeanServerConnection is the parent of MBeanServer, which contains the same methods, with the exception of a small number of methods that only make sense for local access. This similarity allows to write client code that works identically when accessing a local server and a remote server. If the server operation throws an exception, the connector arranges for the client's invocation to get the same exception.

The connector server has an address used by the clients to establish connections to the server. The address is described by the JMXServiceURL class. Example:

service:jmx:jmxmp://example.com:9876

The address is provided to a JMXConnectorFactory instance, which creates the connection:

JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL);

Once connected, the JMXConnector instance can be used to get a MBeanServerConnection instance, which in turn can be used to interact with the remote JMX server as it would reside locally:

MBeanServerConnection jmxServerConnection = jmxConnector.getMBeanServerConnection();
Object attributeValue = jmxServerConnection.getAttribute(objectName, attributeName);

A practical example of how to programmatically access a remote WildFly JMX bus - or any remote JMX bus for that matter - is available here:

Accessing WildFly JMX Bus Remotely with novaordis-jmx

JMX Notifications

https://docs.oracle.com/javase/tutorial/jmx/notifs/index.html

The JMX API defines a mechanism that enables MBeans to generate notifications. Typical use cases are signaling a state change, a detected event or a problem.

To generate a notification, an MBean must implement NotificationEmitter or extend NotificationBroadcasterSupport.

To send a notification, a Notification instance or one of its subclasses must be created and passed to NotificationBroadcasterSupport.sendNotification().

To receive a notification, a listener can register with the emitter MBean directly, or with the MBean server.

Notification

https://docs.oracle.com/en/java/javase/13/docs/api/java.management/javax/management/Notification.html

The Notification class represent a notification emitted by an MBean.

Often used sub-classes: AttrributeChangeNotification.

Every notification has a source, which is the Object Name of the MBean that generated the notification. If the notification has been forwarded through the MBean Server, and the original source of the notification was a reference to the emitting MBean object, then the MBean server replaces it by the MBean's ObjectName. If the listener has registered directly with the MBean, this is either the object name of a direct reference to the MBean. It is strongly recommended that notification senders use the object name rather than a reference to the MBean object as the source.

Every notification has a sequence number, which can be used to order notifications coming from the same source. The sequence number can be zero, but preferably the number should be incremented for each notification emitted by a given MBean.

The notification instance is the passed to NotificationBroadcasterSupport.sendNotification().

NotificationEmitter

https://docs.oracle.com/en/java/javase/13/docs/api/java.management/javax/management/NotificationEmitter.html

NotificationEmitter is an interface implemented by MBean that emits notifications. It allows a listener to be registered with the MBean as a notification listener. When an MBean emits a notification, it considers each listener that has been added with addNotificationListener() and not subsequently removed with removeNotificationListener(), also considering filters.

If the method call of a filter or listener throws an Exception, then that exception should not prevent other listeners from being invoked. However, if the method call throws an Error, then it is recommended that processing of the notification stop at that point, and if it is possible to propagate the Error to the sender of the notification, this should be done.

Implementations of this interface and of NotificationBroadcaster should be careful about synchronization. In particular, it is not a good idea for an implementation to hold any locks while it is calling a listener. To deal with the possibility that the list of listeners might change while a notification is being dispatched, a good strategy is to use a CopyOnWriteArrayList for this list.

NotificationBroadcasterSupport

https://docs.oracle.com/en/java/javase/13/docs/api/java.management/javax/management/NotificationBroadcasterSupport.html

NotificationBroadcasterSupport implements NotificationEmitter interface.

By default, the notification dispatch model is synchronous. That is, when a thread calls sendNotification, the NotificationListener.handleNotification method of each listener is called within that thread. You can override this default by overriding handleNotification in a subclass, or by passing an Executor to the constructor.

NotificationListener

https://docs.oracle.com/en/java/javase/13/docs/api/java.management/javax/management/NotificationListener.html

JMX Notification Playground Example

https://github.com/ovidiuf/playground/tree/master/java/jmx/jmx-notifications