Stories

Detail Return Return

【Tomcat】《How Tomcat Works》英文版GPT翻譯(第二十章) - Stories Detail

Chapter 20: JMX-Based Management(第 20 章:基於 JMX 的管理)

Chapter 19 discussed the Manager application. It showed that the ManagerServlet class implemented the ContainerServlet interface to get access to Catalina internal objects. This chapter now shows that managing Tomcat can be achieved more sophisticatedly using the Java Management Extensions (the JMX specification). For those unfamiliar with JMX, a brief introduction is given at the beginning of the chapter. In addition, this chapter explains the Commons Modeler library that Catalina uses to ease the task of writing Managed Beans, the objects used for managing other objects. Examples are offered to make understanding the use of JMX in Tomcat easier.

第19章討論了Manager應用程序。

它展示了 ManagerServlet 類實現了ContainerServlet接口,以便訪問Catalina內部對象。

本章將展示更復雜地使用Java管理擴展(JMX規範)來管理Tomcat。

對於不熟悉JMX的人,本章在開頭進行了簡要介紹。

此外,本章還解釋了Catalina使用的Commons Modeler庫,以簡化編寫管理其他對象的託管Bean的任務。

為了更好地理解在Tomcat中使用JMX的用法,提供了示例。

Introduction to JMX(JMX 簡介)

So, if the ContainerServlet interface is good enough for the Manager application to get access to the internal body of Catalina, why should we care about JMX? Because JMX provides much greater flexibility than ContainerServlet. Many server-based applications, such as Tomcat, JBoss, JONAS, Geronimo, and many others, use this cool technology to manage their resources.

如果ContainerServlet接口足夠好,可以讓Manager應用程序訪問Catalina的內部結構,那麼我們為什麼要關心JMX呢?因為JMX提供了比ContainerServlet更大的靈活性。

許多基於服務器的應用程序,如Tomcat、JBoss、JONAS、Geronimo等,都使用這項很酷的技術來管理它們的資源。

The JMX specification, currently at version 1.2.1, defines an open standard for managing Java objects. For example, Tomcat 4 and 5 use JMX to enable various objects (such as server, host, context, valve, and so on) in the servlet container to be flexibly and easily managed by management applications. The developers of Tomcat even made the effort to write the Admin application that acts as a management application.

JMX規範目前處於1.2.1版本,定義了一種管理Java對象的開放標準。

例如,Tomcat 4和5使用JMX來使得servlet容器中的各種對象(如服務器、主機、上下文、閥門等)能夠靈活、輕鬆地由管理應用程序管理。

Tomcat的開發人員甚至還費心編寫了一個作為管理應用程序的Admin應用程序。

A Java object that can be managed by JMX-compliant manager application is said to be a JMX manageable resource. In fact, a JMX manageable resource can also be an application, an implementation or a service, a device, a user, and so forth. A JMX manageable resource is written in Java or provides a Java wrapper.

一個可以由符合JMX管理器應用程序的管理的Java對象被稱為JMX可管理資源。

實際上,JMX可管理資源也可以是一個應用程序、一個實現或服務、一個設備、一個用户等等。

JMX可管理資源是用Java編寫的或提供Java包裝器的。

For a Java object to be a JMX manageable resource, you must create another object called Managed Bean or MBean. The org.apache.catalina.mbeans package contains a number of MBeans. ConnectorMBean, StandardEngineMBean, StandardHostMBean, StandardContextMBean are examples of the Managed Beans in this package. From their name you can guess that the ConnectMBean class is used to manage a connector, the StandardContextMBean class is for managing an org.apache.catalina.core.StandardContext instance, and so on. Of course, you can also write an MBean that manages more than one Java object if you want to.

要使一個Java對象成為JMX可管理資源,您必須創建另一個稱為Managed Bean或MBean的對象。

org.apache.catalina.mbeans包中包含了許多MBean。ConnectorMBean、StandardEngineMBean、StandardHostMBean、StandardContextMBean是該包中的Managed Bean的示例。

從它們的名稱可以猜到,ConnectMBean類用於管理連接器,StandardContextMBean類用於管理org.apache.catalina.core.StandardContext實例,等等。

當然,如果需要,您也可以編寫一個管理多個Java對象的MBean。

An MBean exposes the properties and methods of the Java object(s) it manages the management application. The management application itself does not have access to the managed Java objects directly. Therefore, you can choose any property and or method of a Java object that should be callable by the management application.

一個MBean向管理應用程序公開它管理的Java對象的屬性和方法。管理應用程序本身不能直接訪問被管理的Java對象。因此,您可以選擇任何一個Java對象的屬性和/或方法,使其可被管理應用程序調用。

Once you have an MBean class, you need to instantiate it and register it with another Java object referred to as the MBean server. The MBean server is a central registry for all the MBeans in an application. The management application accesses the MBeans through the MBean server. Drawing an analogy between JMX and a servlet application, the management application is equivalent to a web browser. The MBean server is like a servlet container; it provides access to the managed-resources to the client (the management application). The MBeans are servlets or JSP pages. Just like the web browser never touches a servlet/JSP page directly but only through a servlet container, a management application accesses the MBeans through the MBean server.

一旦您有了一個MBean類,您需要實例化它,並將其註冊到另一個被稱為MBean服務器的Java對象中。

MBean服務器是一個應用程序中所有MBean的中央註冊表。管理應用程序通過MBean服務器訪問MBeans。將JMX與servlet應用程序進行類比,管理應用程序相當於Web瀏覽器。

MBean服務器類似於servlet容器;它為客户端(管理應用程序)提供對被管理資源的訪問。MBeans就像servlet或JSP頁面。

就像Web瀏覽器永遠不直接訪問servlet/JSP頁面,而是通過servlet容器,管理應用程序通過MBean服務器訪問MBeans。

There are four types of MBeans: standard, dynamic, open, and model. Standard MBeans are the easiest to write among the four, but offer the least flexibility. The other three come with more flexibility and we're particularly interested in model MBeans because Catalina uses this type of MBeans. Standard MBeans are discussed next to give you the look and feel of writing an MBean. Afterwards, there is a discussion of model MBeans. We skip the dynamic and open MBeans because they are not relevant to this chapter. Interested readers are referred to the JMX 1.2.1 specification document for further details.

有四種類型的MBean:標準、動態、開放和模型。在這四種類型中,標準MBean是最容易編寫的,但提供的靈活性最少。

其他三種類型提供更大的靈活性,我們特別關注模型MBean,因為Catalina使用這種類型的MBean。

接下來將討論標準MBean,以便讓您瞭解編寫MBean的外觀和感覺。然後,將討論模型MBean。

我們跳過動態和開放MBean,因為它們與本章不相關。有興趣的讀者可以參考JMX 1.2.1規範文檔以獲取更多細節。

Architecturally, the JMX specification is divided into three levels, the instrumentation level, the agent level, and the distributed services level. The MBean server resides in the agent level and the MBeans in the instrumentation level. The distributed services level will be covered in the future version of the JMX specification.

從架構上講,JMX規範分為三個級別:

  • 儀器級別
  • 代理級別
  • 分佈式服務級別

MBean服務器位於代理級別,MBeans位於儀器級別。分佈式服務級別將在未來版本的JMX規範中介紹。

The instrumentation level of the specification defines the standard for writing JMX manageable resources, i.e. how to write MBeans. The agent level provides a specification for creating agents. An agent encapsulates an MBean server and services for handling MBeans. Agents and MBeans they manage normally reside in the same Java Virtual Machine. Because the JMX specification comes with a reference implementation, you do not need to write an MBean server of your own. The reference implementation provides a way of creating a default MBean server.

規範的儀器級別定義了編寫JMX可管理資源的標準,即如何編寫MBeans。

代理級別提供了創建代理的規範。代理封裝了一個MBean服務器和處理MBeans的服務。

代理和它們管理的MBeans通常駐留在同一個Java虛擬機中。

由於JMX規範附帶了一個參考實現,您不需要編寫自己的MBean服務器。參考實現提供了一種創建默認MBean服務器的方法。

Note Download the specification and reference implementation from http://java.sun.com/products/JavaManagement/download.html. MX4J, an open source version of JMX whose library is included in the software accompanying this book, is available from http://mx4j.sourceforge.net

注意:從http://java.sun.com/products/JavaManagement/download.html下載規範和參考實現。MX4J是JMX的開源版本,其庫包含在附帶本書的軟件中,可從http://mx4j.sourceforge.net獲取。

Warning The zip file that accompanies this book contains the mx4j.jar file that packages the version 2.0 beta 1 of MX4J, replacing the mx4j-jmx.jar file included in Tomcat 4.1.12. This was done in order for you to use the more recent version of JMX (version 1.2.1).

警告:隨本書附帶的zip文件包含mx4j.jar文件,該文件打包了MX4J的2.0 beta 1版本,取代了Tomcat 4.1.12中包含的mx4j-jmx.jar文件。

這樣做是為了讓您使用更新的JMX版本(1.2.1版)。

The JMX API(JMX API)

The reference implementation consists of a core Java library in the javax.management package and other packages specific to certain areas of JMX programming. This section discusses some of the more important types in the API.

參考實現由javax.management包中的核心Java庫和其他特定於某些JMX編程領域的包組成。

本節討論了API中一些較重要的類型。

MBeanServer

The javax.management.MBeanServer interface represents an MBean server. To create an instance of MBeanServer, simply use one of the methods in the javax.management.MBeanServerFactory class, such as the createMBean method.

javax.management.MBeanServer接口表示一個MBean服務器。

要創建MBeanServer的實例,只需使用javax.management.MBeanServerFactory類中的方法之一,例如createMBean方法。

To register an MBean with an MBeanServer, call the registerMBean method on the MBeanServer instance. The following is the signature of the registerMBean method.

要將MBean註冊到MBeanServer中,調用MBeanServer實例上的registerMBean方法。

以下是registerMBean方法的簽名。

public ObjectInstance registerMBean(java.lang.Object object,
 ObjectName name) throws InstanceAlreadyExistsException,
 MBeanRegistrationException, NotCompliantMBeanException

