In this section, we will take a look at the three levels of the JMX architecture. The level closest to the application is called the instrumentation level. This level consists of four approaches for instrumenting application and system resources to be manageable (i.e., making them managed beans, or MBeans), as well as a model for sending and receiving notifications. JMX notifications are analogous to SNMP traps.
The middle level of the JMX architecture is called the agent level. This level contains a registry for handling manageable resources (the MBean server) as well as several agent services, which themselves are MBeans and thus are manageable. The combination of an instance of the MBean server, its registered MBeans, and any agent services in use within a single Java Virtual Machine ( JVM) is typically referred to as a JMX agent.
The third level of the JMX architecture is called the distributed services level. This level contains the middleware that connects JMX agents to applications that manage them (management applications). This middleware is broken into two categories: protocol adaptors and connectors. Through a protocol adaptor, an application such as a web browser can connect to one or more JMX agents and manage the MBeans that are registered within it (for example, via HTTP). As long as the management application can understand the objects contained in the protocol stream, it can manage the MBeans they represent; thus, protocol adaptors do not need to be written in Java. A connector follows the familiar proxy pattern and is made up of a client and server pair. The server half of the connector pair is normally collocated with the JMX agent it represents (although this is not required), while the client half runs in the JVM of the management application. Issues such as security and Java serialization are understood by both the client and server components of the connector.
The JMX architecture is depicted graphically in Figure 1-1.
Figure 1-1. The JMX architecture (note: protocol adaptors and connectors are not currently standardized)
This section covers the JMX instrumentation level and includes all MBean types, with examples. This is the level that should be of most concern to developers, because this level prepares resources to be manageable. Figure 1-1 shows the two areas of concern for the instrumentation level of the JMX architecture:
Application resources, such as a connection, a pool of connections, a printer connected to the network, or even the application itself
The instrumentation strategy that is used to instrument application resources
An application resource that is to be manageable through JMX must provide information about five of its features:
Attributes, which contain the state of the resource
Constructors, which are used by management applications and other JMX agents to create instances of the resource
Operations, which may be invoked by a management application or other JMX agent to cause the resource to perform some action
Parameters to constructors and operations
Notifications, which are emitted by the resource and sent via the JMX notification infrastructure to any interested agents
The combination of these five pieces of information—or metadata—about a resource’s features is known as its management interface. It is through this interface alone that a management application or other JMX agent may interact with a resource.
There are four instrumentation approaches defined by JMX that we can use to describe the management interface of a resource: standard, dynamic, model, and open. Before we discuss these approaches, let’s get a good working definition of an MBean, which is how we will refer to a managed resource from this point forward.
An
MBean
is an application or
system resource that has been instrumented to be manageable through
JMX. Instrumenting
a resource involves writing some
code. This code must follow four rules. First, the state of the
resource must be completely described through getters and
setters.[1] It is this requirement
that earns the instrumented resource the
“bean” moniker (from the same rule
for maintaining the state of a JavaBean). Second, the resource must
be instrumented (i.e., coded) according to one of the JMX MBean types
(standard, dynamic, model, or open). Following this requirement earns
the resource bean the “M” (for
manageable) part of the MBean name. Third, the MBean must provide at
least one public constructor. Finally, an MBean must be concrete
(i.e., not declared abstract
).
Suppose we have a resource called GenericResource
that has the following attributes:
-
Version
The version of the
GenericResource
-
ProcessingTime
The number of milliseconds of processing time that have been consumed by this instance of
GenericResource
-
NumberOfExceptions
The total number of exceptions that have been thrown by this instance of
GenericResource
in the course of its processing
The most straightforward implementation of the state of
GenericResource
would look like Example 1-1.
Example 1-1. Attributes of a candidate resource
public class GenericResource { // class details. . . // Version (read-only) private String _version = "1.0.1"; public String getVersion( ) { return _version; } // ProcessingTime (read-only) private long _processingTime; public long getProcessingTime( ) { return _processingTime; } // NumberOfExceptions (read-write) private short _numberOfExceptions; public short getNumberOfExceptions( ) { return _numberOfExceptions; } public void setNumberOfExceptions(short value) { _numberOfExceptions = value; } // other class details. . . }
This simple example demonstrates the fundamentals of instrumenting
the attributes of a resource according to the JavaBeans state
pattern. Each attribute is backed by a private member variable, so
that the part of the resource’s state represented by
that attribute cannot be accessed directly. All attributes in this
example are readable and have corresponding getters. Only the
NumberOfExceptions
attribute is writable, and it
provides a setter for that purpose.
Standard
MBeans are the simplest type of MBean
to code from scratch. All you need to do is define the MBean
interface as a Java interface and implement that interface on the
resource MBean. If we were to instrument
GenericResource
(from Example 1-1) as a standard MBean, we would define a Java
interface
that looks like this:
public interface GenericResourceMBean { // Version (read-only) public String getVersion( ); // ProcessingTime (read-only) public long getProcessingTime( ); // NumberOfExceptions (read-write) public short getNumberOfExceptions( ); public void setNumberOfExceptions(short value); }
We would then implement the interface on the
GenericResource
class:
public class GenericResource implements GenericResourceMBean { // etc. (from Example 1-1) }
The name assigned to this interface is very important: it must be the
name of the class that implements it, followed by
MBean
. In other words, for any resource class
XYZ
that is to be instrumented as a standard
MBean, a Java interface called XYZMBean
must be
defined, and it must be implemented by XYZ
. Note
that the MBean
suffix is
case-sensitive:
Mbean
is incorrect, as is mBean
or mbean
.
That is all the instrumentation code that must be written to make
GenericResource
capable of being managed! Of
course, this example is more simplistic than most resources we will
deal with in the real world, most of which will include one or more
management operations. Suppose we want to add a
method, reset(
), to reset the state of the
ProcessingTime
and
NumberOfExceptions
attributes. We would add this
method to the MBean interface, as shown in the following code.
public interface GenericResourceMBean {
// Version (read-only)
public String getVersion( );
// ProcessingTime (read-only)
public long getProcessingTime( );
// NumberOfExceptions (read-write)
public short getNumberOfExceptions( );
public void setNumberOfExceptions(short value);
// reset( ) operation
public void reset( );
}
Then we would implement
the
method on the GenericResource
class, as shown in
Example 1-2.
Example 1-2. The GenericResource managed bean
public class GenericResource { //class details. . . // Version (read-only) private String _version = "1.0.1"; public String getVersion( ) { return _version; } // ProcessingTime (read-only) private long _processingTime; public long getProcessingTime( ) { return _processingTime; } // NumberOfExceptions (read-write) private short _numberOfExceptions; public short getNumberOfExceptions( ) { return _numberOfExceptions; } public void setNumberOfExceptions(short value) { _numberOfExceptions = value; } public void reset( ) { _processingTime = 0; setNumberOfExceptions(0); } // other class details. . . }
The metadata required of every MBean is created automatically by the JMX infrastructure for standard MBeans. Before an MBean can be managed, it must be registered with a JMX agent (as described in the later section, Section 1.2.2.1). When a standard MBean is registered, it is inspected, and metadata placeholder classes are created and maintained by the JMX agent on behalf of the MBean. The Java reflection API is used to discover the constructor(s) on the MBean class, as well as other features. The attribute and operation metadata comes from the MBean interface and is verified by the JMX agent.
We will look at creating standard MBeans in detail in Chapter 2.
In the case of standard MBeans, the JMX agent creates the metadata that describes the features of a resource. In contrast, the developer himself must provide the metadata that describes a resource as a dynamic MBean. With the increased difficulty comes a gain in flexibility, however, because the instrumentation developer controls the creation of the metadata.
Dynamic MBeans implement a JMX interface called
DynamicMBean
that contains methods that allow the JMX agent to discover the
management interface of the resource at runtime. The
DyamicMBean
interface
is defined in Example 1-3.
Example 1-3. The DynamicMBean interface
package javax.management; public interface DynamicMBean { public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException; public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException; public AttributeList getAttributes(String[] attributes); public AttributeList setAttributes(AttributeList attributes); public Object invoke(String actionName, Object params[], String signature[]) throws MBeanException, ReflectionException; public MBeanInfo getMBeanInfo( ); }
There are six types of dynamic MBean metadata (one for each type of feature), shown in Figure 1-2 in Unified Modeling Language (UML) notation.
To describe the management interface of a resource as a dynamic
MBean, we create five fundamental pieces of metadata
that
correspond to its five fundamental features: constructors,
attributes, parameters, operations, and notifications. As we can see
from Figure 1-2, these five pieces of metadata are
described through instances of
MBeanConstructorInfo
,
MBeanAttributeInfo
,
MBeanParameterInfo
,
MBeanOperationInfo
, and
MBeanNotificationInfo
, respectively. The
parameters that are passed to a constructor or operation must also be
described through the JMX metadata class
MBeanParameterInfo
. Once all the metadata for an
MBean has been described through these classes, it is contained in a
single metadata class—MBeanInfo
—that
describes the MBean interface in its entirety. The JMX agent uses the
getMBeanInfo( ) method of the
DynamicMBean
interface to obtain this
MBeanInfo
object in order to discover the
management interface of a dynamic MBean.
Once the management interface has been discovered, the JMX agent uses
the other methods of DynamicMBean
to retrieve and
set attribute values and invoke operations on the MBean.
We will look at how to instrument a resource as a dynamic MBean in detail in Chapter 3.
Note
Consider instrumenting a resource as a dynamic MBean if:
You want to make a resource manageable but cannot change the source code of the resource itself (e.g., if it’s third-party software). Wrapping the resource class in a
DynamicMBean
implementation is ideal in this case.The management interface of the resource changes over time as the resource evolves as part of an application.
The management interface potentially changes each time the resource is instantiated.
The features
of a resource that is instrumented as a
model MBean are described through the use of metadata classes that
are specific to model MBeans. In addition, every model MBean must
implement the ModelMBean
interface,
which is defined in Example 1-4.
Example 1-4. The ModelMBean interface
public interface ModelMBean extends DynamicMBean, PersistentMBean, ModelMBeanNotificationBroadcaster { public void setModelMBeanInfo(ModelMBeanInfo inModelMBeanInfo) throws MBeanException, RuntimeOperationsException; public void setManagedResource(Object mr, String mr_type) throws MBeanException, RuntimeOperationsException, InstanceNotFoundException, InvalidTargetObjectTypeException; }
Notice that the ModelMBean
interface
extends the DynamicMBean
interface, which means
that a model MBean is a dynamic MBean. However, every JMX
implementation is required to ship an off-the-shelf implementation of
ModelMBean
called
RequiredModelMBean
. This presents the developer
with a key benefit: because a model MBean implementation already
exists, the work of writing one is already done. While the
instrumentation developer must still create the necessary metadata
classes (which we will discuss shortly), she does not have to
implement the ModelMBean
interface, which
significantly reduces development time.
Model MBeans introduce the concept of a descriptor, which is an additional set of metadata—specific to model MBeans—that allows the instrumentation developer to provide a much richer description of any MBean feature. Certain predefined descriptor values provide support for functionality such as the following:
Automatic attribute change notifications
Persistence of the MBean’s state at a specified interval
Logging of MBean state changes
Caching of an MBean feature (such as an attribute value or the return value of an operation) to improve performance for static (or relatively static) MBean features
Model MBean metadata extends dynamic MBean metadata, in that each model MBean metadata class extends its dynamic MBean counterpart. This relationship is shown in Figure 1-3.
ModelMBeanInfo
is an exception, as it is an
interface (implemented by a support class called
ModelMBeanInfoSupport
) that extends
MBeanInfo
. There is also no special model MBean
metadata class to describe parameters, because there is no difference
between a parameter to a dynamic MBean constructor or operation and a
parameter to a model MBean constructor or operation.
The relationships between the model MBean metadata classes are shown in Figure 1-4.
We will discuss how to instrument resources as model MBeans in detail in Chapter 4.
Note
Consider instrumenting a resource as a model MBean if:
The benefits of instrumenting as a dynamic MBean are required, but a significant per-MBean development time investment is undesirable.
A richer set of information about one or more of the features of the MBean (such as its attributes or operations) than can be described using dynamic MBeans is required.
Using the standard, dynamic, or model MBean instrumentation approaches allows us to describe MBean features (i.e., attributes, constructors, parameters, operations, and notifications) that are one of the following types:
A fundamental Java type, such as
boolean
,char
,long
, orfloat
(through its corresponding JDK wrapper—Boolean
,Char
,Long
, orFloat
, respectively)A string, as
java.lang.String
An array of fundamental types or strings
However, sometimes MBean attributes are more complex. Open MBeans were designed in an effort to make MBeans accessible to the widest possible range of management applications. Strictly speaking, you can use complex types on the management interface of standard, dynamic, and model MBeans. However, for a management application to correctly interpret the state of those types, the classes (i.e., the Java bytecode) representing those types must be available to the management application. The result is a coupling between the management application and the resources it manages, compromising the maintainability of the underlying managed resources. Open MBeans eliminate the need for management applications to understand the classes describing the complex types, deferring this intelligence instead to a predefined set of open MBean classes that can universally describe those types.
Every open MBean type
is
a concrete subclass of an abstract open MBean class called
OpenType
, and only subclasses of
OpenType
are allowed to describe features of open
MBeans. Three new types are defined that allow the instrumentation
developer to describe MBean features of arbitrary complexity:
At some point, the state of an MBean (or any object, for that matter)
must be resolved down to fundamental types, strings, or arrays.
However, open MBeans provide us with a mechanism to describe complex
links between types so that those links can be resolved indirectly.
For example, if we want to instrument a class A
as
an MBean, and A
in turn contains an instance of a
class B
, which contains an instance of a class
C
, we need some way to describe the links in the
inheritance graph between A
, B
,
and C
. It is for precisely this sort of arbitrary
complexity that open MBeans were designed.
Open MBeans differ from dynamic
and model MBeans in that there is no
special interface specifically for open MBeans that an open MBean
must implement. Instead, open MBeans must implement the
DynamicMBean
interface; what makes them
“open” is their use of special open
MBean metadata classes to describe their features and
their use of the OpenType
subclasses we discussed
earlier. For every open MBean feature (with the exception of
notifications), JMX defines an interface/support class pair that is
used to describe the feature. For example, to describe an open MBean
attribute, we use the OpenMBeanAttributeInfo
interface, which is implemented by a support class called
OpenMBeanAttributeInfoSupport
. Each support class,
in turn, extends its dynamic MBean counterpart. For example,
OpenMBeanAttributeInfoSupport
extends
MBeanAttributeInfo
. These relationships are shown
for all open MBean metadata classes in Figure 1-5.
Figure 1-5. UML diagram showing the inheritance relationships between the open MBean metadata interfaces, their support classes, and the dynamic MBean metadata classes
The OpenMBeanInfoSupport
class
contains the metadata for the MBean’s features
(which follows the pattern for dynamic and model MBeans). The
relationships between the open MBean metadata classes are shown in
Figure 1-6.
We will cover open MBeans in detail in Chapter 5.
Note
Consider instrumenting a resource as an open MBean if:
The benefits of dynamic instrumentation are required.
One or more MBean features cannot be completely described using one of the Java fundamental types, an array, or
java.lang.String
(in other words, if the feature is a complex data structure).
The JMX agent is designed so that management applications, or other components of the system, actively collect information about (i.e., query) the resources that are being managed by that agent. This works well when this information is refreshed at reasonable intervals and the application resources are stable. However, there are times when an immediate notification of a resource fault needs to be communicated to an interested party (such as a management application) outside the JMX agent. It is for this reason that the JMX notification model was designed. A JMX notification is similar to an SNMP trap and can be used to send critical, warning, or simply system or application information when certain events occur in the system.
At the core of the notification model are two principal participants:
A notification broadcaster, which emits notifications
A notification listener, which registers its interest in receiving certain notifications through the JMX agent infrastructure and receives those notifications when they are broadcast
A notification
broadcaster
is an object that implements the
NotificationBroadcaster
interface. Through this interface, a notification listener can
register or remove its interest in receiving notifications and can
query the notification broadcaster about what notifications it emits.
A notification
listener
is an object that implements the
NotificationListener
interface, which has a single method,
handleNotification( ), that it uses to process
all the notifications it receives.
To receive notifications, a notification listener must register its
interest in receiving the notifications emitted by the broadcaster
through the broadcaster’s implementation of
NotificationBroadcaster
. When the notification
listener does so, it passes references to itself, an optional
notification filter object, and an optional
handback object. The notification filter is an
object that implements the NotificationFilter
interface, and it is used by the broadcaster to determine which
notifications it will send to the listener. Only those notification
types that have been enabled in the filter will be sent to the
listener. The handback object is opaque to the broadcaster and has
meaning only to the listener, which uses the handback object in its
processing of the notification.
If no notification filter object is passed to the notification
broadcaster, the listener is in effect telling the broadcaster that
it wants to receive every notification the broadcaster emits.
However, if the notification listener wants to receive only a subset
of the notifications emitted by the broadcaster, it creates a
notification filter object and adds the notification types in which
it is interested through the
NotificationFilter
interface.
The relationships between the various components of the JMX notification model are shown in Figure 1-7.
Figure 1-7. UML diagram showing the relationships between the entities that participate in the JMX notification model
A listener can receive notifications from multiple broadcasters,
which in turn can send notifications to multiple listeners. In fact,
a single listener may register itself multiple times with the same
broadcaster, providing a different handback and/or notification
filter object each time. This allows the listener a great deal of
flexibility in how to process specific notifications. When the
broadcaster emits a notification, an instance of
Notification
is sent, along with the handback
object supplied by the listener. The notification supplied by the
broadcaster must include a
userData
object. The specification does
not say what this object must look like, which leaves the broadcaster
free to implement it as necessary. However, the listener must be
aware of this object (and what it looks like) in order to be able to
determine whether to ignore it or to process it.
Notifications are a fairly advanced topic. We will take a detailed look at how to create, send, filter, and receive notifications in Chapter 7.
Note
Consider using notifications if:
It is necessary to alert interested parties about the inner workings of a resource in real time.
The details of the inner workings of a resource are not of special significance (other than their business value, of course) until a particular set of circumstances occurs.
The agent level of the JMX architecture is made up of the MBean server and the JMX agent services. The MBean server has two purposes: it serves as a registry of MBeans and as a communications broker between MBeans and management applications (and other JMX agents). The JMX agent services provide additional functionality that is mandated by the JMX specification, such as scheduling and dynamic loading.
In this section, we will look at the MBean server and then at each of the required JMX agent services.
The MBean server is at the heart of the JMX agent. The MBean server
acts as a registry for MBeans, and the JMX agent accesses this
registry through the
MBeanServer
interface. To decouple the interaction between the agent and the
MBean instance, JMX introduces the concept of an object
name, which is implemented by a JMX class
called
ObjectName
. Before an MBean is registered, an
object name that uniquely identifies the MBean within the MBean
server’s internal registry must be created for the
MBean (this can be done by the agent who registers the MBean or by
the MBean itself ). If the object name is unique
within the MBean
server’s registry, a new entry containing the object
name and a reference to the MBean is created for that MBean. If the
object name used to register the MBean is not unique, the
registration attempt will fail because another MBean has already been
registered using that object name.
Once an MBean is registered, the object name assigned to the MBean is
used as the means of indirect communication between the agent and the
MBean. The MBean server acts as a broker for the request through its
implementation of the MBeanServer
interface. If
the agent wants to query an MBean for its attribute values, it
invokes the appropriate method on the MBeanServer
interface and passes the object name of the MBean whose values are to
be retrieved. The MBean server uses the object name as a lookup into
its registry, retrieves the reference to the MBean object, and makes
the invocation. The results of the invocation on the MBean object are
then returned to the agent. At no time does the agent have a direct
reference to the MBean.
A factory class,
MBeanServerFactory
,
is provided to obtain a reference to the MBean server. The use of a
factory decouples the MBeanServer
interface from
its implementation. MBeanServerFactory
provides
two static methods that allow us to create an MBean server:
- createMBeanServer( )
Creates an instance of the MBean server, holds that reference internally to the
MBeanServerFactory
, and returns the reference to the caller. TheMBeanServerFactory
internal reference to the MBean server that was created prevents it from being subject to garbage collection.- newMBeanServer( )
Creates an instance of the MBean server and returns that reference to the caller. No internal reference is maintained inside the
MBeanServerFactory
. When there are no more live references to the MBean server, it is eligible for garbage collection.
We will take a detailed look at the MBean server and how to create and use it in Chapter 6.
The M-Let (short for management applet) service is a JMX agent service that allows you to load MBeans from anywhere on the network, including a local machine. The M-Let service is itself an MBean and can be managed as such. Information about MBeans to be loaded is contained in a text file called an M-Let file. This file has an XML-like syntax, but the syntax does not constitute well-formed XML. Using special tags called M-Let tags, we can encode enough information in the M-Let file that the M-Let service can locate, download the bytecode for, and instantiate MBeans.
Here’s how the M-Let service works. First, we instantiate the M-Let service’s MBean class and register it with the MBean server. Next, through a method call, we provide the M-Let service with the URL to the M-Let file, which retrieves the M-Let file and reads its contents. The M-Let service then instantiates all of the MBeans specified in the M-Let file.
We can also use the M-Let service, in conjunction with the MBean server, to load MBeans without the use of an M-Let file. We simply add the file’s URL to the M-Let service’s list of URLs that it will search when attempting to load MBeans, then call a method on the MBean server and pass the M-Let service’s object name (which we created when we registered the M-Let service MBean with the MBean server) as the MBean class loader.
We will take a detailed look at how to use the M-Let service in Chapter 9.
A monitor observes the attribute value of an MBean, called the observed object, at specific intervals, called the granularity period. From this observation the monitor calculates a value called the derived gauge, which is either the value of the attribute or the difference in the value of the attribute (for numerical attributes only, of course) between the most recent two observations. When the derived gauge satisfies a certain condition —which varies depending on the type of monitor in use—a notification of a type that is specific to that monitor is sent to all registered notification listeners. The monitoring service can also send error notifications if a problem arises.
The JMX specification mandates that three types of monitors be provided with every compliant implementation:
- Counter monitors
Observe a continually increasing, nonnegative, integer MBean attribute (of type
byte
,short
,int
,long
, or the corresponding JDK wrapper class) and send a notification when the derived gauge exceeds a certain value, known as the threshold- Gauge monitors
Observe an arbitrarily changing numeric value (of type
short
,int
,long
,float
,double
, or the corresponding JDK wrapper type) and send a notification when the derived gauge exceeds an upper limit (known as the high threshold ) or drops below a lower limit (known as the low threshold )Note
Consider using a gauge monitor to monitor an attribute:
Whose type is numeric
Whose value can increase or decrease at any time
Whose value is constrained between a lower threshold and an upper threshold
To send a notification if the attribute’s value exceeds the upper threshold or drops below the lower threshold
- String monitors
Observe a string attribute of an MBean and send a notification when the derived gauge either matches or differs from a predefined string value
We will discuss the monitoring services in Chapter 9.
The timer service is a special-purpose notification broadcaster designed to send notifications at specific time intervals, starting at a particular date and time. Like the other agent services, the timer service is required for all compliant JMX implementations. The timer service is itself an MBean, so it can be managed (although it does not have to be registered with the MBean server to be used). There are two primary uses of the timer service:
To send a single notification to all listeners interested in that notification type
To send multiple notifications that repeat at specific intervals for a set number of times, or indefinitely
The timer service is capable of sending any number of different notifications at different intervals. Each notification that is to be sent by the timer service is given a notification type, defined by the agent that instructs the timer service to send that notification. In other words, the timer service does not send a predefined set of notification types. Instead, the agent tells the timer service what notification types to send and provides other information that specifies when to start sending the notification, how many times the notification is to repeat, and the amount of time that is to elapse between each notification (for repeating notifications only).
We will discuss the timer service in Chapter 10.
The relation service provides a facility to associate MBeans with each other and must be implemented by every compliant JMX implementation. You use the metadata classes provided by the relation service to describe n-ary relationships between registered MBeans as dictated by your application policies. You then use the relation service to maintain the consistency of those relationships so that those application policies are followed. The relation service formalizes the rules for describing and maintaining relationships between MBeans, resulting in two major benefits:
The relationship between MBeans is formalized into a well-defined type that can be checked by the relation service in a way similar to how Java types are checked.
The number of MBeans that may participate in one role of a relationship (i.e., its cardinality) can be enforced by the relation service.
To use the relation service effectively, you need to understand a few key concepts:
- Roles
A role describes the MBean objects that perform a particular role.
- Role information
Role information provides metadata about a role, such as the role name and the minimum and maximum number of MBeans that are allowed to perform that role.
- Relation types
Relation type information is also metadata, but it describes the relationship between one or more role information objects. The
RelationType
interface provides information about the relation type, such as the name of the relation type and the various roles that make up that type.- Relations
A relation is an instance of a relation type. It is critical to the correct functioning of the relation service that all relation types remain consistent. In other words, the metadata describing the relationship between MBeans (i.e., the relation type) provides the constraints on the relation that allow the relation service to be used to ensure that the relation remains consistent at all times. Once a relation has been instantiated, it must remain consistent, or the relation service will throw an exception.
We will discuss the relation service in Chapter 11.
In this section, we will take a look at the distributed services level of the JMX architecture, which is unspecified at the time of this writing. However, significant work has already been done to create the standard. Specifically, the RMI connector client and server will be standardized soon as part of JSR 160. This will provide a standard for all subsequent connectors to follow. The protocol adaptor side will remain unspecified for a while, although significant work has been done in this area as well. The main reason to standardize on the RMI connector is to leverage existing work in the JDK regarding issues such as security, connection pools, and security.
In this section, we will briefly look at connectors and adaptors. Then we will see what is coming soon with the distributed services level of JMX architecture regarding JSR 160.
As mentioned earlier, there is a clear difference between a connector and an adaptor. A connector consists of two parts: a client proxy and a server stub. Connectors are intended to do the following:
Hide the specific details regarding the network location of the resources in an application under management (i.e., provide location transparency).
Present a consistent view (via an interface) of an MBean server that is located in a different process space than the local MBean server.
Shielding the proxy client from the details of how to send and receive messages to the server stub (and vice versa) makes it unnecessary for any particular instance of the MBean server to know its location on the network, which means that this can be left as a configuration detail.
An adaptor is different from a connector in that there is no client
component. The adaptor runs at the server location and renders the
MBean server state in a form that is appropriate for, and can be
recognized by, the client. An example of this is the
HtmlAdaptorServer
that ships as part of the JMX RI
(note that it is not officially part of the RI, as the distributed
services level has yet to be fully specified). It is unlikely that
any adaptors will be mandated by the JMX specification in the near
future. However, given the momentum that the adoption of JMX is
enjoying, several adaptor implementations should soon be available.
We will not cover the specifics of the RMI connector or of any
particular adaptor here, as those details are unspecified at the
moment. However, you’ll find several contributions
to investigate in the contrib
package of the JMX
RI.
The next release of JMX—which is set to coincide with Release 1.4 of the Java 2 Enterprise Edition ( J2EE) platform (at the time of this writing, early 2003)—will provide standards for the distributed services level of the JMX architecture. The main standardization you can expect from JMX 1.5 is the RMI connector, which provides a mechanism for handling remote agents.
The RMI connector is based on the concept of a remote MBean server, which is fundamental to the model used by JMX connectors as part of the distributed services architecture. This concept is illustrated in Figure 1-8.
There are two components to a connector: the client and the server. Between the two connector components is the connection itself. In JMX 1.5, the only specified connection will be RMI. However, the remote MBean server concept can apply to other protocols, such as HTTP and SOAP. The connector server listens for incoming connections from connector clients. When a connector client attempts to establish a connection, the connector server handles the details of creating the connection. After the connection has been established, all of the MBeans registered in the remote MBean server can be accessed; that is, their attributes can be retrieved and set (depending on the read/write status of each particular attribute, of course) and their operations can be invoked.
This also holds true for notifications sent from MBeans in the remote agent. Notifications emitted by remote broadcasters will be sent through the RMI connection to their intended listeners. The details of how the notification is sent over the connection are unknown to both the broadcaster and the listener.
[1] This is not strictly true for the dynamic, model, and open MBean types. However, I highly recommend strict adherence to this pattern.
Get Java Management Extensions now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.