Chapter 6. MBean Server

In this chapter, you will look at the MBean server classes in detail and cover the relevant methods of the interfaces and classes required to interact with the MBean server. You will look at the invocations and how they are handled in the MBean server, go through the methods of the MBeanServer interface, and cover the MBeanServerFactory class, MBeanRegistration interface, ObjectName class, and the MBeanServerDelegateMBean. At the end of this chapter, you will also learn how to build queries for MBeans.

The MBean server is a core component of the JMX agent layer. As the examples in the previous chapters have shown, the MBean server is responsible for decoupling the management applications from the managed resources. The MBean server achieves this by abstracting the managed resources behind a management interface and object name references.

The MBean server acts as a registry to the MBeans and contains the metadata describing the management interface of each MBean. MBeans are always accessed through the methods of the MBeanServer interface. The MBeanServer interface declares the methods for setting and getting the management attributes and invoking the management operations of an MBean. MBeans are always referenced via their object names instead of direct references to the resources themselves. This is essential for isolating the management applications from the resources and is the main responsibility of the MBean server.

In addition, you have seen that the MBean type, whether a Standard or a Dynamic MBean, is abstracted from the management tools. A management application using the services of an MBean server is not aware of the managed resource is implemented. Regardless of the MBean type, the MBean server exposes the same metadata structures to the management application. If Standard MBeans are used, the agent uses the Java introspection to build the metadata based on the method naming conventions discussed in Chapter 3, “Standard MBeans.” In the case of the Dynamic MBean, the agent discovers the management interface by invoking the getMBeanInfo() method of the DynamicMBean interface.

Invocation Mechanism

In the previous chapters, you invoked methods of managed resources through an HTTP protocol adaptor. You also programmatically manipulated the MBeans via the MBeanServer interface. When using the HTTP protocol adaptors, you either had to choose the MBean by selecting it from a list of object names, or by entering a query on the Web page, which returned a list of matching object names representing the MBeans. With programmatic invocations, you created an ObjectName instance and used it with each invocation of management operation.

The MBeanServer interface declares the methods required to manipulate MBeans. When the MBean registers itself to the MBean server, the server stores a Java object reference of the resource and maps it to the ObjectName reference. This layer of indirection guarantees that the management applications do not rely on the interface of the managed resource directly, but only on the management interface exposed by the agent. For the isolation of application and resource to work, all communication between the two must travel through the JMX agent. This is guaranteed as long as the ObjectName references are the only way for the client to access the MBean. The MBean server will delegate the invocation to the correct resource instance based on its internal mapping of object names to resource references.

Note

The management applications never directly reference the managed resources. All communication between the application and the managed resource must go through the JMX agent layer.

If you recall the DynamicMBean interface from Chapter 4, “Dynamic MBeans,” you may remember that the interface mainly consists of almost exact matches of the invoke(), setAttribute(), and getAttribute() methods of the MBeanServer interface. The difference between the method declarations is the ObjectName argument the MBean server requires the clients to include in the invocation.

When the invocation gets to the MBean server, it looks up the resource reference for the corresponding ObjectName and delegates the call from the server to the MBean's DynamicMBean interface. The methods of the DynamicMBean interface match those in the MBeanServer with the exception of ObjectName reference, which is not required. If the MBean server needs to invoke methods of a Standard MBean, the server looks up the correct resource reference and uses introspection to find and invoke the corresponding method on the Standard MBean.

The Figure 6.1 illustrates this sequence of calls from the client to the MBean server.

The management application accesses the MBeans using ObjectName reference.

Figure 6.1. The management application accesses the MBeans using ObjectName reference.

Because the Standard MBeans require introspection to be used, they do not perform as well as Dynamic MBeans under a heavy load of invocations. Usually, however, the performance difference between Standard and Dynamic MBeans is not relevant to the managed component.

Also notice that when notifications are being broadcast from MBeans, it is the MBean server's responsibility to map the Notification instance's source field from a direct Java object reference to an ObjectName reference. This ensures that the receiver of the notification will also reference the source via its object name instead of directly.

