The JMX specification provides a very rich, generic notification mechanism. In this chapter, we will look at the JMX notification model, which serves as the foundation for notifications. Then we will look at what a notification is and examples of different notification types. We will then take a detailed look at the different classes and interfaces that JMX provides to underpin the JMX notification model, including:
Notification
This class represents the contents of a single notification and is sent by the broadcaster to the listener (or receiver) of the notification.
NotificationFilter
This interface,
when
implemented, gives the notification listener a way to tell the JMX
notification infrastructure that it is interested in only a subset of
the potential notifications sent by the broadcaster. The JMX RI
provides a class called NotificationFilterSupport
that can be used as an off-the-shelf notification filter.
NotificationBroadcaster
This interface
must
be implemented by all notification broadcasters. In addition, the RI
provides an implementation of this interface called
NotificationBroadcasterSupport
that can be used as
an off-the-shelf notification broadcaster.
NotificationListener
This interface must be implemented by all receivers of JMX notifications.
A notification in the context of JMX is a unit of
information sent by a broadcaster through the JMX infrastructure to a
listener, which interprets and processes the notification. A
notification contains, at a minimum, the notification type (a unique
string that identifies the notification), an
Object
reference to the notification broadcaster,
and a sequence number (an integer value that uniquely identifies a
particular occurrence of a specific notification type). Other
optional information that can be sent in a notification includes a
time stamp, a human-readable text message, and a reference to an
object that permits additional processing of the notification to
occur. Of course, the type (and meaning) of this object must be
agreed upon by the listener and the implementation of the
broadcaster.
A
notification
broadcaster implements a special JMX interface called
NotificationBroadcaster
that allows any number of
notification listeners to register an interest in receiving any or
all of the notifications emitted by the broadcaster. Messages are
sent to the listener through the JMX infrastructure using a callback
mechanism. A notification listener implements a JMX
interface called NotificationListener
that allows
the JMX infrastructure to deliver a notification on a callback method
of the NotificationListener
interface. The
listener may, at its discretion, choose to receive only a subset of
the possible notifications emitted by the broadcaster by providing a
notification filter. A notification
filter must implement a JMX interface called
NotificationFilter
.
JMX notification filtering is performed before of notifications are broadcast, so it is the broadcaster’s responsibility to determine (by using the filter) whether a notification is to be sent to a listener. When the broadcaster is about to emit a particular type of notification to a listener, it checks the filter to see whether the notification is one the listener wants to receive. If the filter tells the broadcaster that the listener is interested in that notification, the broadcaster sends the notification to the listener. Otherwise, the broadcaster does not send the notification, saving the listener the trouble of receiving and ignoring notifications in which it is not interested. If no filter is present, the broadcaster sends all notifications to the listener.
In addition to a notification filter, a listener may optionally pass a reference to an object called a handback , an object that will be handed back to the listener when notifications are sent to that listener. This object is opaque (i.e., its contents are unknown) to the broadcaster, which simply stores the object away until a notification is broadcast to the listener, at which time the object is passed unchanged to the listener. The JMX specification does not constrain what this object must be, only implying that it is used to provide contextual information that the listener creates upon registering its interest in receiving a notification, then exploits upon receiving the notification. Notification listener developers can thus implement the handback object as their needs dictate. We will look at some examples of handback objects later in this chapter.
The relationships between the various components of the JMX notification model are shown in Figure 7-1.
Figure 7-1. UML diagram showing the relationships between the various components of the JMX notification model
When a listener wants to receive notifications, it invokes a method
called addNotificationListener(
)
on the broadcaster, passing it a reference
to itself, a reference to the filter it wants to use, and a handback
object reference (both the filter and handback references may be
null
). The same listener can register its interest
in receiving MBean notifications from a particular broadcaster more
than once, passing a different handback object to
addNotificationListener( ) each time. The
notification broadcaster keeps a table of listener/filter/handback
object triplets to ensure that it passes the correct handback object
upon broadcasting each notification to the listener. The listener may
also pass a different filter for each handback object, allowing even
more flexibility in providing contextual information when processing
notifications. As Figure 7-1 also shows, each
Notification
object may only be associated with
one broadcaster (the source
) and one user-defined
object (userData
).
The key to processing notifications lies in the notification type. As we discussed in Chapter 3, a notification type is a string that may be of the form:
vendor
[.application
][.component
][.eventGroup
].event
where vendor
is the name of your company,
application
is the name of the application
(optional), component
is the name of the
component (usually the name of the MBean, also optional),
eventGroup
is the name of the group to
which the event belongs (optional), and
event
is the name of the event
notification. For example, the notification
"acme.OrderEntry.billing.responseTime.slow"
is
defined by the company acme for the Order Entry
system’s billing component for a group of events
related to response time to indicate that response time is slow. How
this notification is handled is up to the listener. Notice, however,
that only vendor
and
event
are required, so we could have
simply defined the event as
"acme.responseTimeSlow"
.
While the above pattern is recommended by the JMX specification, this convention for defining notifications is not enforced in the RI. However, it is a good idea to follow this convention to ensure as much consistency as possible between applications from various vendors.
Why is the notification type so important? The notification type serves as the “handle” for the notification and is used in processing it. In addition, the listener is capable of processing several different notification types, and it uses the notification type as a first step in cracking into a notification to process it further.
Now that we’ve been introduced to the players and their respective roles in the JMX notification model, let’s take a closer look at the classes provided by the JMX RI that make it all happen.