To the registerMBean method you pass the MBean instance you want to register and the ObjectName instance. An ObjectName instance is like a key in a HashMap; it uniquely identifies an MBean. The registerMBean method returns an ObjectInstance. The javax.management.ObjectInstance class encapsulates an object name of an MBean and its class name.

通過registerMBean方法,您需要傳遞要註冊的MBean實例和ObjectName實例。

ObjectName實例類似於HashMap中的鍵;它唯一標識一個MBean。

registerMBean方法返回一個ObjectInstance。javax.management.ObjectInstance類封裝了一個MBean的對象名稱和其類名稱。

To retrieve an MBean or a set of MBeans matching a pattern, the MBeanServer interface provides two methods: queryNames and queryMBeans. The queryNames method returns a java.util.Set containing the object names of the MBeans matching the specified pattern object name. Here is the signature of the queryName method:

要檢索匹配模式的MBean或一組MBean,MBeanServer接口提供了兩種方法:queryNames和queryMBeans。queryNames方法返回一個包含與指定模式對象名稱匹配的MBean對象名稱的java.util.Set。

以下是queryName方法的簽名:

public java.util.Set queryNames(ObjectName name, QueryExp query)

The query argument specifies the filtering criteria.

查詢參數指定過濾標準。

If the name argument is null or no domain and key properties are specified, all the ObjectName instances of the registered MBeans will be returned. If the query is null, no filtering is applied.

如果 name 參數為空或未指定域和鍵屬性,則將返回已註冊 MBeans 的所有 ObjectName 實例。如果查詢參數為空,則不會應用過濾功能。

The queryMBeans method is similar to queryNames. However, it returns a java.util.Set containing ObjectInstance objects for the selected MBeans. The queryMBeans method has the following signature:

queryMBeans 方法與 queryNames 類似。

不過,它返回的是一個 java.util.Set 集合,其中包含所選 MBeans 的 ObjectInstance 對象。queryMBeans 方法的簽名如下:

public java.util.Set queryMBeans(ObjectName name, QueryExp query)

Once you have the object name of the MBean you want, you can manipulate the property of the managed resource or invoke its method exposed in the MBean.

一旦你獲得了想要的 MBean 的對象名稱,你就可以操作託管資源的屬性或調用 MBean 中公開的方法。

You can call any method of the registered MBeans by calling the MBeanServer interface's invoke method. The MBeanServer interface's getAttribute and setAttribute methods are used for getting and setting a property of a registered MBean.

你可以通過調用 MBeanServer 接口的 invoke 方法來調用已註冊的 MBeans 的任何方法。

MBeanServer 接口的 getAttribute 和 setAttribute 方法用於獲取和設置已註冊 MBean 的屬性。

ObjectName

An MBean server is a registry for MBeans. Each of the MBeans in an MBean server is uniquely identified by an object name, just like an entry in a HashMap is uniquely identified by a key.

MBean 服務器是 MBeans 的註冊表。

MBean 服務器中的每個 MBean 都由對象名稱唯一標識,就像 HashMap 中的條目由鍵唯一標識一樣。

An object name is represented by the javax.management.ObjectName class. An object name consists of two parts: a domain and a set of key/value pairs. A domain is a string, and can be a blank string. In an object name, the domain is followed by a colon and one or more key/value pairs. A key is a non-blank string that may not contain any of the following characters: equal sign, comma, colon, asterisk, and question mark. The same key may only occur once in an object name.

對象名稱由 javax.management.ObjectName 類表示。

對象名稱由兩部分組成:域和一組鍵/值對。域是一個字符串,可以是空字符串。在對象名稱中,域後面跟着一個冒號和一個或多個鍵/值對。

鍵是一個非空字符串,不得包含以下任何字符:等號、逗號、冒號、星號和問號。同一個鍵在對象名稱中只能出現一次。

A key and its value are separated by an equal sign, and two key/value pairs are separated by a comma. For example, the following is a valid object name with two keys:

鍵及其值之間用等號分隔,兩個鍵/值對之間用逗號分隔。

例如,以下是一個具有兩個鍵的有效對象名稱:

myDomain:type=Car,color=blue

An ObjectName instance can also represent a property pattern for searching MBeans in an MBean server. An ObjectName that is a pattern uses a wildcard in its domain part or key/value pairs. A pattern ObjectName may have zero or more keys.

ObjectName 實例還可以表示用於在 MBean 服務器中搜索 MBeans 的屬性模式。

模式 ObjectName 在其域部分或鍵/值對中使用通配符。模式 ObjectName 可能具有零個或多個鍵。

Standard MBeans(標準 MBeans)

Standard MBeans are the simplest MBeans. To manage a Java object using a standard MBean, here is what you need to do:

標準MBean是最簡單的MBean。

要使用標準MBean管理一個Java對象,需要按照以下步驟進行操作:

  • Create an interface named after your Java class plus the suffix MBean. For example, if the Java class you want to manage is called Car, the interface is called CarMBean.
  • Modify your Java class so that it implements the interface you've created.
  • Create an agent. The agent class must contain an MBeanServer.
  • Create an ObjectName for your MBean.
  • Instantiate the MBeanServer.
  • Register the MBean in the MBeanServer.
  • 創建一個以您的Java類名稱加上後綴MBean的接口。例如,如果要管理的Java類名為Car,則接口名為CarMBean。
  • 修改您的Java類,使其實現您創建的接口。
  • 創建一個代理類。該代理類必須包含一個MBeanServer。
  • 為您的MBean創建一個ObjectName。
  • 實例化MBeanServer。
  • 將MBean註冊到MBeanServer中。

The standard MBeans are the easiest to write, but using them requires your classes be modified. While modifying the classes is okay in some projects, in others (especially when the number of classes is high) this is not acceptable. Other types of MBeans allow you to manage your objects without modifying your classes.

標準MBean是編寫最簡單的MBean,但使用它們需要修改您的類。

在某些項目中修改類是可以接受的,但在其他項目中(特別是類數量較多時)這是不可接受的。

其他類型的MBean可以讓您在不修改類的情況下管理對象。

As an example of a standard MBean, consider the following Car class that you want to be JMX-manageable:

以一個標準MBean的例子來説明,考慮以下要使其能夠通過JMX管理的Car類:

package ex20.pyrmont.standardmbeantest;

package ex20.pyrmont.standardmbeantest;
public class Car {
 private String color = "red";
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
 public void drive() {
 System.out.println("Baby you can drive my car.");
 }
}

The first step you need to take is modify it so that it implements the CarMBean interface. The new Car class is given in Listing 20.1:

您需要做的第一步是修改該類,使其實現 CarMBean 接口。新的 Car 類如清單 20.1 所示:

Listing 20.1: The modified Car class

清單 20.1:修改後的 Car 類

package ex20.pyrmont.standardmbeantest;
public class Car implements CarMBean {
 private String color = "red";
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
 public void drive() {
 System.out.println("Baby you can drive my car.");
 }
}

Now, create the CarMBean interface in Listing 20.2

現在,創建清單 20.2 中的 CarMBean 接口

Listing 20.2: The CarMBean interface

清單 20.2:CarMBean 接口

package ex20.pyrmont.standardmbeantest;
public interface CarMBean {
 public String getColor();
 public void setColor(String color);
 public void drive();
}

Basically, in the interface you declare all the methods that you want the Car class to expose. In this example, the CarMBean interface lists all the methods in the Car class. If, say, you don't want the drive method to be available to the management application, all you need to do is remove its definition from the CarMBean interface.

基本上,在接口中聲明瞭你希望 Car 類公開的所有方法。

在這個例子中,CarMBean 接口列出了 Car 類中的所有方法。

如果你不想讓駕駛方法對管理應用程序可用,你只需要從 CarMBean 接口中移除它的定義。

Finally, Listing 20.3 offers the StandardAgent class that is used to create a standard MBean and manage the Car object

最後,第20.3節提供了用於創建標準 MBean 並管理 Car 對象的 StandardAgent 類。

Listing 20.3: The StandardAgent class

第20.3節:StandardAgent 類


package ex20.pyrmont.standardmbeantest;
        import javax.management.Attribute;
        import javax.management.ObjectName;
        import javax.management.MBeanServer;
        import javax.management.MBeanServerFactory;