ObjectName class

The ObjectName class represents a reference to the MBean component in the agent. An ObjectName is unique within an MBean server and is used by the management applications and other MBeans to invoke operations and manipulate MBean components registered to the server.

The ObjectName consists of two parts—the domain name and an unordered list of property-value pairs. The string representation of an ObjectName must follow the following syntax:

[DomainName]:property=value[,property=value]*

The DomainName part of the ObjectName is optional. If no domain name is specified, the agent assigns a default domain name to the object. You can define the default domain name by passing it as an argument to the createMBeanServer() or newMBeanServer() method in the MBeanServerFactory class. You can retrieve the default domain name from the MBean server via the getDefaultDomain() method call.

The domain name is case sensitive. Its structure and semantic is application dependent. However, the domain name string is not allowed to use any of the special characters that are used as object name separators or wild cards by the JMX implementation. Such characters include the colon (:), comma (,), equals sign (=), asterisk (*), and question mark (?). The latter two are used to compose patterns of ObjectName instances.

The property list part of the ObjectName string representation can contain any number of property-value pairs. Unique properties can be freely assigned and do not have to match the management attributes exposed by the MBean in its management interface. The property list part must contain at least one property-value pair. If more than one property-value pair is used, the order is not significant.

The canonical name of an MBean is a string representation of the ObjectName instance where the properties are sorted in a lexical order.

The following are some examples of properly formed object names:

Connector:transport=RMI
:name=ExportService,type=Service
Connector:*

MBeanServerFactory Class

The MBeanServerFactory class allows you to create instances of MBeanServer implementations. The MBeanServerFactory class consists of six methods:

public static MBeanServer createMBeanServer();
public static MBeanServer createMBeanServer(String domain);
public static MBeanServer newMBeanServer();
public static MBeanServer newMBeanServer(String domain);
public static ArrayList findMBeanServer(String AgentId);
public static void releaseMBeanServer(MBeanServer mbeanServer);

You have already seen the createMBeanServer() method used in several examples. This method creates an MBean server implementation and returns it to the caller. It also adds the created MBean server reference to an internal data structure that allows you to find the server instance later via the findMBeanServer() method call.

The createMBeanServer() method uses a default domain name specified by the JMX implementation for MBeans that do not include a domain name as part of their registration. It is possible to override the default domain name with an overloaded version of the createMBeanServer(), which allows you to specify your own default domain name.

The newMBeanServer() method works much the same as the createMBeanServer() method. The difference is that the server instances created with the newMBeanServer() call are not stored for later retrieval. Therefore, the instances cannot be found by the findMBeanServer() method call. Also, these server instances may be garbage collected as soon as no live references are kept to them.

The releaseMBeanServer() method allows you to remove any internal references kept by the JMX implementation for the given MBeanServer instance. This allows the MBean server to be garbage collected by a JVM if no other references to it exist.

Finally, the findMBeanServer() method is used to find any existing and registered MBeanServer instances in the JVM. You can either search for all instances by providing a null reference as parameter to the method call, or you can find a specific instance of an MBeanServer by providing an AgentID as parameter to the method call. The AgentID identifier can be retrieved from all MBean server instances via the MBeanServerDelegateMBean. A MBeanServerDelegateMBean is automatically registered with each compliant MBean server instance. A more detailed look at this MBean and what other information can be retrieved via its management interface will be discussed a little later in the “MbeanServerDelegate” section called.

Those were all the methods of the MBeanServerFactory class. Using this factory class, you can create, find, and release MBeanServer instances. Next, take a look at what the MBeanServer interface itself holds in store for you.

MBeanServer Interface

