4.1 Introduction

Creating instrumentation with MBeans from scratch can be time-consuming and tedious . The JMX model MBean specification [1] provides generic instrumentation that can be quickly customized for many resources. This chapter describes the model MBean in detail and provides multiple examples of its use in practice.

A model MBean is a fully customizable dynamic MBean. The RequiredModelMBean class, which implements the ModelMBean interface, is guaranteed to exist on every JMX agent. A model MBean implements the ModelMBean interface that extends a set of interfaces including DynamicMBean , PersistentMBean , and ModelMBeanNotificationBroadcaster .

Like the open MBean, the model MBean has it's own extended MBeanInfo interface called ModelMBeanInfo . ModelMBeanInfo associates new, extensible metadata objects called descriptors with the management interface. Descriptors add additional information about the managed resource and are also used to customize the behavior of a RequiredModelMBean instance. In this chapter, when we say simply "model MBeans" we are referring to implementations of the model MBean or RequiredModelMBean . When we are referring to the ModelMBean interface, we will say "the ModelMBean interface."

Model MBeans were added to JMX for several reasons:

  • Ease of use for developers . Because model MBeans have an actual implementation class, RequiredModelMBean , as part of every JMX implementation, developers don't need to write their entire MBean and address all of the accompanying support for logging, notifications, errors, persistence, and so on. All of this is provided as part of the RequiredModelMBean implementation. Because it is an actual implementation, you can create subclasses for it and override its behavior with your own. Model MBeans make it possible to instrument your managed resource in as little as five lines of code (not including configuration of the model MBean).

  • Ease of support by development tools . Because model MBeans are fully configurable through metadata kept in descriptors, the creation of ModelMBeanInfo requires either a lot of programmatic setting of metadata or a lot of XML [2] in a file. However, the use of metadata with a portable XML file or API to create it makes it much easier to create and maintain model MBeans with development tools. Part of the intent for model MBeans was to enable the creation of management objects during development by development tools and wizards. Eventually we hope that developing the management objects and interfaces for your application will be as much a part of your application development cycle as developing remote interfaces and logging or tracing support.

  • Common services . Model MBeans support a common set of behaviors in all implementations, including logging, generic notifications, attribute change notifications, persistence, and value caching. These behaviors can be customized and overridden.

  • Dynamic behavior . Model MBeans are completely customized during development or during runtime. During development, the ModelMBeanInfo class supports APIs to customize the management interface and behavior of the model MBean. During runtime, external files, properties files, or XML files can be used to customize the model MBean. Likewise the resource may use the ModelMBeanInfo APIs to customize the model MBean so that it conforms to its own runtime factors.

  • Isolation . Model MBeans isolate the application manageability instrumentation from differences in Java runtimes and JMX implementations. Manageable components today may be installed and used in different editions of Java: J2SE, [3] J2EE, [4] and eventually J2ME. [5] These different JVMs may use different approaches when providing common services to model MBeans. For example, a J2SE JMX RequiredModelMBean implementation may support persistence by writing the data to files. If persistence to a database were required, then RequiredModelMBean would use JDBC [6] directly. However, a J2EE JMX RequiredModelMBean may be implemented as a local EJB [7] or wrapped as a remote EJB and use container-managed persistence. As JMX becomes more pervasive in the J2ME JVMs, these differences in MBean behavior will become more apparent.

    In a J2ME JVM, persistence and logging may not be allowed at all if the JVM is run on a diskless device. Even value caching in memory may be too costly. If you were writing your own MBeans for your component, you would have to write very different MBeans for each of these scenarios. However, because you use the MBeanServer as a factory to instantiate the RequiredModelMBean class that has been supplied by the JMX implementation, your use of the MBean in your managed resource does not change. The JMX implementation is required to make sure that the RequiredModelMBean implementation is appropriate for the installation and current JVM environment. Your investment in instrumentation of your managed resources is protected and requires less development and maintenance.