public class StandardAgent {
    private MBeanServer mBeanServer = null;
    public StandardAgent() {
        mBeanServer = MBeanServerFactory.createMBeanServer();
    }
    public MBeanServer getMBeanServer() {
        return mBeanServer;
    }
    public ObjectName createObjectName(String name) {
        ObjectName objectName = null;
        try {
            objectName = new ObjectName(name);
        }
        catch (Exception e) {
        }
        return objectName;
    }
    private void createStandardBean(ObjectName objectName,
                                    String managedResourceClassName) {
        try {
            mBeanServer.createMBean(managedResourceClassName, objectName);
        }
        catch(Exception e) {
        }
    }
    public static void main(String[] args) {
        StandardAgent agent = new StandardAgent();
        MBeanServer mBeanServer = agent.getMBeanServer();
        String domain = mBeanServer.getDefaultDomain();
        String managedResourceClassName =
                "ex20.pyrmont.standardmbeantest.Car";
        ObjectName objectName = agent.createObjectName(domain + ":type=" +
                managedResourceClassName);
        agent.createStandardBean(objectName, managedResourceClassName);
        // manage MBean
        try {
            Attribute colorAttribute = new Attribute("Color","blue");
            mBeanServer.setAttribute(objectName, colorAttribute);
            System.out.println(mBeanServer.getAttribute(objectName,
                    "Color"));
            mBeanServer.invoke(objectName,"drive",null,null);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The StandardAgent class is an agent that will instantiate an MBean server and use it to register a CarMBean. The first thing to note is the mBeanServer variable, to which the StandardAgent class's constructor assigns an MBeanServer. The constructor calls the createMBeanServer method of the MBeanServerFactory class.

StandardAgent 類是一個將實例化 MBean 服務器並用於註冊 CarMBean 的代理。

首先要注意的是 mBeanServer 變量,StandardAgent 類的構造函數會為該變量分配一個 MBeanServer。

構造函數調用 MBeanServerFactory 類的 createMBeanServer 方法。

public StandardAgent() {
 mBeanServer = MBeanServerFactory.createMBeanServer();
 }

The createMBeanServer method returns a default MBeanServer object implemented by the JMX reference implementation. An advanced JMX programmer may wish to provide his/her own MBeanServer implementation. For this book, however, we're not interested in doing so.

createMBeanServer方法返回由JMX參考實現實現的默認MBeanServer對象。

高級的JMX程序員可能希望提供自己的MBeanServer實現。然而,在本書中,我們對此不感興趣。

The createObjectName method in the StandardAgent class in Listing 20.3 returns an instance of ObjectName based on the String argument passed to the method. The createStandardMBean method in StandardAgent calls the createMBean method of MBeanServer. The createMBean method accepts the class name of the managed resource and the ObjectName instance that uniquely identifies the created MBean for the managed resource. The createMBean method also registers the created MBean in the MBeanServer. Because a standard MBean follows a certain naming convention, you don't need to supply the MBean type name to the createMBean method. If the managed resource's class name is Car, then its MBean will be CarMBean.

StandardAgent類中的createObjectName方法在Listing 20.3中根據傳遞給該方法的字符串參數返回一個ObjectName實例。

StandardAgent中的createStandardMBean方法調用MBeanServer的createMBean方法。

createMBean方法接受託管資源的類名和唯一標識創建的MBean的ObjectName實例。

createMBean方法還在MBeanServer中註冊創建的MBean。

由於標準MBean遵循特定的命名約定,您不需要向createMBean方法提供MBean類型名稱。

如果託管資源的類名是Car,則其MBean將是CarMBean。

The main method of StandardAgent starts off by creating an instance of StandardAgent and calls its getMBeanServer method to obtain a reference to the MBeanServer instance inside the StandardAgent.

StandardAgent的main方法首先創建StandardAgent的實例,並調用其getMBeanServer方法以獲取StandardAgent內部的MBeanServer實例的引用。

StandardAgent agent = new StandardAgent();
 MBeanServer mBeanServer = agent.getMBeanServer();

It then creates an ObjectName for the CarMBean. The MBeanServer's default domain is used as the domain for the ObjectName. A key named type is appended to the domain. The value for type is the fully qualified name of the managed resource.

然後,它會為 CarMBean 創建一個 ObjectName。

MBeanServer 的默認域被用作 ObjectName 的域。名為 type 的鍵被附加到域中。

type 的值是受管資源的全稱。

String domain = mBeanServer.getDefaultDomain();
 String managedResourceClassName =
 "ex20.pyrmont.standardmbeantest.Car";
 ObjectName objectName = agent.createObjectName(domain + ":type=" +
 managedResourceClassName);

The main method then calls the createStandardBean method, passing the object name and the managed resource class name.

然後,main 方法調用 createStandardBean 方法,並傳遞對象名稱和託管資源類名稱。

agent.createStandardBean(objectName, managedResourceClassName);

Next, the main method manages the Car object through the CarMBean instance. It creates an Attribute object called colorAttribute to represent the Color attribute and sets the value to blue. It then invokes the setAttribute method passing the objectName and colorAttribute. It then invokes the drive method using the invoke method on the MBeanServer object.

接下來,主方法通過CarMBean實例來管理Car對象。

它創建了一個名為colorAttribute的Attribute對象來表示顏色屬性,並將值設置為藍色。

然後,它通過傳遞objectName和colorAttribute來調用setAttribute方法。

然後,它使用MBeanServer對象上的invoke方法來調用drive方法。

Model MBeans(MBeans 模式)

Model MBeans provide flexibility. They are harder to program than standard MBeans, but you do not need to modify your Java classes for the objects to be manageable. Using model MBeans is highly preferable if modifying the existing classes is not an option.

Model MBeans提供了靈活性。

它們比標準MBeans更難編程,但您無需修改Java類即可管理對象。

如果修改現有類不是一個選項,那麼使用模型MBeans是非常可取的。

Using model MBeans is different from using standard MBeans. When employing a standard MBean to manage your resource, you write an interface that must be implemented by the managed resource. When using a model MBean, you do not write any interface. Instead, the javax.management.modelmbean.ModelMBean interface is provided for you that represents a model MBean. You just need to have an implementation for this interface. Luckily, JMX comes with the javax.management.modelmbean.RequiredModelMBean class, the default implementation of ModelMBean. You can instantiate the RequiredModelMBean class or its subclass.

使用模型MBeans與使用標準MBeans不同。

當使用標準MBean來管理資源時,您需要編寫一個由受管資源實現的接口。而使用模型MBean時,您不需要編寫任何接口。相反,javax.management.modelmbean.ModelMBean接口為您提供了一個表示模型MBean的接口。您只需要為此接口編寫一個實現即可。

幸運的是,JMX提供了javax.management.modelmbean.RequiredModelMBean類,它是ModelMBean的默認實現。您可以實例化RequiredModelMBean類或其子類。

Note Other implementation classes for the ModelMBean interface are also possible. For example, the Commons Modeler library, which we will discuss in the next section, has its own implementation class that does not extend RequiredModelMBean.

注意,ModelMBean接口的其他實現類也是可能的。
例如,我們將在下一節中討論的Commons Modeler庫有自己的實現類,它不繼承RequiredModelMBean。

The greatest challenge in writing a model MBean is telling your ModelMBean object which attributes and operations in the managed resource should be exposed to an agent. You achieve this by creating a javax.management.modelmbean.ModelMBeanInfo object. A ModelMBeanInfo object describes the constructors, attributes, operations, and event listeners exposed to an agent. Constructing a ModelMBeanInfo object can be a tedious task (see the example in this section), but once you have one, you just need to associate it with your ModelMBean object.

編寫模型MBean的最大挑戰是告訴您的ModelMBean對象應該將受管資源的哪些屬性和操作暴露給代理。

您可以通過創建一個javax.management.modelmbean.ModelMBeanInfo對象來實現這一點。ModelMBeanInfo對象描述了構造函數、屬性、操作和事件監聽器對代理可見。

構造一個ModelMBeanInfo對象可能是一項繁瑣的任務(請參見本節的示例),但一旦擁有了一個,您只需要將其與您的ModelMBean對象關聯起來即可。

Using RequiredModelMBean as your ModelMBean implementation, there are two ways of associating your ModelMBean with a ModelMBeanInfo:

使用RequiredModelMBean作為您的ModelMBean實現,有兩種將您的ModelMBean與ModelMBeanInfo關聯的方式:

  1. By passing the ModelMBeanInfo object to the RequiredModelMBean constructor.
  2. By passing the ModelMBeanInfo object to the setModelMBeanInfo method on the RequiredModelMBean object.

After constructing a ModelMBean, you must associate your managed resource with it
by calling the setManagedResource method of the ModelMBean interface. This
method has the following signature:

public void setManagedResource(java.lang.Object managedResource, java.lang.String managedResourceType) throws MBeanException, RuntimeOperationsException, InstanceNotFoundException, InvalidTargetObjectTypeException

The value of the managedResourceType argument can be one of the following: ObjectReference, Handle, IOR, EJBHandle, or RMIReference. Currently, only ObjectReference is supported.

Then, of course, you still have to create an ObjectName and register the model MBean with the MBean server.

This section provides an example of using a model MBean with the same Car object as the one used in the standard MBean example. Before we discuss the example, however, let's look at the ModelMBeanInfo interface whose instance describes the attributes and operations that your managed resource will expose.

MBeanInfo and ModelMBeanInfo(MBeanInfo 和 ModelMBeanInfo)

The javax.management.mbean.ModelMBeanInfo interface describes the constructors, attributes, operations, and listeners exposed by a ModelMBean. A constructor is represented by the javax.management.modelmbean.ModelMBeanConstructorInfo class, an attribute by the javax.management.modelmbean.ModelMBeanAttributeInfo class, an operation by the javax.management.modelmbean.ModelMBeanOperationInfo class, and a listener by the javax.management.modelmbean.ModelMBeanNotificationInfo class. In this chapter, we're only interested in the attributes and operations.

javax.management.mbean.ModelMBeanInfo接口描述了ModelMBean所暴露的構造函數、屬性、操作和監聽器。javax.management.modelmbean.ModelMBeanConstructorInfo類表示構造函數,javax.management.modelmbean.ModelMBeanAttributeInfo類表示屬性,javax.management.modelmbean.ModelMBeanOperationInfo類表示操作,javax.management.modelmbean.ModelMBeanNotificationInfo類表示監聽器。

在本章中,我們只關注屬性和操作。

JMX provides a default implementation of ModelMBeanInfo: the javax.management.modelmbean.ModelMBeanInfoSupport class. Here is the signature of the ModelMBeanInfoSupport class's constructor that we will use in this example:

JMX提供了ModelMBeanInfo的默認實現:javax.management.modelmbean.ModelMBeanInfoSupport類。

以下是我們在本示例中將使用的ModelMBeanInfoSupport類構造函數的簽名:

public ModelMBeanInfoSupport(java.lang.String className, java.lang.String description, ModelMBeanAttributeInfo[] attributes, ModelMBeanConstructorInfo[] constructors, ModelMBeanOperationInfo[] operations, ModelMBeanNotificationInfo[] notifications)

You construct a ModelMBeanAttributeInfo object by using its constructor:

您可以使用以下構造函數創建ModelMBeanAttributeInfo對象:

public ModelMBeanAttributeInfo(java.lang.String name,
 java.lang.String type, java.lang.String description,
 boolean isReadable, boolean isWritable,
 boolean isIs, Descriptor descriptor)
 throws RuntimeOperationsException

Here is the list of parameters:

以下是參數列表:

  • name. The name of the attribute
  • type. The type or class name of the attribute
  • description. The description of the attribute.
  • isReadable. true if the attribute has a getter method, false otherwise.
  • isWritable. true if the attribute has a setter method, false otherwise.
  • isIs. true if the attribute has an is getter, false otherwise.
  • descriptor. An instance of Descriptor containing the appropriate metadata for
    this instance of the Attribute. If it is null then a default descriptor will be
    created.
  • name:屬性的名稱
  • type:屬性的類型或類名
  • description:屬性的描述
  • isReadable:如果屬性有getter方法,則為true;否則為false
  • isWritable:如果屬性有setter方法,則為true;否則為false
  • isIs:如果屬性有is getter方法,則為true;否則為false
  • descriptor:包含此屬性實例的適當元數據的Descriptor實例。如果為null,則將創建一個默認的描述符。

You create a ModelMBeanOperationInfo object using the following constructor:

您可以使用以下構造函數創建ModelMBeanOperationInfo對象:

public ModelMBeanOperationInfo(java.lang.String name, java.lang.String description, MBeanParameterInfo[] signature, java.lang.String type, int impact, Descriptor) throws RuntimeOperationsException

Here is the list of parameters:

以下是參數列表:

  • name. The name of the method.
  • description. The description of the operation.
  • signature, an array of MBeanParameterInfo objects describing the parameters of the method.
  • type. The type of the method's return value.
  • impact. The impact of the method. The value is one of the following: INFO, ACTION, ACTION_INFO, UNKNOWN.
  • descriptor. An instance of Descriptor containing the appropriate metadata, for this instance of the MBeanOperationInfo.
  • name:方法的名稱
  • description:方法的描述
  • signature:描述方法參數的MBeanParameterInfo對象數組
  • type:方法的返回值類型
  • impact:方法的影響。值為以下之一:INFO、ACTION、ACTION_INFO、UNKNOWN
  • descriptor:包含此MBeanOperationInfo實例的適當元數據的Descriptor實例。

ModelMBean Example( ModelMBean 示例)

This example shows how to use a model MBean to manage a Car object whose class is presented in Listing 20.4.

本例展示瞭如何使用模型 MBean 來管理 "汽車 "對象,其類如清單 20.4 所示。

Listing 20.4: The Car class

清單 20.4:汽車類

package ex20.pyrmont.modelmbeantest1;
public class Car {
 private String color = "red";
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
 public void drive() {
 System.out.println("Baby you can drive my car.");
 }
}

For a model MBean, you don't need to write an interface as in the case of a standard MBean. You simply instantiate the RequiredMBean class. Listing 20.5 provides the ModelAgent class that is used to create the MBean and manage a Car object.

對於模型 MBean,您不需要像編寫標準 MBean 那樣編寫接口。

您只需實例化 RequiredMBean 類。清單 20.5 提供了用於創建 MBean 和管理 Car 對象的 ModelAgent 類。

Listing 20.5: The ModelAgent class

清單 20.5:ModelAgent 類


package ex20.pyrmont.modelmbeantest1;
        import javax.management.Attribute;
        import javax.management.Descriptor;
        import javax.management.MalformedObjectNameException;
        import javax.management.MBeanOperationInfo;
        import javax.management.MBeanParameterInfo;
        import javax.management.MBeanServer;
        import javax.management.MBeanServerFactory;
        import javax.management.ObjectName;
        import javax.management.modelmbean.DescriptorSupport;
        import javax.management.modelmbean.ModelMBean;
        import javax.management.modelmbean.ModelMBeanAttributeInfo;
        import javax.management.modelmbean.ModelMBeanInfo;
        import javax.management.modelmbean.ModelMBeanInfoSupport;
        import javax.management.modelmbean.ModelMBeanOperationInfo;
        import javax.management.modelmbean.RequiredModelMBean;
public class ModelAgent {
    private String MANAGED_CLASS_NAME =
            "ex20.pyrmont.modelmbeantest1.Car";
    private MBeanServer mBeanServer = null;
    public ModelAgent() {
        mBeanServer = MBeanServerFactory.createMBeanServer();
    }
    public MBeanServer getMBeanServer() {
        return mBeanServer;
    }
    private ObjectName createObjectName(String name) {
        ObjectName objectName = null;
        try {
            objectName = new ObjectName(name);
        }
        catch (MalformedObjectNameException e) {
            e.printStackTrace();
        }
        return objectName;
    }
    private ModelMBean createMBean(ObjectName objectName,
                                   String mbeanName) {
        ModelMBeanInfo mBeanInfo = createModelMBeanInfo(objectName,
                mbeanName);
        RequiredModelMBean modelMBean = null;
        try {
            modelMBean = new RequiredModelMBean(mBeanInfo);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return modelMBean;
    }
    private ModelMBeanInfo createModelMBeanInfo(ObjectName
                                                        inMbeanObjectName, String inMbeanName) {
        ModelMBeanInfo mBeanInfo = null;
        ModelMBeanAttributeInfo[] attributes = new
                ModelMBeanAttributeInfo[1];
        ModelMBeanOperationInfo[] operations = new
                ModelMBeanOperationInfo[3];
        try {
            attributes[0] = new ModelMBeanAttributeInfo("Color",
                    "java,lang.String",
                    "the color.", true, true, false, null);
            operations[0] = new ModelMBeanOperationInfo("drive",
                    "the drive method",
                    null, "void", MBeanOperationInfo.ACTION, null);
            operations[1] = new ModelMBeanOperationInfo("getColor",
                    "get color attribute",
                    null, "java.lang.String", MBeanOperationInfo.ACTION, null);
            Descriptor setColorDesc = new DescriptorSupport(new String[] {
                    "name=setColor", "descriptorType=operation",
                    "class=" + MANAGED_CLASS_NAME, "role=operation"});
            MBeanParameterInfo[] setColorParams = new MBeanParameterInfo[] {
                    (new MBeanParameterInfo("new color", "java.lang.String",
                            "new Color value") )} ;
            operations[2] = new ModelMBeanOperationInfo("setColor",
                    "set Color attribute", setColorParams, "void",
                    MBeanOperationInfo.ACTION, setColorDesc);
            mBeanInfo = new ModelMBeanInfoSupport(MANAGED_CLASS_NAME,
                    null, attributes, null, operations, null);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return mBeanInfo;
    }
    public static void main(String[] args) {
        ModelAgent agent = new ModelAgent();
        MBeanServer mBeanServer = agent.getMBeanServer();
        Car car = new Car();
        String domain = mBeanServer.getDefaultDomain();
        ObjectName objectName = agent.createObjectName(domain +
                ":type=MyCar");
        String mBeanName = "myMBean";
        ModelMBean modelMBean = agent.createMBean(objectName, mBeanName);
        try {
            modelMBean.setManagedResource(car, "ObjectReference");
            mBeanServer.registerMBean(modelMBean, objectName);
        }
        catch (Exception e) {
        }
        // manage the bean
        try {
            Attribute attribute = new Attribute("Color", "green");
            mBeanServer.setAttribute(objectName, attribute);
            String color = (String) mBeanServer.getAttribute(objectName,
                    "Color");
            System.out.println("Color:" + color);
            attribute = new Attribute("Color", "blue");
            mBeanServer.setAttribute(objectName, attribute);
            color = (String) mBeanServer.getAttribute(objectName, "Color");
            System.out.println("Color:" + color);
            mBeanServer.invoke(objectName, "drive", null, null);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

As you can see, writing model MBeans requires a lot of work, especially in declaring all the attributes and operations exposed by a managed resource. The next section will look at the Commons Modeler library that helps you write model MBeans faster.

正如您所見,編寫模型 MBeans 需要大量工作,特別是在聲明受託資源公開的所有屬性和操作方面。

下一節將介紹 Commons Modeler 庫,它可以幫助您更快地編寫模型 MBeans。

Commons Modeler( 共用建模器)

The Commons Modeler library is part of the Apache Software Foundation's Jakarta project. It provides easy ways of writing model MBeans. The greatest help you can get from it is the fact that you don't need to write code to create a ModelMBeanInfo object.

Commons Modeler 庫是 Apache 軟件基金會的 Jakarta 項目的一部分。

它提供了編寫模型 MBeans 的簡便方法。

您可以從中獲得的最大幫助是,您無需編寫代碼來創建 ModelMBeanInfo 對象。

Recall from the previous example that to construct a RequiredModelMBean instance, you need to create a ModelMBeanInfo object that you pass to the RequiredModelMBean class's constructor:

從前面的例子中可以回憶起,要構建一個RequiredModelMBean實例,你需要創建一個ModelMBeanInfo對象,並將其傳遞給RequiredModelMBean類的構造函數。

ModelMBeanInfo mBeanInfo = createModelMBeanInfo(objectName,
 mbeanName);
 RequiredModelMBean modelMBean = null;
 try {
 modelMBean = new RequiredModelMBean(mBeanInfo);
 }
 ...

The Commons Modeler library is part of the Apache Software Foundation's Jakarta project. It provides easy ways of writing model MBeans. The greatest help you can get from it is the fact that you don't need to write code to create a ModelMBeanInfo object.

Commons Modeler庫是Apache軟件基金會的Jakarta項目的一部分。

它提供了編寫模型MBean的簡單方式。

它最大的幫助在於你不需要編寫代碼來創建一個ModelMBeanInfo對象。

Recall from the previous example that to construct a RequiredModelMBean instance, you need to create a ModelMBeanInfo object that you pass to the RequiredModelMBean class's constructor:

回想一下前面的例子,要構造一個RequiredModelMBean實例,你需要創建一個ModelMBeanInfo對象,然後將其傳遞給RequiredModelMBean類的構造函數:

MBean Descriptor(MBean 描述符)

An MBean descriptor is an XML document that describes the model MBeans managed by the MBean server. An MBean descriptor starts with the following header:

MBean描述符是一個XML文檔,用於描述MBean服務器管理的模型MBeans。

MBean描述符以以下標頭開始:

<?xml version="1.0"?>
<!DOCTYPE mbeans-descriptors PUBLIC
"-//Apache Software Foundation//DTD Model MBeans Configuration File"
"http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd">

It is followed by the mbeans-descriptors root element:

其後是 mbeans-descriptors 根元素:

<mbeans-descriptors>
...
</mbeans-descriptors>

Inside the opening and closing mbeans-descriptors tags are mbean elements, each of which represents a model MBean. The mbean element can contain elements that represent attributes, operations, constructors, and notification. The following subsections discuss three elements that you need to understand Tomcat's MBean descriptor.

在開放和關閉的mbeans-descriptors標籤內部,包含着mbean元素,每個元素代表一個模型MBean。

mbean元素可以包含代表屬性、操作、構造函數和通知的元素。

接下來的小節將討論三個元素,你需要了解Tomcat的MBean描述符。

mbean

An mbean element describes a model MBean and includes the information to construct the corresponding ModelMBeanInfo object. The mbean element has the following definition:

mbean 元素描述一個模型 MBean,幷包含用於構建相應 ModelMBeanInfo 對象的信息。

mbean 元素的定義如下:

<!ELEMENT mbean (descriptor?, attribute*, constructor*, notification*,
operation*)>

The mbean element definition specifies that an mbean element can contain an optional descriptor element, zero or more attribute elements, zero or more constructor elements, zero or more notification elements, and zero or more operation elements.

mbean元素定義指定mbean元素可以包含一個可選的描述符元素,零個或多個屬性元素,零個或多個構造函數元素,零個或多個通知元素以及零個或多個操作元素。

An mbean element can have the following attributes:

mbean元素可以具有以下屬性:

  • className. Fully qualified Java class name of the ModelMBean implementation. If this attribute is not present, the org.apache.commons.modeler.BaseModelMBean will be used.
  • description. A description of this model MBean.
  • domain. The MBean server's domain in which the ModelMBean created by this managed bean should be registered, when creating its ObjectName.
  • group. Optional name of a "grouping classification" that can be used to select groups of similar MBean implementation classes.
  • name. A name that uniquely identifies this model MBean. Normally, the base class name of the corresponding server component is used.
  • type. Fully qualified Java class name of the managed resource implementation class.
  • className. ModelMBean 實現的完全限定Java類名。

    • 如果沒有提供此屬性,則將使用 org.apache.commons.modeler.BaseModelMBean
  • description. 此模型MBean的描述。
  • domain. 創建由該託管bean創建的ModelMBean時,應將其註冊到的MBean服務器的域。
  • group. 可選的“分組分類”的名稱,可用於選擇相似MBean實現類的組。
  • name. 唯一標識此模型MBean的名稱。通常使用相應服務器組件的基類名稱。
  • type. 託管資源實現類的完全限定Java類名。

attribute

You use the attribute element to describe a JavaBeans property of an MBean. The attribute element can have an optional descriptor element and can have the following attributes.

你可以使用attribute元素來描述MBean的JavaBeans屬性。attribute元素可以包含一個可選的descriptor元素,並且可以具有以下屬性。

  • description. A description of this attribute.
  • displayName. The display name of this attribute.
  • getMethod. The getter method of the property represented by the attributeelement.
  • is. A boolean value indicating whether or not this attribute is a boolean with an is getter method. By default, the value of the is attribute is false.
  • name. The name of this JavaBeans property.
  • readable. A boolean value indicating whether or not this attribute is readable by management applications. By default, the value of readable is true.
  • setMethod. The setter method of the property represented by this attributeelement.
  • type. The fully qualified Java class name of this attribute.
  • writeable. A boolean value indicating whether or not this attribute can be written by management applications. By default, this is set to true.
  • description。對此屬性的描述。
  • displayName。此屬性的顯示名稱。
  • getMethod。由attribute元素表示的屬性的getter方法。
  • is。一個布爾值,指示此屬性是否具有一個is getter方法。默認情況下,is屬性的值為false。
  • name。此JavaBeans屬性的名稱。
  • readable。一個布爾值,指示管理應用程序是否可以讀取此屬性。默認情況下,readable的值為true。
  • setMethod。由attribute元素表示的屬性的setter方法。
  • type。此屬性的完全限定的Java類名稱。
  • writeable。一個布爾值,指示管理應用程序是否可以寫入此屬性。默認情況下,此值為true。

    operation

The operation element describes a public method of the model MBean exposed to management applications. It can have zero or more parameter subelements and the following attributes:

操作元素描述了暴露給管理應用程序的模型 MBean 的公共方法。它可以具有零個或多個參數子元素和以下屬性:

  • description. The description of this operation.
  • impact. This attribute indicates the impact of this method. The possible values are ACTION (write like), ACTION-INFO (write+read like), INFO (read like), or UNKNOWN.
  • name. The name of this public method.
  • returnType. The fully qualified Java class name of the return type of this method.
  • description:此操作的描述。
  • impact:此方法的影響。可能的值有 ACTION(類似寫操作),ACTION-INFO(類似寫操作和讀操作),INFO(類似讀操作)或 UNKNOWN。
  • name:此公共方法的名稱。
  • returnType:此方法返回類型的完全限定 Java 類名。

    parameter

The parameter element describes a parameter passed to a constructor or an operation. It can have the following attributes:

參數元素描述傳遞給構造函數或操作的參數。它可以有以下屬性:

  • description. The description of this parameter.
  • name. The name of this parameter.
  • type. The fully qualified Java class name of this parameter.
  • description(描述)。該參數的描述。
  • name(名稱)。該參數的名稱。
  • type(類型)。此參數的完整 Java 類名。

    Example mbean Element(mbean 元素示例)

Catalina comes with a number of model MBeans that are all declared in the mbean-descriptors.xml file in the org.apache.catalina.mbeans package. Listing 20.6 offers the declaration of the StandardServer MBean in Tomcat 4.

Catalina提供了一些模型MBean,這些MBean都在org.apache.catalina.mbeans包的mbean-descriptors.xml文件中聲明。

圖表20.6展示了Tomcat 4中StandardServer MBean的聲明。

Listing 20.6: The declaration of the StandardServer MBean

清單 20.6:StandardServer MBean 的聲明

<mbean name="StandardServer"
 className="org.apache.catalina.mbeans.StandardServerMBean"
 description="Standard Server Component"
 domain="Catalina"
 group="Server"
 type="org.apache.catalina.core.StandardServer">
 <attribute name="debug"
 description="The debugging detail level for this component"
 type="int"/>
 <attribute name="managedResource"
 description="The managed resource this MBean is associated with"
 type="java.lang.Object"/>
 <attribute name="port"
 description="TCP port for shutdown messages"
 type="int"/>
 <attribute name="shutdown"
 description="Shutdown password"
 type="java.lang.String"/>
 <operation name="store"
 description="Save current state to server.xml file"
 impact="ACTION"
 returnType="void">
 </operation>
</mbean>

The mbean element in Listing 20.6 declares a model MBean uniquely identified as StandardServer. This MBean is represented by the org.apache.catalina.mbeans.StandardServerMBean and manages an instance of org.apache.catalina.core.StandardServer. The domain is Catalina and the group is Server.

在第20.6節的代碼中,mbean元素聲明瞭一個被唯一標識為StandardServer的模型MBean。這個MBean由org.apache.catalina.mbeans.StandardServerMBean表示,並管理着一個org.apache.catalina.core.StandardServer的實例。域名是Catalina,組名是Server。

There are four properties exposed by the model MBean: debug, managedResource, port, and shutdown, as described by the four attribute elements nested inside the mbean element. The MBean also exposes one method, store, which is described by the operation element.

模型MBean公開了四個屬性:debug、managedResource、port和shutdown,這些屬性由嵌套在mbean元素內部的四個attribute元素描述。該MBean還公開了一個名為store的方法,該方法由operation元素描述。

Writing Your Own Model MBean Class(編寫自己的模型 MBean 類)

When using Commons Modeler, you define the type of your model MBean in the className attribute of your mbean element. By default, Commons Modeler uses the org.apache.commons.modeler.BaseModelMBean class. However, there are circumstances where you want to extend BaseModelMBean:

在使用Commons Modeler時,您需要在mbean元素的className屬性中定義您的模型MBean的類型。默認情況下,Commons Modeler使用org.apache.commons.modeler.BaseModelMBean類。然而,在某些情況下,您可能希望擴展BaseModelMBean:

  1. You want to override the property or method of the managed resource.
  2. You want to add an attribute or operation that is not defined in the managed resource
  3. 您想要覆蓋受管資源的屬性或方法。
  4. 您想要添加一個在受管資源中未定義的屬性或操作。

Catalina provides many subclasses of BaseModelMBean in the org.apache.catalina.mbeans package, and you'll learn about them shortly

Catalina在org.apache.catalina.mbeans包中提供了許多BaseModelMBean的子類,您很快就會了解它們。

Registry(登記處)

The API centers on the org.apache.commons.modeler.Registry class. Here are some of the things you can do with this class:

API 的核心是 org.apache.commons.modeler.Registry 類。以下是您可以使用此類執行的一些操作:

  • Obtain an instance of javax.management.MBeanServer (so you don't need to call the createMBeanServer method of javax.management.MBeanServerFactory).
  • Read an mbean descriptor file using the loadRegistry method.
  • Create a ManagedBean object that you can use to construct a model MBean.
  • 獲取javax.management.MBeanServer的實例(這樣您就不需要調用javax.management.MBeanServerFactory的createMBeanServer方法)。
  • 使用loadRegistry方法讀取mbean描述符文件。
  • 創建一個ManagedBean對象,您可以使用它來構造一個模型MBean。

    ManagedBean(託管類)

A ManagedBean object describes a model MBean and replaces a javax.management.MBeanInfo object.

ManagedBean 對象描述一個模型 MBean,並取代 javax.management.MBeanInfo 對象。

BaseModelMBean

The org.apache.commons.modeler.BaseModelMBean class implements the javax.management.modelmbean.ModelMBean interface. Using this class, you don't need to use the javax.management.modelmbean.RequiredModelMBean class.

org.apache.commons.modeler.BaseModelMBean 類實現了 javax.management.modelmbean.ModelMBean 接口。

使用該類時,您無需使用 javax.management.modelmbean.RequiredModelMBean 類。

One particularly useful field of this class is the resource field that represents the resource managed by this model MBean. The resource field has the following definition:

該類的一個特別有用的字段是資源字段,它表示由該模型 MBean 管理的資源。

資源字段的定義如下:

protected java.lang.Object resource;

Using the Modeler API(使用建模 API)

The Car class whose object we want to manage is given in Listing 20.7.

我們要管理的汽車類對象見清單 20.7。

Listing 20.7: The Car class

清單 20.7: 汽車類

package ex20.pyrmont.modelmbeantest2;
public class Car {
 public Car() {
 System.out.println("Car constructor");
 }
 private String color = "red";
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
 public void drive() {
 System.out.println("Baby you can drive my car.");
 }
}

With Commons Modeler, you don't hard code the attributes and operations of your managed object. Instead, you list them in an XML document which acts as a descriptor for your model MBean(s). In this example, such a document takes the form of the car-mbean-descriptor.xml given in Listing 20.8.

有了 Commons Modeler,你就不用硬編碼託管對象的屬性和操作了。

取而代之的是在 XML 文檔中列出這些屬性和操作,作為模型 MBean 的描述符。

在本例中,這種文檔的形式是清單 20.8 中的 car-mbean-descriptor.xml。

Listing 20.8: The car-mbean-descriptor.xml file、

清單 20.8:car-mbean-descriptor.xml 文件

<?xml version="1.0"?>
<!DOCTYPE mbeans-descriptors PUBLIC
"-//Apache Software Foundation//DTD Model MBeans Configuration File"
"http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd">
<mbeans-descriptors>
 <mbean name="myMBean"
 className="javax.management.modelmbean.RequiredModelMBean"
 description="The ModelMBean that manages our Car object"
 type="ex20.pyrmont.modelmbeantest.Car">
 <attribute name="Color"
 description="The car color"
 type="java.lang.String"/>
 <operation name="drive"
 description="drive method"
 impact="ACTION"
 returnType="void">
 <parameter name="driver" description="the driver parameter"
 type="java.lang.String"/>
 </operation>
 </mbean>
</mbeans-descriptors>

Now, you need the agent class (ModelAgent.java) in Listing 20.9.

現在,您需要清單 20.9 中的代理類 (ModelAgent.java)。

Listing 20.9: The ModelAgent Class

清單 20.9: ModelAgent 類

  
package ex20.pyrmont.modelmbeantest2;  
        import java.io.InputStream;  
        import java.net.URL;  
        import javax.management.Attribute;  
        import javax.management.MalformedObjectNameException;  
        import javax.management.MBeanServer;  
        import javax.management.ObjectName;  
        import javax.management.modelmbean.ModelMBean;  
        import org.apache.commons.modeler.ManagedBean;  
        import org.apache.commons.modeler.Registry;  
public class ModelAgent {  
    private Registry registry;  
    private MBeanServer mBeanServer;  
    public ModelAgent() {  
        registry = createRegistry();  
        try {  
            mBeanServer = Registry.getServer();  
        }  
        catch (Throwable t) {  
            t.printStackTrace(System.out);  
            System.exit(1);  
        }  
    }  
    public MBeanServer getMBeanServer() {  
        return mBeanServer;  
    }  
    public Registry createRegistry() {  
        Registry registry = null;  
        try {  
            URL url = ModelAgent.class.getResource  
                    ("/ex20/pyrmont/modelmbeantest2/car-mbean-descriptor.xml");  
            InputStream stream = url.openStream();  
            Registry.loadRegistry(stream);  
            stream.close();  
            registry = Registry.getRegistry();  
        }  
        catch (Throwable t) {  
            System.out.println(t.toString());  
        }  
        return (registry);  
    }  
    public ModelMBean createModelMBean(String mBeanName)  
            throws Exception {  
        ManagedBean managed = registry.findManagedBean(mBeanName);  
        if (managed == null) {  
            System.out.println("ManagedBean null");  
            return null;        }  
        ModelMBean mbean = managed.createMBean();  
        ObjectName objectName = createObjectName();  
        return mbean;  
    }  
    private ObjectName createObjectName() {  
        ObjectName objectName = null;  
        String domain = mBeanServer.getDefaultDomain();  
        try {  
            objectName = new ObjectName(domain + ":type=MyCar");  
        }  
        catch (MalformedObjectNameException e) {  
            e.printStackTrace();  
        }  
        return objectName;  
    }  
    public static void main(String[] args) {  
        ModelAgent agent = new ModelAgent();  
        MBeanServer mBeanServer = agent.getMBeanServer();  
        Car car = new Car();  
        System.out.println("Creating ObjectName");  
        ObjectName objectName = agent.createObjectName();  
        try {  
            ModelMBean modelMBean = agent.createModelMBean("myMBean");  
            modelMBean.setManagedResource(car, "ObjectReference");  
            mBeanServer.registerMBean(modelMBean, objectName);  
        }  
        catch (Exception e) {  
            System.out.println(e.toString());  
        }  
        // manage the bean  
        try {  
            Attribute attribute = new Attribute("Color", "green");  
            mBeanServer.setAttribute(objectName, attribute);  
            String color = (String) mBeanServer.getAttribute(objectName,  
                    "Color");  
            System.out.println("Color:" + color);  
            attribute = new Attribute("Color", "blue");  
            mBeanServer.setAttribute(objectName, attribute);  
            color = (String) mBeanServer.getAttribute(objectName, "Color");  
            System.out.println("Color:" + color);  
            mBeanServer.invoke(objectName, "drive", null, null);  
        }  
        catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

See how the agent class is much shorter when using Commons Modeler?

看到使用 Commons Modeler 時,代理類是如何縮短的嗎?

Catalina's MBeans(Catalina的MBeans)

As mentioned at the beginning of this chapter, Catalina provides a number of MBean classes in the org.apache.catalina.mbeans package. All these MBeans extend the org.apache.commons.modeler.BaseModelMBean class either directly or indirectly. This section discusses the three most important MBean classes that Tomcat 4 provides: ClassNameMBean, StandardServerMBean, and MBeanFactory. You should find no problem understanding other model MBean classes in Catalina if you can understand these three classes. The three classes are discussed in this section. In addition, the MBeanUtil class in the org.apache.catalina.mbeans package is also explained.

如本章開頭所提到的,Catalina在org.apache.catalina.mbeans包中提供了一些MBean類。所有這些MBean類直接或間接地繼承自org.apache.commons.modeler.BaseModelMBean類。本節討論了Tomcat 4提供的三個最重要的MBean類:ClassNameMBean、StandardServerMBean和MBeanFactory。如果你能理解這三個類,那麼你應該沒有問題理解Catalina中的其他模型MBean類。本節將討論這三個類。此外,org.apache.catalina.mbeans包中的MBeanUtil類也會進行解釋。

ClassNameMBean

The org.apache.catalina.mbeans.ClassNameMBean class extends org.apache.commons.modeler.BaseModelMBean. It provides the write-only property className that represents the class name of the managed resource. The ClassNameMBean class is given in Listing 20.10.

org.apache.catalina.mbeans.ClassNameMBean類繼承自org.apache.commons.modeler.BaseModelMBean類。它提供了只寫屬性className,表示受控資源的類名。ClassNameMBean類在代碼清單20.10中給出。

Listing 20.10: The ClassNameMBean class

清單 20.10:ClassNameMBean 類

  
package org.apache.catalina.mbeans;  
        import javax.management.MBeanException;  
        import javax.management.RuntimeOperationsException;  
        import org.apache.commons.modeler.BaseModelMBean;  
public class ClassNameMBean extends BaseModelMBean {  
    public ClassNameMBean()  
            throws MBeanException, RuntimeOperationsException {  
        super();  
    }  
    public String getClassName() {  
        return (this.resource.getClass().getName());  
    }  
}

The ClassNameMBean class is an example of a subclass of BaseModelMBean that was written to provide a property that is not available in the managed resource itself. Many mbean elements defined in the mbeans-descriptors.xml file use this class as their type of Model MBean.

ClassNameMBean 類是 BaseModelMBean 子類的一個示例,編寫它的目的是為了提供託管資源本身所不具備的屬性。

在 mbeans-descriptors.xml 文件中定義的許多 mbean 元素都使用該類作為其模型 MBean 類型。

StandardServerMBean

The StandardServerMBean class extends org.apache.commons.modeler.BaseModelMBean to manage an instance of org.apache.catalina.core.StandardServer. The StandardServerMBean class (given in Listing 20.11) is an example of a model MBean class that is written to override a method (i.e. the store method) in the managed resource. When the store method is invoked by a management application, the store method in the StandardServerMBean (and not that in the managed StandardServer object) that gets executed.

StandardServerMBean 類擴展了 org.apache.commons.modeler.BaseModelMBean,用於管理 org.apache.catalina.core.StandardServer 的實例。

StandardServerMBean 類(在清單 20.11 中給出)是模型 MBean 類的一個示例,該類的編寫目的是覆蓋受管資源中的一個方法(即存儲方法)。

當管理應用程序調用存儲方法時,將執行 StandardServerMBean 中的存儲方法(而不是受管 StandardServer 對象中的存儲方法)。

Listing 20.11: The StandardServerMBean class

清單 20.11:StandardServerMBean 類


package org.apache.catalina.mbeans;
        import javax.management.InstanceNotFoundException;
        import javax.management.MBeanException;
        import javax.management.MBeanServer;
        import javax.management.RuntimeOperationsException;
        import org.apache.catalina.Server;
        import org.apache.catalina.ServerFactory;
        import org.apache.catalina.core.StandardServer;
        import org.apache.commons.modeler.BaseModelMBean;
public class StandardServerMBean extends BaseModelMBean {
    private static MBeanServer mserver = MBeanUtils.createServer();
    public StandardServerMBean()
            throws MBeanException, RuntimeOperationsException {
        super();
    }
    public synchronized void stored throws InstanceNotFoundException,
    MBeanException, RuntimeOperationsException {
        Server server = ServerFactory.getServer();
        if (server instanceof StandardServer) {
            try {
                ((StandardServer) server).store();
            }
            catch (Exception e) {
                throw new MBeanException(e, "Error updating conf/server.xml");
            }
        }
    }
}

The StandardServerMBean class is an example of a model MBean class that subclasses BaseModelMBean to override a method in the managed resource.

StandardServerMBean類是一個模型MBean類的示例,它繼承了BaseModelMBean類,以重寫託管資源中的一個方法。

MBeanFactory

The MBeanFactory class represents a factory object that creates all model MBeans that manage various resources in Catalina. The MBeanFactory class also provides methods for deleting these MBeans.

MBeanFactory類表示一個工廠對象,它創建了Catalina中管理各種資源的所有模型MBeans。MBeanFactory類還提供了刪除這些MBeans的方法。

As an example, take a look at the createStandardContext method in Listing 20.12.

以createStandardContext方法為例,請參考第20.12節的代碼。

Listing 20.12: The createStandardContext method

第20.12節:createStandardContext方法


public String createStandardContext(String parent,
                                    String path, String docBase) throws Exception {
    // Create a new StandardContext instance
    StandardContext context = new StandardContext();
    path = getPathStr(path);
    context.setPath(path);
    context.setDocBase(docBase);
    ContextConfig contextConfig = new ContextConfig();
    context.addLifecycleListener(contextConfig);
    // Add the new instance to its parent component
    ObjectName pname = new ObjectName(parent);
    Server server = ServerFactory.getServer();
    Service service =
            server.findService(pname.getKeyProperty("service"));
    Engine engine = (Engine) service.getContainer();
    Host host = (Host) engine.findChild(pname.getKeyProperty("host"));
    // Add context to the host
    host.addChild(context);
    // Return the corresponding MBean name
    ManagedBean managed = registry.findManagedBean("StandardContext");
    ObjectName oname =
            MBeanUtils.createObjectName(managed.getDomain(), context);
    return (oname.toString());
}

MBeanUtil

The org.apache.catalina.mbeans.MBeanUtil class is a utility class that provides static methods for creating various MBeans to manage Catalina objects, static methods for deleting those MBeans, and static methods for creating object names. For example, the createMBean method in Listing 20.13 creates a model MBean for a org.apache.catalina.Server object.

org.apache.catalina.mbeans.MBeanUtil類是一個實用類,提供了靜態方法來創建各種MBean以管理Catalina對象,刪除這些MBean的靜態方法,以及創建對象名稱的靜態方法。

例如,在清單20.13中的createMBean方法創建了一個用於管理org.apache.catalina.Server對象的模型MBean。

Listing 20.13: The createMBean method that creates a model MBean that manages a Server object.

清單20.13:創建一個管理Server對象的模型MBean的createMBean方法。、

public static ModelMBean createMBean(Server server) throws Exception {
    String mname = createManagedName(server);
    ManagedBean managed = registry.findManagedBean(mname);
    if (managed == null) {
        Exception e = new Exception(
                "ManagedBean is not found with "+mname);
        throw new MBeanException(e);
    }
    String domain = managed.getDomain();
    if (domain == null)
        domain = mserver.getDefaultDomain();
    ModelMBean mbean = managed.createMBean(server);
    ObjectName oname = createObjectName(domain, server);
    mserver.registerMBean(mbean, oname);
    return (mbean);
}

Catalina's MBeans Creation(卡塔利娜的 MBeans 創作)

Now that you are familiar with some of the model MBean in Catalina, we will take a look at how these MBeans are created and made available to management applications.

現在您已經熟悉了 Catalina 中的一些模型 MBean,我們將看看這些 MBean 是如何創建並提供給管理應用程序的。

The server.xml file, the configuration file of Tomcat, defines the following Listener element inside the Server element:

Tomcat 的配置文件 server.xml 文件在服務器元素內定義了以下 Listener 元素:

<Server port="8005" shutdown="SHUTDOWN" debug="0">
 <Listener
 c1assName="org.apache.catalina.mbeans.ServerLifecycleListener"
 debug="0"/>
...

This will add a listener of type org.apache.catalina.mbeans.ServerLifecycleListener to the org.apache.catalina.core.StandardServer object that represents a Server. When the StandardServer instance is started, it fires a START_EVENT event, as defined in the start method of the StandardServer class:

這將為表示服務器的 org.apache.catalina.core.StandardServer 對象添加一個 org.apache.catalina.mbeans.ServerLifecycleListener 類型的監聽器。

當 StandardServer 實例啓動時,它會觸發一個 START_EVENT 事件,該事件在 StandardServer 類的 start 方法中定義:

public void start() throws LifecycleException {
 ...
 lifecycle.fireLifecycleEvent(START_EVENT, null);
 ...
}

When the StandardServer object is stopped, a STOP_EVENT event is triggered, as defined in its stop method:

當 StandardServer 對象停止時,會觸發一個 STOP_EVENT 事件,該事件在其 stop 方法中定義:

public void stop() throws LifecycleException {
 ...
 lifecycle.fireLifecycleEvent(STOP_EVENT, null);
 ...
}

These events will cause the lifecycleEvent method of the ServerLifecycleListener class to be executed. Listing 20.14 presents the lifecycleEvent method.

這些事件將導致執行 ServerLifecycleListener 類的 lifecycleEvent 方法。

清單 20.14 介紹了 lifecycleEvent 方法。

public void lifecycleEvent(LifecycleEvent event) {  
    Lifecycle lifecycle = event.getLifecycle();  
    if (Lifecycle.START_EVENT.equals(event.getType())) {  
        if (lifecycle instanceof Server) {  
            // Loading additional MBean descriptors  
            loadMBeanDescriptors();  
            createMBeans();  
        }  
    }  
    else if (Lifecycle.STOP_EVENT.equals(event.getType())) {  
        if (lifecycle instanceof Server) {  
            destroyMBeans();  
        }  
    }  
    else if (Context.RELOAD_EVENT.equals(event.getType())) {  
        if (lifecycle instanceof StandardContext) {  
            StandardContext context = (StandardContext)lifecycle;  
            if (context.getPrivileged()) {  
                context.getServletContext().setAttribute  
                        (Globals.MBEAN_REGISTRY_ATTR,  
                                MBeanUtils.createRegistry());  
                context.getServletContext().setAttribute  
                        (Globals.MBEAN_SERVER_ATTR,  
                                MBeanUtils.createServer());  
            }  
        }  
    }  
}

The createMBeans method is the method that creates all the MBeans in

createMBeans 方法是創建 Catalina 中所有 MBeans 的方法。

Catalina. This method starts off by creating an instance of MBeanFactory, a model MBean class explained in the previous section.

中創建所有 MBean 的方法。該方法首先創建 MBeanFactory 的實例,MBeanFactory 是上一節中解釋過的 MBean 模型類。

Listing 20.15: The createMBeans method in ServerLifecycleListener

清單 20.15:ServerLifecycleListener 中的 createMBeans 方法


protected void createMBeans() {
    try {
        MBeanFactory factory = new MBeanFactory();
        createMBeans(factory);
        createMBeans(serverFactory.getserver());
    }
    catch (MBeanException t) {
        Exception e = t.getTargetException();
        if (e == null)
            e = t;
        log("createMBeans: MBeanException", e);
    }
    catch (Throwable t) {
        log("createMBeans: Throwable", t);
    }
}

The first createMBeans method uses the MBeanUtil class to create an ObjectName for the MBeanFactory and register it in the MBean server.

第一個createMBeans方法使用MBeanUtil類為MBeanFactory創建一個ObjectName,並將其註冊到MBean服務器中。

The second createMBeans method takes an org.apache.catalina.Server object and creates a model MBean for it. It is interesting to trace this createMBeans method (presented in Listing 20.16).

第二個createMBeans方法接受一個org.apache.catalina.Server對象,併為其創建一個模型MBean。

追蹤這個createMBeans方法是很有趣的(見代碼清單20.16)。

Listing 20.16: The createMBeans method that creates an MBean for a Server object

代碼清單20.16:創建一個Server對象的MBean的createMBeans方法

protected void createMBeans(Server server) throws Exception {
        // Create the MBean for the Server itself
        if (debug >= 2)
            log("Creating MBean for Server " + server);
        MBeanUtils.createMBean(server);
        if (server instanceof StandardServer) {
            ((StandardServer) server).addPropertyChangeListener(this);
        }
        // Create the MBeans for the global NamingResources (if any)
        NamingResources resources = server.getGlobalNamingResources();
        if (resources != null) {
            createMBeans(resources);
        }
        // Create the MBeans for each child Service
        Service services[] = server.findServices();
        for (int i = 0; i < services.length; i++) {
            // FIXME - Warp object hierarchy not currently supported
            if (services[i].getContainer().getClass().getName().equals
                    ("org.apache.catalina.connector.warp.WarpEngine")) {
                if (debug >= 1) {
                    log("Skipping MBean for Service " + services[i]);
                }
                continue;
            }
            createMBeans(services[i]);
        }
    }

Note that the createMBeans method in Listing 20.16 calls the following line in the for loop that iterates all Service objects in the StandardServer instance:

請注意,清單 20.16 中的 createMBeans 方法在遍歷 StandardServer 實例中所有服務對象的 for 循環中調用了下面一行:

createMBeans(services[i]);

This method creates MBean instances for the services and calls the createMBeans method for creating MBean objects for all the connectors and engines in the service The createMBeans method that creates a Service MBean is given in Listing 20.17.

此方法為服務創建MBean實例,並調用createMBeans方法為服務中的所有連接器和引擎創建MBean對象。創建Service MBean的createMBeans方法在列表20.17中給出。

Listing 20.17: The createMBeans method that creates a Service MBean

列表20.17:創建Service MBean的createMBeans方法

protected void createMBeans(Service service) throws Exception {
 // Create the MBean for the Service itself
 if (debug >= 2)
 log("Creating MBean for Service " + service);
 MBeanUtils.createMBean(service);
 if (service instanceof StandardService) {
 ((StandardService) service).addPropertyChangeListener(this);
 }
 // Create the MBeans for the corresponding Connectors
 Connector connectors[] = service.findConnectors();
 for (int j = 0; j < connectors.length; j++) {
 createMBeans(connectors[j]);
 }
 // Create the MBean for the associated Engine and friends
 Engine engine = (Engine) service.getContainer();
 if (engine != null) {
 createMBeans(engine);
 }
}

The createMBeans (engine) method, as you might suspect, calls the createMBeans method that creates the MBeans for hosts:

正如你所猜測的那樣,createMBeans (engine) 方法會調用 createMBeans 方法,為主機創建 MBeans:

protected void createMBeans(Engine engine) throws Exception {
    // Create the MBean for the Engine itself
    if (debug >= 2) {
        log("Creating MBean for Engine " + engine);
    }
    MBeanUtils.createMBean(engine);
...
    Container hosts[] = engine.findChildren();
    for (int j = 0; j < hosts.length; j++) {
        createMBeans((Host) hosts[j]);
    }
...
}

The createMBeans (host) method in turns creates a ContextMBean, like the following:

createMBeans (host) 方法會創建一個 ContextMBean,如下所示:


  
protected void createMBeans(Host host) throws Exception {  
        ...  
        MBeanUtils.createMBean(host);  
        ...  
        Container contexts[] = host.findChildren();  
        for (int k = 0; k < contexts.length; k++) {  
        createMBeans((Context) contexts[k]);  
        }  
        ...  
        }  
        The createMBeans (context) method is as follows:  
protected void createMBeans(Context context) throws Exception {  
        ...  
        MBeanUtils.createMBean(context);  
        ...  
        context.addContainerListener(this);  
        if (context instanceof StandardContext) {  
        ((StandardContext) context).addPropertyChangeListener(this);  
        ((StandardContext) context).addLifecycleListener(this);  
        }  
        // If the context is privileged, give a reference to it  
        // in a servlet context attribute        if (context.getPrivileged()) {  
        context.getServletContext().setAttribute  
        (Globals.MBEAN_REGISTRY_ATTR, MBeanUtils.createRegistry());  
        context.getServletContext().setAttribute  
        (Globals.MBEAN_SERVER_ATTR, MBeanUtils.createServer());  
        }  
        ...  
        }

If the context's privileged property is true, two attributes will be created and stored in the ServletContext object for the web application. The keys for those attributes are Globals.MBEAN_REGISTRY_ATTR and Globals.MBEAN_SERVER_ATTR. Here is a fragment from the org.apache.catalina.Globals class:

如果上下文的特權屬性為true,則會在Web應用程序的ServletContext對象中創建並存儲兩個屬性。這些屬性的鍵是Globals.MBEAN_REGISTRY_ATTR和Globals.MBEAN_SERVER_ATTR。

下面是來自org.apache.catalina.Globals類的一個片段:

/**
* The servlet context attribute under which the managed bean Registry
* will be stored for privileged contexts (if enabled).
*/
public static final String MBEAN_REGISTRY_ATTR =
 "org.apache.catalina.Registry";
/**
* The servlet context attribute under which the MBeanServer will be
* stored for privileged contexts (if enabled).
*/
public static final String MBEAN_SERVER_ATTR =
 "org.apache.catalina.MBeanServer";

The MBeanUtils.createRegistry method returns a Registry instance. The MBeanUtils.createServer method returns an instance of javax.management.MBeanServer instance with which all Catalina's MBeans are registered.

MBeanUtils.createRegistry 方法返回一個註冊表實例。

MBeanUtils.createServer 方法返回一個 javax.management.MBeanServer 實例,所有 Catalina 的 MBeans 都在該實例中註冊。

In other words, you can obtain these Registry and MBeanServer objects from a web application whose privileged property is set to true. The next section discusses how you can create a JMX manager application to manage Tomcat.

換句話説,您可以從特權屬性設置為 true 的網絡應用程序中獲取這些註冊表和 MBeanServer 對象。

下一節將討論如何創建一個 JMX 管理器應用程序來管理 Tomcat。

The Application(應用)

The application here is a web application for administering Tomcat. It is simple but enough to give you a general idea of how to use the MBeans exposed by Catalina. You can use it to list all the ObjectName instances in Catalina, as well as list all the contexts currently running and remove any of them.

這裏的應用程序是一個用於管理 Tomcat 的網絡應用程序。

它很簡單,但足以讓您大致瞭解如何使用 Catalina 公開的 MBeans。

您可以用它來列出 Catalina 中的所有 ObjectName 實例,以及列出當前運行的所有上下文並刪除其中任何一個。

First of all, you need to create a descriptor for the application (Listing 20.18). You must place this file in the in %CATALINA_HOME%/webapps directory

Listing 20.18: The myadmin.xml file

<Context path="/myadmin" docBase="../server/webapps/myadmin" debug="8"
privileged="true" reloadable="true">
</Context>

One thing you need to worry about is to make sure that the privileged property of the Context element is set to true. The docBase attribute specifies the location of the application.

需要注意的一點是,確保 Context 元素的 privileged 屬性設置為 true。docBase 屬性指定了應用程序的位置。

The application consists of one servlet, presented in Listing 20.19.

應用程序由一個 servlet 組成,如清單 20.19 所示。

Listing 20.19: The MyAdminServlet class

清單 20.19:MyAdminServlet 類


package myadmin;
        import java.io.IOException;
        import java.io.PrintWriter;
        import java.net.URLEncoder;
        import java.util.Iterator;
        import java.util.Set;
        import javax.management.MBeanServer;
        import javax.management.ObjectName;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import org.apache.commons.modeler.Registry;
public class MyAdminServlet extends HttpServlet {
    private Registry registry;
    private MBeanServer mBeanServer;
    public void init() throws ServletException {
        registry = (Registry)
                getServletContext().getAttribute("org.apache.catalina.Registry");
        if(registry == null) {
            System.out.println("Registry not available");
            return;
        }
        mBeanServer = (MBeanServer) getServletContext().getAttribute(
                "org.apache.catalina.MBeanServer");
        if (mBeanServer==null) {
            System.out.println("MBeanServer not available");
            return;
        }
    }
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        if (registry==null || mBeanServer==null) {
            out.println("Registry or MBeanServer not found");
            return;
        }
        out.println("<html><head></head><body>");
        String action = request.getParameter("action");
        if ("listAllManagedBeans".equals(action)) {
            listAllManagedBeans(out);
        }
        else if ("listAllContexts".equals(action)) {
            listAllContexts(out);
        }
        else if ("removeContext".equals(action)) {
            String contextObjectName =
                    request.getParameter("contextObjectName");
            removeContext(contextObjectName, out);
        }
        else {
            out.println("Invalid command");
        }
        out.println("</body></html>");
    }
    private void listAllManagedBeans(PrintWriter out) {
        String[] managedBeanNames = registry.findManagedBeans();
        for (int i=0; i<managedBeanNames.length; i++) {
            out.print(managedBeanNames[i] + "<br/>");
        }
    }
    private void listAllContexts(PrintWriter out) {
        try {
            ObjectName objName = new ObjectName("Catalina:type=Context,*");
            Set set = mBeanServer.queryNames(objName, null);
            Iterator it = set.iterator();
            while (it.hasNext()) {
                ObjectName obj = (ObjectName) it.next();
                out.print(obj +
                        " <a href=?action=removeContext&contextObjectName=" +
                        URLEncoder.encode (obj.toString(), "UTF-8") +
                        ">remove</a><br/>");
            }
        }
        catch (Exception e) {
            out.print(e.toString());
        }
    }
    private void removeContext(String contextObjectName,
                               PrintWriter out) {
        try {
            ObjectName mBeanFactoryObjectName = new
                    ObjectName("Catalina:type=MBeanFactory");
            if (mBeanFactoryObjectName!=null) {
                String operation = "removeContext";
                String[] params = new String[1];
                params[0] = contextObjectName;
                String signature[] = { "java.lang.String" };
                try {
                    mBeanServer.invoke(mBeanFactoryObjectName, operation,
                            params, signature);
                    out.println("context removed");
                }
                catch (Exception e) {
                    out.print(e.toString());
                }
            }
        }
        catch (Exception e) {
        }
    }
}

Finally, you need the application deployment descriptor in Listing 20.20.

最後,您需要清單 20.20 中的應用程序部署描述符。

Listing 20.20: The web.xml file

清單 20.20:web.xml 文件

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
 PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
 <servlet>
 <servlet-name>myAdmin</servlet-name>
 <servlet-class>myadmin.MyAdminServlet</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>myAdmin</servlet-name>
 <url-pattern>/myAdmin</url-pattern>
 </servlet-mapping>
</web-app>

To list all ObjectName instances, use the following URL:

要列出所有 ObjectName 實例,請使用以下 URL:

http://localhost:8080/myadmin/myAdmin?action=listAllMBeans

You will see a list of MBean objects. Here are the first six of them:

您將看到一個 MBean 對象列表。下面是前六個對象:

MemoryUserDatabase
DigestAuthenticator
BasicAuthenticator
UserDatabaseRealm
SystemErrLogger
Group

內存用户數據庫
摘要驗證器
基本驗證器
用户數據庫域
系統錯誤記錄器

To list all the contexts, use this URL:

要列出所有上下文,請使用此 URL:

http://localhost:8080/myadmin/myAdmin?action=listAllContexts

You will see all the running applications. To remove any of them, click the remove hyperlink.

您將看到所有正在運行的應用程序。

要刪除其中任何一個,請單擊刪除超鏈接。

Summary(摘要)

In this chapter you have learned how to manage Tomcat using JMX. You have been introduced to the two of four types of MBeans and developed a simple Admin application to use the MBeans offered by Catalina

在本章中,您將學習如何使用 JMX 管理 Tomcat。

您還了解了四種 MBeans 中的兩種,並開發了一個簡單的管理應用程序來使用 Catalina 提供的 MBeans

user avatar u_16297326 Avatar sofastack Avatar debuginn Avatar aipaobudezuoyeben Avatar yangrd Avatar qqxx6661 Avatar kason_5c6fb9100a56b Avatar kuaishoutech Avatar zijie1024 Avatar
Favorites 9 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.