As mentioned at the beginning of the chapter, the MBean server is the core component of the JMX agent layer. The management applications interact with the MBean server through the MBeanServer interface that all the MBean server instances implement. Among the responsibilities of the MBean server are the registration and unregistration of the MBean components and access to management operations and attributes of an MBean. In addition, the MBean server provides the means for decoupling the management applications from the resources, as was discussed earlier. Also, the management operation invocations in the MBean server are detyped through the invoke() method. Because the management clients do not rely on statically typed Java interfaces to invoke the management operations, you can freely let the interfaces evolve without having to change the existing clients. This can become helpful where the maintenance of components is concerned.

You have already used many of the methods in the MBeanServer interface. Next you will go through the relevant methods of the interface to refresh what you have already learned and fill in some new details. Remember that all the communication between the management applications and the MBeans go through this interface, so you should become familiar with it.

invoke()

The invoke() method is interesting in that it plays a vital part in decoupling the management clients from the managed resources. As discussed in Chapter 2, “Architecture,” and earlier in this chapter, the decoupling of the management applications from the resource is one of the key design points of the JMX-based architecture. In the signature of the invoke() method, this design becomes evident to the application developer. You will notice that the MBeans are always referenced via the ObjectName reference—never directly.

The complete signature of the invoke() method of the MBeanServer interface is as follows:

public Object invoke(ObjectName name, String operationName,
                     Object[] params, String[] signature)
              throws InstanceNotFoundException, MBeanException,
                     ReflectionException

The indirection provided by the object name references allows you to change the component implementation without affecting the existing clients. It is not necessary to detach the client-server communication while components are being updated. If the component is momentarily unavailable, the MBean server could suspend the invocation or redirect it to another MBean. If the MBeans are synchronizing their state, through a database for example, they can implement a simple failover functionality this way.

Another significant point to notice in the invoke() method declaration is how the management operation invocation is detyped and does not rely on a statically typed Java interface that the resource implements. All operation invocations are carried through the invoke() method, which contains the name and signature of the operation you want to invoke. This means that in addition to switching the implementation “behind the scenes” from the client, it is possible for the management interface of a component to evolve—to add a new management attributes and operations. Due to the detyped invocation, this evolution of the component's management interface can occur without affecting existing clients. A new management application can take advantage of the recently added management operation, but the existing clients will continue to work as long as the management interface for the operations they require does not change.

The exception types included in the invoke() method declaration are as follows:

  • InstanceNotFoundExceptionThrown when the MBean server cannot find a registered MBean for the given object name

  • MbeanExceptionCan be used by the managed resource to wrap application-specific exceptions

  • ReflectionExceptionThrown when the actual invocation operation from the MBean server to the managed resource fails

The invoke() method returns an object reference that represents the return value of the management operation. Notice that implicit type conversion between primary return types of a Standard MBean interface to corresponding object types is performed by the agent.

createMBean

The createMBean() method is overloaded with four different versions in the MBeanServer interface. The different versions of the createMBean() method allow you to create an MBean instance in the agent with a given ObjectName reference, optionally with an explicit constructor signature if the default constructor cannot be used, and an explicit class loader.

The following are declarations of the createMBean() methods in the MBeanServer interface. The exceptions have been left out for the sake of brevity.

public ObjectInstance createMBean(String className,
                                  ObjectName name);

public ObjectInstance createMBean(String className,
                                  ObjectName name,
                                  Object[] params,
                                  String[] signature);
public ObjectInstance createMBean(String className,
                                  ObjectName name,
                                  ObjectName loaderName);

public ObjectInstance createMBean(String className,
                                  ObjectName name,
                                  ObjectName loaderName,
                                  Object[] params,
                                  String[] signature);

The first overloaded version of the createMBean() method instantiates the given class using the default constructor and attempts to register the object as an MBean to the server. If successful, it binds the MBean to a given ObjectName reference.

The second overloaded version of the createMBean() method allows you to define the signature of the constructor that the agent uses to instantiate the MBean component. You can specify the constructor by providing an array of objects that contain the values of the constructor call and an array of String objects that contain the fully qualified classnames of the value objects. The agent can determine the signature of the constructor from the String array with classnames and pass the objects as values to the instantiation call.