4.1.1 The Simplest Model MBean Example

In this section we will look at a simple example of how to use a model MBean. This example shows how to make a resource manageable in as little as five lines of code. In this example we expose attributes and operations of the managed resource and send a notification upon an error condition.

Recall from Chapter 3, on MBeans, that the Apache server application had its own standard MBean. Let's look at what it would take to create a model MBean for the Apache server. We will have to write a Java utility, ApacheServer , to get the information from the Apache module and return it to the model MBean. In our scenario, the ApacheServer class is similar to the Apache implementation, but it does not implement the ApacheMBean class, and it does not have to support value caching (see Code Block 3 in the text that follows ). The model MBean will provide caching support at a much finer grain. The caching policy will be defined in the attribute descriptors in ModelMBeanInfo . Therefore, we don't support the isCaching() , getCacheLifetime() , setCacheLifetime() , getCaching() , and setCaching() methods in the original standard MBean interface. The ApacheServer class is the managed resource.

The first code block that follows shows how to find the MBeanServer, instantiate the model MBean, instantiate ApacheServer , associate it with the model MBean, configure the model MBean, and send a notification if the server is down at this time. The second code block shows how to configure the model MBean through ModelMBeanInfo . Notice that we can selectively cache the data from the Apache server, choosing not to cache some of the more time-sensitive counters. The third code block shows the slightly modified Apache class from Chapter 3. All of the examples in this book (plus some others) are available on the book's Web site: http://www.awprofessional.com/titles/0672324083.