The last two overloaded versions of the createMBean() method are identical to the first two with an additional ObjectName reference to a class loader. The loaderName parameter can be used to explicitly define a class loader that should be used to load the MBean component.

The createMBean() method call declares five common exception types to indicate error conditions in either the MBean object initialization or in the MBean registration phase. The ReflectionException can be thrown if the class cannot be loaded with the default class loader or with the explicitly declared class loader. A ReflectionException is also thrown if there were any other exceptions thrown while trying to invoke the MBean's constructor, for example, if the MBean did not declare a public, no-args constructor. You can retrieve the original exception via the getTargetException() method of the ReflectionException class.

The InstanceAlreadyExistsException can be thrown from the createMBean() method call if the ObjectName reference is already in use and mapped to another MBean component. The MBeanRegistrationException can be thrown if the MBean component implements the MBeanRegistration interface and throws an exception in its preRegister() method. You will see the details of the MBeanRegistration interface in the section of the same name later in this chapter.

Also, the MBeanRegistrationException class exposes the original exception class via the getTargetException() method.

The MBeanException wraps any application exceptions that can be thrown from the implementation of the MBean's constructor. The NotCompliantMBeanException is thrown if the classname supplied is not a compliant MBean. This can occur if the agent is unable to find the corresponding Standard MBean interface or the DynamicMBean interface in the class hierarchy.

In addition to these exceptions described, the InstanceNotFoundException object can be thrown by the two createMBean() methods that require an ObjectName reference to the class loader to load the MBean component. In case the ObjectName reference is not found in the agent, the InstanceNotFoundException can be thrown.

Notice that the functionality of the createMBean() invocation is roughly the equivalent of calling the instantiate() and then registerMBean() methods on the server. However, because the createMBean() method does not expose or require direct references to resource objects but works with the ObjectName references, it is better suited for management applications trying to create and register new MBean components remotely. You will see the details of both the instantiate() and registerMBean() methods a bit later in this chapter in the “RegisterMBean and UnregisterMBean section.

addNotificationListener and removeNotificationListener

Recall from Chapter 3 the discussion of the JMX notification mechanism. It requires that all MBeans wanting to broadcast management notifications must implement the NotificationBroadcaster interface. This interface includes the addNotificationListener() and removeNotificationListener() methods that are almost identical to the ones declared in the MBeanServer interface. Again, the difference is in the MBeanServer interface where the ObjectName reference is required as a first argument for both method implementations. As with the invoke() method, the addNotificationListener() and removeNotificationListener() methods look up the corresponding MBean reference based on the supplied ObjectName and delegate the method invocation to the registered MBean.

public void addNotificationListener(ObjectName name,
                                    NotificationListener listener,
                                    NotificationFilter filter,
                                    Object handback)
                       throws InstanceNotFoundException;

public void addNotificationListener(ObjectName name,
                                    ObjectName listener,
                                    NotificationFilter filter,
                                    Object handback)
                       throws InstanceNotFoundException;
public void removeNotificationListener(
                                    ObjectName name,
                                    NotificationListener listener)
                       throws InstanceNotFoundException,
                              ListenerNotFoundException;

public void removeNotificationListener(
                                    ObjectName name,
                                    ObjectName listener)
                       throws InstanceNotFoundException,
                              ListenerNotFoundException;

The second variation of both the addNotificationListener() and removeNotificationListener() methods allows you to register another MBean directly as a listener to the broadcaster MBean. This will become especially useful when dealing with remote notifications.

getAttribute and setAttribute

The getAttribute() and setAttribute()methods also have their corresponding equivalents in the DynamicMBean interface. In the case of the Standard MBean instrumentation, the agent attempts to invoke a correct accessor method by introspecting the MBean class and building the invocation based on the Standard MBean naming conventions.

registerMBean and unregisterMBean

The registerMBean() call allows you to register a pre-existing object as an MBean to the server. Notice that if the ObjectName argument is null, the MBean may provide an ObjectName itself by implementing the MBeanRegistration interface. You will see how this works in practice when the interface is covered in detail.

The following is the declaration of registerMBean() and unregisterMBean() methods:

public ObjectInstance registerMBean(Object object,
                                    ObjectName name)
                            throws InstanceAlreadyExistsException,
                                   MBeanRegistrationException,
                                   NotCompliantMBeanException;

public void unregisterMBean(ObjectName name)
                            throws InstanceNotFoundException,
                                   MBeanRegistrationException;

The MBean may cancel the registration by throwing an exception from its preRegister() method of an MBeanRegistration interface. In that case, the exception will be wrapped in the MBeanRegistrationException instance and can be retrieved through the getTargetException() method. In a similar fashion, the unregistering of an MBean can be prevented by an exception thrown from the preDeregister() method of the MBeanRegistration interface. Also, notice that the agent does attempt to verify that the class being registered is a valid MBean. If a validation error occurs, a NotCompliantMBeanException is thrown by the registerMBean() method.

Because the registerMBean() method takes a reference to a pre-existing Java object as an argument, it often does not make sense to use this method from a remote location. Because the distribution layer for the JMX is not yet defined, some JMX connectors may choose to not allow this method to be accessed remotely at all. Remember that you can always use the createMBean() methods instead.

queryMBeans and queryNames

The queryMBeans() and queryNames() methods allow you to query the server for MBean object instances or object names. The query can be built by defining a name pattern as an ObjectName argument or by providing a query expression to the server. The queries are explained in detail at the end of this chapter.

public Set queryMBeans(ObjectName name, QueryExp query);

public Set queryNames(ObjectName name, QueryExp query);

Both methods return either a set of ObjectInstance objects or ObjectName objects that represent the matching MBeans for the given query or object name pattern.

Other MBeanServer Methods

The getDefaultDomain() method returns the default domain string used by the agent. If the MBean is registered with an object name that does not contain the domain part, the return value of this method is used as a default domain value.

The getMBeanCount() method returns the number of MBeans registered to the MBean server.

The getMBeanInfo() method returns the metadata of a given MBean. The management applications can use the returned MBeanInfo object to discover the management operations, attributes, and notifications of the MBean.

The isInstanceOf() method allows you to test if a given MBean is an instance of a class type. The classname is given as an argument to this method.

The isRegistered() method allows you to test whether an MBean registered to a given object name already exists in the MBean server.

MBeanRegistration Interface

The MBean life cycle can be defined from the moment it is registered to the MBean server to the moment it is unregistered from the MBean server. During this time, the MBean component is accessible to the management tools and other MBean components through its object name reference.

The JMX API defines an MBeanRegistration interface that can be used to receive callbacks in the MBean implementation of the life cycle events. The MBeanRegistration defines four methods that the MBean server is required to invoke on any MBean implementing the MBeanRegistration interface.

public ObjectName preRegister(
                       MBeanServer server,
                       ObjectName name
                  ) throws java.lang.Exception;

public void postRegister(Boolean registrationDone);

public void preDeregister() throws java.lang.Exception;

public void postDeregister();

The preRegister() and postRegister()methods are called by the agent just before the MBean is registered to the MBean server and right after the registration. The preDeregister() and postDeregister() methods are similarly called right before the MBean is unregistered from the agent and right after it has successfully been unregistered from the agent.

preRegister and postRegister

The preRegister() method has two parameters—a MBeanServer reference and an ObjectName reference. The MBeanServer reference is a reference to the MBean server to which the MBean is being registered. If the MBean requires interaction with the server, for example to use services of other MBeans, this reference should be stored by the MBean component.

The object name reference is the name that was given as a parameter with the registerMBean() or createMBean() method call on the MBean server. Notice that the return type of the preRegister() method is an ObjectName type. If a null pointer is passed as an object name when the MBean is being registered, the MBean is free to supply its own ObjectName instance to the agent.