Code Block 1

  package  jnjmx.ch4;  import  javax.management.*;  import  javax.management.modelmbean.*;  import  java.lang.reflect.Constructor;  import  java.util.ArrayList; /**  *  @author  Heather Kreger  * Chapter 4:  Java and JMX Building Manageable Systems  * ApacheServerManager: Manages the ApacheServer as a managed  * resource using a model MBean.  *  * ModelMBeanInfo is created using ModelMBeanInfo APIs  * rather than an XML file.  */  public class  ApacheServerManager {  public   static   void  main(String[] args) {  boolean  tracing =  false;  String serverURL = "";  try  {  if  (args.length != 0) {         System.out.println(args[0]);  if  (args[0] !=  null  )           serverURL = serverURL.concat(args[0]);  else  serverURL = "http://www.apache.org/server-status?auto";       }       // This serverURL default mechanism is just for this example       // We would not recommend this in a real application  if  (!serverURL.startsWith("http"))         serverURL = "http://www.apache.org/server-status?auto";       /** Find an MBeanServer for our MBean */       MBeanServer myMBS = MBeanServerFactory.createMBeanServer();       /** Instantiate an unconfigured RequiredModelMBean in the MBeanServer */       RequiredModelMBean apacheMMBean =         (RequiredModelMBean) myMBS.instantiate(           "javax.management.modelmbean.RequiredModelMBean");       /** Create a name for the MBean        * domain = apacheManager        * one attribute: id = ApacheServer*/       ObjectName apacheMBeanName =  new  ObjectName("apacheManager: id=ApacheServer");       /** Instantiate the ApacheServer utility to be delegated to */       jnjmx.ch4.ApacheServer myApacheServer =  new  jnjmx.ch4.ApacheServer(serverURL);       /** Set the configuration of the ModelMBean through the ModelMBeanInfo        ** This method is below */       ApacheServerManager asmgr =  new  ApacheServerManager();       ModelMBeanInfo apacheMMBeanInfo =         asmgr.createApacheModelMBeanInfo(           myApacheServer,           apacheMBeanName);       apacheMMBean.setModelMBeanInfo(apacheMMBeanInfo);       // ** Set the ApacheServer as the managed resource       apacheMMBean.setManagedResource(myApacheServer, "ObjectReference");       // ** Register the ModelMBean instance that is now ready to run with the       // MBeanServer       ObjectInstance registeredApacheMMBean =         myMBS.registerMBean((Object) apacheMMBean, apacheMBeanName);       // ** Use the ModelMBean to send the notification into JMX where it gets       // sent to a manager adapter that is registered for notifications from the       // Apache MBeans and sends them to a pager system       String apacheStatus =         (String) apacheMMBean.invoke("getState",  null,   null  );  if  ((apacheStatus.equals("DOWN"))          (apacheStatus.equals("NOT_RESPONDING"))) {         System.out.println("Apache Server is Down");         apacheMMBean.sendNotification("Apache Server is Down");         /*  You could create monitor to notify when up          * again so Web traffic can be routed back to it */       }  else  System.out.println("Apache Server is " + apacheStatus);     }  catch  (Exception e) {       System.out.println(         "Apache Server Manager failed with " + e.getMessage());     }     System.exit(0);   } 

Because model MBeans support the NotificationBroadcaster interface, when the getStatus() method returns Down or Not Responding , we have the model MBean send a notification to the MBeanServer, which in turn sends it to all registered notification listeners. This is fairly simple to do; we merely

  1. Find our MBeanServer .

  2. Instantiate the RequiredModelMBean class using the MBeanServer.

  3. Customize RequiredModelMBean in two steps:

    1. Set up the ModelMBeanInfo instance .

    2. Associate the model MBean with the access to the actual managed resource.

  4. Register RequiredModelMBean with the MBeanServer.

  5. Invoke the model MBean to get the Status attribute.

  6. Send the notification if the status is Down or Stopped . In the downloadable examples for the book, we provide an example of a notification listener for this event that you can experiment with.

Here's how we set the ModelMBeanInfo instance that we used to customize this model MBean. The ModelMBeanInfo object created for the ApacheServer managed application used in the Apache model MBean defines the following:

  • String attributes that are read-only: BusyWorkers , BytesPerSec , BytesPerReq , IdleWorkers , ReqPerSec , Scoreboard , State , TotalAccesses , TotalKBytes , and Uptime

  • String attributes that are read/write: Server

  • Operations: start and stop

  • Notification: ApacheServer Down

  • Operations to support the attributes on the ApacheServer class: getBusyWorkers() , getBytesPerReq() , getBytesPerSec() , getIdleWorkers() , getReqPerSec() , getScoreboard() , getServer() , getState() , getTotalAccesses() , getTotalKBytes() , getUptime() , setServer(String URL)

Code Block 2 illustrates the programmatic way to create a ModelMBeanInfo instance. ModelMBeanInfo can also be initialized from data saved in a file. This is shown in the XML primer examples later in this chapter (see Section 4.7). It is much simpler code, but it requires the use of an XML service that is not a standard service of JMX. This entire method is relatively lengthy, but it is very simple to program and it is easy for tools to generate. The method in its entirety is listed here. We will explain how to set an attribute, an operation, and a notification in the next section.

Code Block 2

 // Create the ModelMBeanInfo for the Apache server    ModelMBeanInfo createApacheModelMBeanInfo(     ApacheServer managedApache,     ObjectName apacheMBeanName) {     // Set the ApacheServer's class name, there are other     // more flexible ways to do this     Class apacheClass =  null;   try  {       apacheClass = Class.forName("jnjmx.ch4.ApacheServer");     }  catch  (Exception e) {       System.out.println("ApacheServer Class not found");     }     // Set the MBean's descriptor with default policies     // MBean name is apacheMBeanName     // logging notifications to jmxmain.log     // caching attributes for 10 seconds     Descriptor apacheDescription =  new  DescriptorSupport(  new  String[] {           ("name=" + apacheMBeanName),           "descriptorType=mbean",           ("displayName=ApacheServerManager"),           "type=jnjmx.ch4.ApacheServer",           "log=T",           "logFile=jmxmain.log",           "currencyTimeLimit=10" });     // Define attributes in ModelMBeanAttributeInfo instances     ModelMBeanAttributeInfo[] apacheAttributes =  new  ModelMBeanAttributeInfo[11];     // Declare BusyWorkers attribute     // cache BusyWorkers for 3 seconds,     // use get method     Descriptor busyWorkersDesc =  new  DescriptorSupport(  new  String[] {           "name=BusyWorkers",           "descriptorType=attribute",           "displayName=Apache BusyWorkers",           "getMethod=getBusyWorkers",           "currencyTimeLimit=3" });     apacheAttributes[0] =  new  ModelMBeanAttributeInfo(         "BusyWorkers",         "int",         "Apache Server Busy Workers",  true,   false,   false,  busyWorkersDesc);     // Declare BytesPerSec attribute     // Cache ByetesperSec for 10 seconds     Descriptor bytesPerSecDesc =  new  DescriptorSupport(  new  String[] {           "name=BytesPerSec",           "descriptorType=attribute",           "displayName=Apache BytesPerSec",           "getMethod=getBytesPerSec",           "currencyTimeLimit=10" });     apacheAttributes[1] =  new  ModelMBeanAttributeInfo(         "BytesPerSec",         "int",         "Apache Server Bytes Per Sec",  true,   false,   false,  bytesPerSecDesc);     // Declare BytesPerReq attribute     Descriptor bytesPerReqDesc =  new  DescriptorSupport(  new  String[] {           "name=BytesPerReq",           "descriptorType=attribute",           "displayName=Apache BytesPerReq",           "getMethod=getBytesPerReq",           "currencyTimeLimit=10" });     apacheAttributes[2] =  new  ModelMBeanAttributeInfo(         "BytesPerReq",         "int",         "Apache Server Bytes Per Request",  true,   false,   false,  bytesPerReqDesc);     // Declare IdleWorkers attribute     Descriptor idleWorkersDesc =  new  DescriptorSupport(  new  String[] {           "name=IdleWorkers",           "descriptorType=attribute",           "displayName=Apache IdleWorkers",           "getMethod=getIdleWorkers",           "currencyTimeLimit=10" });     apacheAttributes[3] =  new  ModelMBeanAttributeInfo(         "IdleWorkers",         "int",         "Apache Server Idle Workers",  true,   false,   false,  idleWorkersDesc);     // Declare ReqPerSec attribute     Descriptor reqPerSecDesc =  new  DescriptorSupport(  new  String[] {           "name=ReqPerSec",           "descriptorType=attribute",           "displayName=Apache ReqPerSec",           "getMethod=getReqPerSec",           "currencyTimeLimit=5" });     apacheAttributes[4] =  new  ModelMBeanAttributeInfo(         "ReqPerSec",         "int",         "Apache Server Requests Per Second",  true,   false,   false,  reqPerSecDesc);     // Declare Scoreboard attribute     Descriptor ScoreboardDesc =  new  DescriptorSupport(  new  String[] {           "name=Scoreboard",           "descriptorType=attribute",           "displayName=Apache Scoreboard",           "getMethod=getScoreboard",           "currencyTimeLimit=10" });     apacheAttributes[5] =  new  ModelMBeanAttributeInfo(         "Scoreboard",         "java.lang.String",         "Apache Server Scoreboard",  true,   false,   false,  ScoreboardDesc);     // Declare TotalAccesses attribute     // Do not cache TotalAccesses     Descriptor totalAccessesDesc =  new  DescriptorSupport(  new  String[] {           "name=TotalAccesses",           "descriptorType=attribute",           "displayName=Apache TotalAccesses",           "getMethod=getTotalAccesses",           "currencyTimeLimit=-1" });     apacheAttributes[6] =  new  ModelMBeanAttributeInfo(         "TotalAccesses",         "int",         "Apache Server total accesses",  true,   false,   false,  totalAccessesDesc);     // Declare TotalKBytes attribute     // Do not cache TotalKBytes     Descriptor totalKBytesDesc =  new  DescriptorSupport(  new  String[] {           "name=TotalKBytes",           "descriptorType=attribute",           "displayName=Apache TotalKBytes",           "getMethod=getTotalKBytes",           "currencyTimeLimit=-1" });     apacheAttributes[7] =  new  ModelMBeanAttributeInfo(         "TotalKBytes",         "int",         "Apache Server total KiloBytes",  true,   false,   false,  totalKBytesDesc);     // Declare Uptime attribute     Descriptor uptimeDesc =  new  DescriptorSupport(  new  String[] {           "name=Uptime",           "descriptorType=attribute",           "displayName=Apache Uptime",           "getMethod=getUptime",           "currencyTimeLimit=10" });     apacheAttributes[8] =  new  ModelMBeanAttributeInfo(         "Uptime",         "java.lang.String",         "Apache Server Up Time",  true,   false,   false,  uptimeDesc);     // Declare State attribute     // State has a getMethod     Descriptor stateDesc =  new  DescriptorSupport(  new  String[] {           "name=State",           "descriptorType=attribute",           "displayName=Apache State",           "getMethod=getState",           "currencyTimeLimit=10" });     apacheAttributes[9] =  new  ModelMBeanAttributeInfo(         "State",         "java.lang.String",         "Apache Server state",  true,   false,   false,  stateDesc);     // Declare Server attribute     // Server has a getMethod and a setMethod     Descriptor serverDesc =  new  DescriptorSupport(  new  String[] {           "name=Server",           "descriptorType=attribute",           "displayName=Apache Server URL",           "getMethod=getServer",           "setMethod=setServer",           "currencyTimeLimit=10" });       apacheAttributes[10] =  new  ModelMBeanAttributeInfo(           "Server",           "java.lang.String",           "Apache Server Busy Workers",  true,   true,   false,  serverDesc);     // Declare constructors for the managed resource     // one constructor which accepts one parameter,     // a String URL     Constructor[] myConstructors = apacheClass.getConstructors();     ModelMBeanConstructorInfo[] apacheConstructors =  new  ModelMBeanConstructorInfo[1];     MBeanParameterInfo[] constructorParms =  new  MBeanParameterInfo[] {         (  new  MBeanParameterInfo("serverURL",         "java.lang.String",         "Apache Server URL"))};     Descriptor apacheBeanDesc =  new  DescriptorSupport(  new  String[] {           "name=ApacheServer",           "descriptorType=operation",           "role=constructor" });     apacheConstructors[0] =  new  ModelMBeanConstructorInfo(         "Apache",         "ApacheServer(): Constructs an ApacheServer utility class",         constructorParms,         apacheBeanDesc);     // Define operations in ModelMBeanOperationInfo instances     /* Operations: getBusyWorkers, getBytesPerSec, getBytesPerReq,       * getIdleWorkers, getReqPerSec, getScoreboard, getTotalAccesses,       * getTotalKBytes, getUptime are satisfied by getValue, getState,       * getServer, setServer(String URL), start, stop have own operations */     // Declare getValue operation String getValue()     // Set parameter array     ModelMBeanOperationInfo[] apacheOperations =  new  ModelMBeanOperationInfo[6];     MBeanParameterInfo[] getParms =  new  MBeanParameterInfo[0];     MBeanParameterInfo[] getValueParms =  new  MBeanParameterInfo[] {         (  new  MBeanParameterInfo("FieldName",         "java.lang.String",         "Apache status field name"))};     Descriptor getValueDesc =  new  DescriptorSupport(  new  String[] {           "name=getValue",           "descriptorType=operation",           "class=ApacheServer",           "role=operation" });     apacheOperations[0] =  new  ModelMBeanOperationInfo(         "getValue",         "getValue(): get an apache status field",         getValueParms,         "java.lang.String",         MBeanOperationInfo.INFO,         getValueDesc);     Descriptor getStateDesc =  new  DescriptorSupport(  new  String[] {         "name=getState",         "descriptorType=operation",         "class=ApacheServer",         "role=operation" });     apacheOperations[1] =  new  ModelMBeanOperationInfo(         "getState",         "getState(): current status of apache server",         getParms,         "java.lang.String",         MBeanOperationInfo.INFO,         getStateDesc);     Descriptor getServerDesc =  new  DescriptorSupport(  new  String[] {"name=getServer",          "descriptorType=operation",          "class=ApacheServer",          "role=operation" });     apacheOperations[2] =  new  ModelMBeanOperationInfo("getServer",         "getServer(): URL of apache server",         getParms,         "java.lang.Integer",         MBeanOperationInfo.INFO,         getServerDesc);     MBeanParameterInfo[] setParms =  new  MBeanParameterInfo[] {         (  new  MBeanParameterInfo("url",         "java.lang.String",         "Apache Server URL"))};     Descriptor setServerDesc =  new  DescriptorSupport(  new  String[] {"name=getServer",          "descriptorType=operation",          "class=ApacheServer",          "role=operation" });     apacheOperations[3] =  new  ModelMBeanOperationInfo("setServer",         "getServer(): URL of apache server",         setParms,         "java.lang.String",         MBeanOperationInfo.ACTION,         setServerDesc);     MBeanParameterInfo[] startParms =  new  MBeanParameterInfo[0];     Descriptor startDesc =  new  DescriptorSupport(  new  String[] {"name=start",         "descriptorType=operation",         "class=ApacheServer",         "role=operation" });     apacheOperations[4] =  new  ModelMBeanOperationInfo("start",       "start(): start apache server",       startParms,       "java.lang.Integer",       MBeanOperationInfo.ACTION,       startDesc);     MBeanParameterInfo[] stopParms =  new  MBeanParameterInfo[0];     Descriptor stopDesc =  new  DescriptorSupport(  new  String[] {"name=stop",        "descriptorType=operation",        "class=ApacheServer",        "role=operation" });     apacheOperations[5] =  new  ModelMBeanOperationInfo("stop",       "stop(): start apache server",       stopParms,       "java.lang.Integer",       MBeanOperationInfo.ACTION,       stopDesc);     /* getters/setters for operations */     //    MBeanParameterInfo[] getParms = new MBeanParameterInfo[0];     Descriptor bytespsDesc =  new  DescriptorSupport(  new  String[] {"name=getBytesPerSecond",       "descriptorType=operation",       "class=ApacheServer",       "role=operation" });     apacheOperations[6] =  new  ModelMBeanOperationInfo("getBytesPerSecond",         "number of bytes per second processed",         getParms,         "int",         MBeanOperationInfo.ACTION,         bytespsDesc);     // Define notifications in ModelMBeanNotificationInfo     // declare an "Apache Server Down" notification     ModelMBeanNotificationInfo[] apacheNotifications =  new  ModelMBeanNotificationInfo[1];     Descriptor apacheDownEventDesc =  new  DescriptorSupport(  new  String[] {           "descriptorType=notification",           "name=jmx.ModelMBean.General.Apache.Down",           "severity=1",           "MessageId=Apache001" });     apacheNotifications[0] =  new  ModelMBeanNotificationInfo(  new  String[] {"jmx.ModelMBean.General.Apache.Down" },         "jmx.ModelMBean.General",         "Apache Server Down",         apacheDownEventDesc);     // Create the ModelMBeanInfo     ModelMBeanInfo apacheMMBeanInfo =  new  ModelMBeanInfoSupport(         "Apache",         "ModelMBean for managing an Apache Web Server",         apacheAttributes,         apacheConstructors,         apacheOperations,         apacheNotifications);     // Set the MBean's Descriptor for the ModelMBeanInfo  try  {       apacheMMBeanInfo.setMBeanDescriptor(apacheDescription);     }  catch  (Exception e) {       System.out.println("CreateMBeanInfo failed with " + e.getMessage());     }  return  apacheMMBeanInfo;   } 

Finally, just to complete the example, even though this is basically what's in Chapter 3 as the Apache class, here is the ApacheServer class for getting the data for the Apache server resource we are managing:

Code Block 3

  package  jnjmx.ch4;  /**  *  @author  Heather Kreger  * Chapter 4:  Java and JMX: Building Manageable Systems  * ApacheServer: interacts with an Apache server through a URL  */  import  java.io.BufferedReader;  import  java.io.IOException;  import  java.io.InputStreamReader;  import  java.net.MalformedURLException;  import  java.net.URL;  import  java.net.URLConnection;  import  java.util.HashMap;  import  java.util.StringTokenizer;  import  javax.management.*;  public   class  ApacheServer {   // String constants for each of the Apache-related attributes  private   static   final  String BUSY_WORKERS = "BusyWorkers";  private   static   final  String BYTES_PER_REQ = "BytesPerReq";  private   static   final  String BYTES_PER_SEC = "BytesPerSec";  private   static   final  String CPU_LOAD = "CPULoad";  private   static   final  String IDLE_WORKERS = "IdleWorkers";  private   static   final  String REQ_PER_SEC = "ReqPerSec";  private   static   final  String SCOREBOARD = "Scoreboard";  private   static   final  String TOTAL_ACCESSES = "Total Accesses";  private   static   final  String TOTAL_KBYTES = "Total kBytes";  private   static   final  String UPTIME = "Uptime";  private   static   final   int  MAX_FAILURES = 3;   // state constants for the Apache Server (brought over from ApacheMBean interface  public  String DOWN = "DOWN";  public  String NOT_RESPONDING = "NOT_RESPONDING";  public  String RUNNING = "RUNNING";  public  String UNKNOWN = "UNKNOWN";  private   int  failures = 0;  private  String state = UNKNOWN;  private   long  tzero;  private  URL url;   // constructor that accepts the URL for the Apache server to be managed  public  ApacheServer(String url)  throws  MalformedURLException, IllegalArgumentException {     setServer(url);     // test the ability to communicate using the URL  try  {       getValue(UPTIME);     }  catch  (Exception e) {       System.out.println(         "Apache server at " + url + " does not respond.");     }   }   // Return the URL of the Apache server being managed   // Server is a readable and writable attribute because   // it has a getter and setter  public  String getServer() {  return   this.  url.toString();   }   // Set the URL of the Apache server being managed  public   void  setServer(String url)  throws  MalformedURLException, IllegalArgumentException {  this.  url =  new  URL(url);     // test to be sure the URL is really an Apache server URL  if  (isStatusUrl(  this.  url) ==  false  ) {  throw   new  IllegalArgumentException(url.toString());     }  this.  state = ApacheMBean.UNKNOWN;   }   // return the current state of the Apache server  public  String getState() {     return this.state;   }   // Example operation for start   // If this were running in the same JVM, this is   // where the apache process initialzation would go  public  String start() {  this.  state = RUNNING;     return this.state;   }   // Sample operation for stop   // If this were running in the same JVM, this is   // where the Apache process initialization would go  public  String stop() {  this.  state = DOWN;     return this.state;   }   // Validate that the URL is an Apache server status URL  private   boolean  isStatusUrl(URL url) {  return  url.toString().endsWith("server-status?auto");   }   // Get methods for metrics retrieved via the Apache URL   // These are read-only attributes because no "setters" are   // defined for them  public   int  getBusyWorkers()  throws  ApacheMBeanException {  return  getIntValue(BUSY_WORKERS);   }  public   int  getBytesPerSec()  throws  ApacheMBeanException {  return  getIntValue(BYTES_PER_SEC);   }  public   float  getBytesPerReq()  throws  ApacheMBeanException {  return  getFloatValue(BYTES_PER_REQ);   }  public   float  getCpuLoad()  throws  ApacheMBeanException {  return  getFloatValue(CPU_LOAD);   }  public   int  getIdleWorkers()  throws  ApacheMBeanException {  return  getIntValue(IDLE_WORKERS);   }  public   float  getReqPerSec()  throws  ApacheMBeanException {  return  getFloatValue(REQ_PER_SEC);   }  public  String getScoreboard()  throws  ApacheMBeanException {  return  getStringValue(SCOREBOARD);   }  public   int  getTotalAccesses()  throws  ApacheMBeanException {  return  getIntValue(TOTAL_ACCESSES);   }  public   long  getTotalKBytes()  throws  ApacheMBeanException {  return  getLongValue(TOTAL_KBYTES);   }  public   long  getUptime()  throws  ApacheMBeanException {  return  getLongValue(UPTIME);   }   // These methods are used as internal utilities by the getter methods   // There is one for each type returning the base Java type  private  String getValue(String value)  throws  ApacheMBeanException, NoSuchFieldException, IOException {     String result;     URLConnection k = establishConnection();     result = (String) readStatus(k, value);  if  (result ==  null  ) {  throw   new  NoSuchFieldException(value);     }  return  result;   }  private   float  getFloatValue(String value)  throws  ApacheMBeanException {  float  result;  try  {       result = Float.parseFloat((String) getValue(value));     }  catch  (IOException x) {  throw   new  ApacheMBeanException(x);     }  catch  (NoSuchFieldException x) {  throw   new  ApacheMBeanException(x);     }  return  result;   }  private   int  getIntValue(String value)  throws  ApacheMBeanException {  int  result;  try  {       result = Integer.parseInt((String) getValue(value));     }  catch  (IOException x) {  throw   new  ApacheMBeanException(x);     }  catch  (NoSuchFieldException x) {  throw   new  ApacheMBeanException(x);     }  return  result;   }  private   long  getLongValue(String value)  throws  ApacheMBeanException {  long  result;  try  {       result = Long.parseLong((String) getValue(value));     }  catch  (IOException x) {  throw   new  ApacheMBeanException(x);     }  catch  (NoSuchFieldException x) {  throw   new  ApacheMBeanException(x);     }  return  result;   }  private  String getStringValue(String value)  throws  ApacheMBeanException {     String result;  try  {       result = (String) getValue(value);     }  catch  (IOException x) {  throw   new  ApacheMBeanException(x);     }  catch  (NoSuchFieldException x) {  throw   new  ApacheMBeanException(x);     }  return  result;   }   // Establishes the connection to the URL   // If the connection fails, then the state   // is changed to DOWN or NOT_RESPONDING  private  URLConnection establishConnection()  throws  IOException, ApacheMBeanException {     URLConnection k =  this.  url.openConnection();  try  {       k.connect();  this.  failures = 0;  this.  state = ApacheMBean.RUNNING;     }  catch  (IOException x) {  if  (++  this.  failures > MAX_FAILURES) {  this.  state = DOWN;       }  else  {  this.  state = NOT_RESPONDING;       }  throw   new  ApacheMBeanException("state: " +  this.  state);     }  return  k;   }   // Parses the data returned from the URL  private  String readStatus(URLConnection k, String value)  throws  IOException {     BufferedReader r =  new  BufferedReader(  new  InputStreamReader(k.getInputStream()));  for  (String l = r.readLine(); l !=  null;  l = r.readLine()) {       StringTokenizer st =  new  StringTokenizer(l, ":");  if  (st.nextToken().trim().equals(value)) {         // if it's the right value  return  (String) (st.nextToken().trim()); // get wanted value       }  else  {         st.nextToken(); // past unwanted value       }     }  return  "";   } } 

Now, let's look at the capabilities of model MBeans in detail.



Java and JMX. Building Manageable Systems
Javaв„ў and JMX: Building Manageable Systems
ISBN: 0672324083
EAN: 2147483647
Year: 2000
Pages: 115

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net