It is also possible to cancel the registration of the MBean by throwing an exception from the preRegister() method. If any exceptions from the method are thrown, the agent will not register the MBean to the server. In this case, the agent will create an MBeanRegistrationException Java Management Extensions Specification that wraps the original exception and propagates it to the original caller.

The preRegister() method is useful for initializing the resources the MBean may need. It is also possible for the MBean to investigate the MBean server if it supports the required services and has them available. It is also possible to cancel the registration of an MBean in the preRegister() method.

The sequence of calls invoked when the MBean is being registered and implements the MBeanRegistration interface is shown in Figure 6.2.

Sequence of MBeanRegistration interface callbacks on MBean registration.

Figure 6.2. Sequence of MBeanRegistration interface callbacks on MBean registration.

preDeregister and postDeregister

The preDeregister() method should be used to clean up any resources the MBean may have acquired before it is unregistered from the server. If there is an exception thrown from invocation of the preDeregister() method, it is caught by the agent and wrapped into an MBeanRegistrationException instance before it's propagated to the caller. The postDeregister() method callback is made by the agent after the MBean has been unregistered from the MBean server. This method can be used for any additional cleanup operations that are required after the MBean is no longer registered to the agent.

The sequence of calls invoked when the MBean is being unregistered from the server is shown in Figure 6.3.

Sequence of MBeanRegistration interface callbacks on MBean unregistration.

Figure 6.3. Sequence of MBeanRegistration interface callbacks on MBean unregistration.

MBeanServerDelegate

Each MBean server instance is required to register an MBeanServerDelegateMBean instance when it is created. The server delegate is available to all management applications and other MBeans. The server delegate is always registered with the object name JMImplementation:type=MBeanServerDelegate.

The MBeanServerDelegateMBean exposes information about the server implementation and provides notification of MBean registration and unregistration events. Among the information you may query the server delegate for is the agent ID, specification version the server implements, vendor name, server version, and product name.

The operations of the MBeanServerDelegateMBean are listed in Table 6.1.

Table 6.1. Management Operations of Management Operations of the MBeanServerDelegate MBean

Operation Description
getImplementationName() Returns the name of the JMX implementation, in other words the product name, such as JMX RI or Tivoli JMX Agent.
getImplementationVendor() Returns the name of the vendor of the product, such as Sun Microsystems or Tivoli Systems Inc.
getImplementationVersion() Returns a string containing the version of the product.
getSpecificationName() Returns the full specification name the product implements.
getSpecificationVendor() Returns the vendor of the specification.
getSpecificationVersion() Returns the version of the specification the product implements.
getMBeanServerID() This is an identifier for the agent. The specification does not explicitly define the scope of the ID, so you may have to check with your vendor's implementation. A common implementation is an ID that is unique within the host machine.

In addition, the MBeanServerDelegateMBean is a broadcaster MBean and implements the addNotificationListener() and removeNotificationListener() methods. Management applications and other MBeans can invoke these methods to register their interest to receive MBean server notifications, such as registration and unregistration events.

The MBeanServerDelegateMBean emits notifications on every registerMBean() and unregisterMBean() method invocation executed on the server. The notification class that is sent by the server delegate is an MBeanServerNotification class. It extends the Notification class by adding a getMBeanName() method that returns the ObjectName reference of the MBean that has been registered or unregistered. The notification types of the MBeanServerNotification events are defined in the class as the two constants REGISTRATION_NOTIFICATION and UNREGISTRATION_NOTIFICATION.

Queries

The JMX specification defines a query mechanism that can be used for querying the MBean server for a set of MBeans. The queries can be based on an object name pattern or the management attribute values of MBeans.

The two methods on the MBeanServer interface used for queries are the queryMBeans() and queryNames() methods. Both methods require an ObjectName for their first parameter. The ObjectName for these methods represents the scope of the query. Any query expression passed as the second parameter will be applied only to those MBeans whose object name matches the pattern given as scope.

Scope of Queries

The scope is defined by creating an object name that matches a pattern of MBean names in the agent. For example, all MBeans in the Connector management domain can be matched by creating the following object name:

Connector:*

Any query executed with this scope will only be applied to the MBeans registered under the specific domain. Setting the query scope to null indicates that all MBeans in the server will be within the scope of the query. This is the equivalent of setting the scope to *:*.

The domain part of the object name can also use the '?' sign for defining patterns that match a single character. For example, an object name pattern

Domain?:*

will match management domain names such as DomainA, DomainB, and so on.

The key property list part of the object name can also use the asterisk (*) wildcard to create a name pattern. Notice, however, that only complete property key-value pairs are considered. For example, you cannot use the wildcard to match a specific property value. You can use the wildcard to require that the scope of the query contains only MBeans whose object names have a specific property value set. For example,

Service:type=automatic,*
Service:type=*           // NOT VALID !!

The first scope will match all MBeans in the Service domain that have a type property with value automatic set. However, the second scope is not valid because no pattern matching is performed on the property values.

Building Queries

The JMX specification does not define a specific query language for the MBean server queries. Instead, the queries are built programmatically with the help of a Query class. The Query class contains a set of static methods that return query expressions based on the given parameters. These query expressions are represented by the QueryExp interface that both the queryMBeans() and queryNames() methods use.

The Query class contains methods for query expressions, such as greater than, less than, equals, and so on. These query expressions can be combined with relational query expressions and, or, not, and so on. In addition, there are query expressions for string values such as "starts With", "ends With", and "contains" string. These types of queries are represented in the JMX API with a QueryExp interface. The Query class returns instances of this interface when you use the query expression methods.

For values used in the queries, another interface, ValueExp, is declared in the JMX API. Again, you get the implementations of the value expressions by using the factory methods in the Query class.

For example, to build a simple string matching query on a management attribute Name, you could write the following query generation code:

AttributeValueExp attribute = Query.attr("Name");
StringValueExp name = Query.value("John");
QueryExp query = Query.match(attribute, name);

In this example, both AttributeValueExp and StringValueExp classes implement the ValueExp interface. The match method requires these two classes as parameters and returns an instance of the QueryExp interface representing the query where the attribute Name matches the string John. The query expression can then be invoked on the server:

Set resultSet = server.queryNames(new ObjectName("*:*"), query);

The returned collection would contain the ObjectName references to all MBeans that have a Name management attribute containing the string value "John".

Table 6.2 lists some the methods of the Query class.

Table 6.2. Query Class Methods

Method Description
and(QueryExp a, QueryExp b)
or(QueryExp a, QueryExp b)
not(QueryExp q)
These methods build queries that use the relational operations on the given query expressions.
anySubString(AttributeValueExp attr,
   StringValueExp string)

These methods work on string type management attributes

The anySubString checks whether the given string expression is a substring of the attribute value.

finalSubString(AttributeValueExp attr,
   StringValueExp string)
The finalSubString checks whether the given string expression is a suffix of the attribute value.
initialSubString(AttributeValueExp attr,
   StringValueExp string)
The initialSubString checks whether the given string expression is a prefix of the attribute value.
match(AttributeValueExp attr,
   StringValueExp string)
The match method tests the equality of the string value expressions and the attribute string value. The match allows wildcards * and ? to be used, character sets [Aa] and character ranges [A-Z].
between(ValueExp a, ValueExp b, ValueExp c)
in(ValueExp a, ValueExp[] set)

The between method builds a query expression where the first value has to be within the boundaries specified by the latter two value expressions. All value expressions must be numeric values.

The in method builds a query expression that tests whether the given value expression is part of the set given as a ValueExp array.

plus(ValueExp a, ValueExp b)
minus(ValueExp a, ValueExp b)
times(ValueExp a, ValueExp b)
div(ValueExp a, ValueExp b)
These methods perform an arithmetic operation to the given value expression and return a new value expression that represents the result of the operation. All value expressions must be numeric values.
eq(ValueExp a, ValueExp b)
geq(ValueExp a, ValueExp b)
gt(ValueExp a, ValueExp b)
leq(ValueExp a, ValueExp b)
It(ValueExp a, ValueExp b
These methods return a query expression that represents equality between twp value expressions, greater than or equal to, greater than, less than or equal to, and less than comparisons between the value expressions.
attr(String s) Creates an attribute value expression for the given attribute name.
value() Creates a value expression for the given numeric or string value. The value() method is overloaded to accept most primary types, subclasses of Number, or a string as argument.

Listing 6.2 shows an example code of some simple queries that can be executed on the MBean server.

Example 6.2. Queries.java

package book.jmx.examples;

import java.util.*;
import javax.management.*;

public class Queries {

  public static void main(String[] args) throws Exception {
    MBeanServer server = MBeanServerFactory.createMBeanServer();

    ObjectName john = new ObjectName("DomainA:name=john");
    ObjectName mike = new ObjectName("DomainA:name=mike");
    ObjectName xena = new ObjectName("DomainA:name=xena");

    server.createMBean("book.jmx.examples.User", john);
    server.createMBean("book.jmx.examples.User", mike);
    server.createMBean("book.jmx.examples.User", xena);

    server.setAttribute(john, new Attribute("Name", "John"));
    server.setAttribute(mike, new Attribute("Name", "Mike"));
    server.setAttribute(xena, new Attribute("Name", "Xena"));

    server.setAttribute(john,
        new Attribute("Address", "King's Road 11"));
    server.setAttribute(mike,
        new Attribute("Address", "Strawberry St. 5"));
    server.setAttribute(xena,
        new Attribute("Address", "Strawberry St. 12"));
    testQueries(server);
  }

  static void testQueries(MBeanServer server) throws Exception {

    QueryExp exp =
        Query.match(Query.attr("Name"), Query.value("John"));

    ObjectName scope = new ObjectName("DomainA:*");
    Set set      = server.queryNames(scope, exp);
    Iterator it  = set.iterator();

    System.out.println("MBeans with attribute Name = 'John' n");

    while (it.hasNext()) {
      System.out.println(it.next());
    }

    scope = new ObjectName("DomainA:*");
    exp   = Query.initialSubString(Query.attr("Address"),
                                   Query.value("Strawberry"));

    set   = server.queryNames(scope, exp);
    it    = set.iterator();

    System.out.println(
        " nMBeans with Address startsWith 'Strawberry' n");

    while (it.hasNext()) {
      System.out.println(it.next());
    }
  }

}

When you compile and run the queries example, you should see the following output on your console.

C: Examples> javac -d . -classpath jmx lib jmxri.jar Queries.java

C: Examples> java -classpath .;jmx lib jmxri.jar book.jmx.examples.Queries

MBeans with attribute Name = 'John'
DomainA:name=john

MBeans with Address startsWith 'Strawberry'

DomainA:name=mike
DomainA:name=xena

C: Examples>

Summary

The MBean server is central part of the JMX management architecture. Primarily, the MBean server acts as a registry to the MBeans. It also decouples the management applications from the resource class implementations. As discussed in this chapter, the management applications never directly reference the MBean classes but use object name references to access the managed resources.

For the decoupling to work, the communication between the management applications and the MBeans must always go through the JMX MBean server. The MBeanServer interface exposes the methods for creating and registering MBeans, invoking management operations, accessing the management attributes of an MBean, and executing queries on the server.

Also keep in mind that no statically typed Java interfaces are exposed to the management clients. The clients can discover the management interface, the operations, attributes, and notifications via the metadata information exposed by the agent for each MBean. This also allows the management interfaces to evolve over time without affecting the existing management applications. New management operations and attributes can be added to the resources transparently to the clients. This eases maintenance in the long term, because distribution of updated interfaces is not required for existing clients.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.194.123