详解 javax.management 包

这个包提供了Java管理扩展的核心类。

一、接口概述

接口名称 描述
Descriptor 某个JMX元素的额外的元数据。
DescriptorAccess 这个接口可用于获取与某个JMX组件相关联的Descriptor类的描述符的访问权。
DescriptorRead 这个接口可用于读取某个管理接口元素(例如,MBeanInfo)的描述符。
DynamicMBean 这个接口定义了某个动态的MBean应当实现的方法(动态MBean会对外公开一个动态的管理接口)。
MBeanRegistration 如果想要在MBean服务器中注册或注销某个MBean的之前和之后执行某些操作,那么这个MBean可以实现这个接口。
MBeanServer 这个接口可用于在探针端操作MBean。
MBeanServerConnection 这个接口可以表示和某个(本地的或远程的)MBean服务器之间的连接和通信方式。
MBeanServerDelegateMBean 可用于定义某个MBeanServerDelegate对象的管理接口。
NotificationBroadcaster 如果某个MBean需要发送通知,那么这个MBean应当实现这个接口。
NotificationEmitter 如果某个MBean需要发送通知,那么这个MBean应当实现这个接口。
NotificationFilter 任何作为通知过滤器的类都应该实现这个接口。
NotificationListener 任何需要接收通知的对象都应该实现这个接口。
PersistentMBean 如果某个MBean需要持久化,那么这个MBean应当实现这个接口。
QueryExp 表示某些关系约束,类似于数据库查询的where子句。
ValueExp 表示可以作为参数传递给关系表达式的值。

二、类概述

类名称 描述
Attribute 通过关联属性名称和属性值,这个类可以表示MBean的属性。
AttributeChangeNotification 这个类定义了由MBean发送的属性变更通知。
AttributeChangeNotificationFilter 这个类实现了属性变更通知(AttributeChangeNotification)NotificationFilter(通知过滤器)接口。
AttributeList 这个类表示MBean的属性值列表。
AttributeValueExp 这个类可以表示用作关系约束参数的属性。
DefaultLoaderRepository 已弃用
请换用MBeanServer.getClassLoaderRepository()方法。
ImmutableDescriptor 一种不可变的描述符。
JMX 来自于JMX API的静态方法。
MBeanAttributeInfo 这个类会描述一个对管理功能公开的MBean属性。
MBeanConstructorInfo 这个类会描述一个公开的MBean构造器。
MBeanFeatureInfo 提供某个MBean描述符对象的概要信息。
MBeanInfo 描述某个MBean公开的管理接口,也就是管理功能可以使用的属性和操作的集合。
MBeanNotificationInfo 对于一个给定的Java通知类,MBeanNotificationInfo类可用来描述某个MBean发出的不同的通知实例的特性。
MBeanOperationInfo 描述某个MBean公开的管理操作。
MBeanParameterInfo 描述某个MBean公开的管理操作的参数。
MBeanPermission 这个类可以控制MBeanServer管理操作的执行权限。
MBeanServerBuilder 这个类表示用于创建一个默认实现的MBeanServer的构建器。
MBeanServerDelegate 这个类会从管理的观点来描述MBean服务器(MBeanServer)。
MBeanServerFactory 提供MBean服务器(MBeanServer)的实例引用。
MBeanServerInvocationHandler 这个类是InvocationHandler接口的实现类,它可以通过MBean服务器(MBeanServer)将某个MBean的管理接口中的方法转发至这个MBean。
MBeanServerNotification 表示由MBean服务器(MBeanServer)通过MBeanServerDelegate类型的MBean实例发出的通知。
MBeanServerPermission 这个类表示执行MBeanServer相关操作的权限。
MBeanTrustPermission 这个类表示签名者或代码库的“可信”权限。
Notification Notification类表示由某个MBean发出的通知。
NotificationBroadcasterSupport 这个类是NotificationEmitter接口的一个实现类。
NotificationFilterSupport 这个类是NotificationFilter接口的一个实现类。
ObjectInstance 用于表示某个MBean的对象名和它的类名。
ObjectName 用于表示某个MBean的对象名或某个能够匹配多个MBean名称的模式。
Query 构造查询对象的约束。
QueryEval 允许某个查询能够在一个特定的MBean服务器的上下文中运行。
StandardEmitterMBean 这个类表示一种MBean,它的管理接口可以通过Java接口的反射机制确定,而且它还能发出通知。
StandardMBean 这个类表示一种MBean,它的管理接口可以通过Java接口的反射机制确定。
StringValueExp 这个类表示作为关系约束参数的字符串。

三、异常概述

异常名称 描述
AttributeNotFoundException 指定的属性不存在或者不能获取。
BadAttributeValueExpException 这个异常会在向一个查询构建方法传递一个无效的MBean属性时抛出。
BadBinaryOpValueExpException 这个异常会在向一个查询构建方法传递一个无效的表达式时抛出。
BadStringOperationException 这个异常会在向一个查询构建方法传递一个无效的字符串操作时抛出。
InstanceAlreadyExistsException MBean已经在容器中注册过了。
InstanceNotFoundException 指定的MBean在容器中不存在。
IntrospectionException 当某个MBean进行自省检查时发生了异常。
InvalidApplicationException 这个异常会在尝试进行如下操作时抛出:向一个MBean发送子查询表达式,或者向一个错误类型的MBean发送限定属性表达式。
InvalidAttributeValueException 指定的属性值对于这个属性来说是无效的。
JMException 由JMX实现抛出的异常。
JMRuntimeException 由JMX实现抛出的运行时异常。
ListenerNotFoundException 指定的MBean监听器在容器中不存在。
MalformedObjectNameException 字符串的格式并不对应于一个有效的ObjectName(对象名)。
MBeanException 表示由探针中的MBean方法抛出的“用户自定义”异常。
MBeanRegistrationException 这个类会包装由MBeanRegistration接口的preRegister()、preDeregister()方法抛出的异常。
NotCompliantMBeanException 当在MBean服务器中注册某个对象,而这个对象却不是兼容于JMX的MBean,那么便会抛出这个异常。
OperationsException 表示在对MBean执行管理操作时,MBean服务器中抛出的异常。
ReflectionException 当使用java.lang.reflect类,调用MBean的方法时,这个类可用于表示MBean服务器中抛出的异常。
RuntimeErrorException 当探针中发生java.lang.Error错误时,应当捕获这个错误,然后将其作为RuntimeErrorException异常重新抛出。
RuntimeMBeanException 表示由探针中的MBean方法抛出的运行时异常。
RuntimeOperationsException 当对MBean执行某些操作时,这个类可用于表示探针中抛出的运行时异常。
ServiceNotFoundException 当被请求的服务不存在时,这个类可用于表示此时产生的异常。

四、注解类型概述

注解类型 描述
DescriptorKey 这个类表示元注解,它可以描述一个注解元素是如何关联至描述符中的一个字段的。
MXBean 这个类是一种注解,用于将一个接口显式地标记为一个MXBean接口,或者标记为一个非MXBean接口。

五、javax.management包详述

这个包提供了Java管理扩展的核心类。

Java管理扩展(JMXTM)API是一种用于管理和监控的标准API。典型用途包括:

  • 查询和修改应用程序的配置;
  • 积累应用程序行为相关的统计数据,并且对外提供这些数据;
  • 发出状态变化和环境错误的通知。

JMX API还可以作为系统、网络等设施的管理解决方案的一部分来使用。

这个API包含远程访问的功能,因此,远程管理程序应当能够和正在运行的应用程序展开交互,这样便能实现这些用途了。

1. MBean

JMX API的基本概念就是MBean。一个MBean就是一个具有名称的受管理对象,而这个对象则表示一个资源。它具有一个管理接口,由下列组成:

  • 具有名称和类型的属性,这些属性能够被读取和/或写入;
  • 具有名称和类型的操作,这些操作可以被调用;
  • 具有类型的通知,这些通知可以由MBean发出。

例如,如果使用某个MBean来表示一个应用程序的配置,那么这个MBean就具有可以表示不同配置项的属性。读取CacheSize属性将会返回相应配置项的当前值。写入这个属性将会更新相应的配置项,这样可能会改变正在运行的应用程序的行为。诸如保存之类的操作将会持久化存储当前的配置数据。每当配置改变时,JMX都会发出诸如ConfigurationChangedNotification这样的通知。

在JMX API的标准用法中,MBean是作为Java对象来实现的。但是,正如下文所述,通常不会直接引用这些对象。

1.1 标准MBean(Standard MBean)

为了简化MBean的实现难度,JMX API还包含了标准MBean的概念。标准MBean的属性和操作都是从一个Java接口衍生而来的,它们会使用某些命名模式,类似于JavaBeanTM使用的命名模式。例如,请考虑以下接口:

  1. public interface ConfigurationMBean {
  2. public int getCacheSize();
  3. public void setCacheSize(int size);
  4. public long getLastChangedTime();
  5. public void save();
  6. }

getCacheSizesetCacheSize方法定义了一个可读写的属性,该属性的类型为int,名称为CacheSize(注意,此处首字母大写,不同于JavaBean的命名规约)。

getLastChangedTime方法定义了一个类型为long、名称为LastChangeTime的属性。这是一个只读的属性,因为没有定义setLastChangedTime方法。

save方法定义了一个名为save的保存操作。它不是一个属性,因为它的名称前缀并不是getset

标准MBean的命名模式在JMX规范中有着详细的描述。

有两种方法可以使一个Java对象成为一个实现了管理接口的MBean。第一种方法就是确保这个对象所属的类和相应的Java接口具有完全相同的名称,但是不带有MBean的后缀。因此,这个对象在本例中就应当是Configuration类的实例,这个类应当和ConfigurationMBean接口在相同的Java包中。第二种方法就是使用StandardMBean类。

1.2 MXBean

MXBean是标准MBean的一个变种,它会将复杂的类型映射至一个标准的类型集合中,这个类型集合在javax.management.openmbean包中定义。如果你可能需要在你的MBean接口中引用应用程序专用的类,那么MXBean就是非常合适的。MXBean在JMX规范中会有着详细的描述。

1.3 动态MBean(Dynamic MBean)

动态MBean是一种在运行时定义其管理接口的MBean。例如,一个配置MBean可以通过解析一个XML文件来确定待公开属性的名称和类型。

如果某个Java对象所属的类实现了DynamicMBean接口,那么这些对象就都是动态MBean。

1.4 开放MBean(Open MBean)

开放MBean是一种动态MBean,它的属性、操作参数和返回值的类型是通过一个很小的预定义的Java类集合来构建的。开放MBean会使用远程管理程序简化操作的执行,这个远程管理程序不需要访问应用程序专用的类型,包括非Java程序。开放MBean由javax.management.openmbean包定义。

1.5 模型MBean(Model MBean)

模型MBean是一种动态MBean,它可以作为管理接口和底层受管理资源之间的桥梁。管理接口和受管理资源都被指定为Java对象。不同的管理接口和受管理资源可以多次重用相同的模型MBean,它还可以提供一些常用的功能,例如:持久化和缓存。模型MBean由javax.management.modelmbean包定义。

2. MBean服务器(MBean Server)

MBean必须在一个MBean服务器中注册才能使用。MBean服务器是一种MBean容器。通常,访问MBean的唯一方法就是通过MBean服务器进行访问。换句话说,代码不能直接访问实现了MBean接口的Java对象,但是可以通过MBean服务器,根据名称访问MBean。每个MBean在MBean服务器中都有一个唯一的名称,由ObjectName类定义。

MBean服务器是一个实现了MBeanServer接口的对象。使用最方便的MBean服务器是Java平台的MBean服务器(Platform MBean Server)。它是一种MBean服务器,可以在相同的Java虚拟机内运行的不同的受管理组件之间共享。可以使用ManagementFactory.getPlatformMBeanServer()方法访问Java平台的MBean服务器。

通过MBeanServerFactory类,应用程序代码还可以创建一个新的MBean服务器,或者访问已经创建的MBean服务器。

2.1 在MBean服务器中创建MBean

可以使用两种方法来创建一个MBean。第一种方法:构建一个实现了MBean接口的类的实例,然后使用registerMBean方法,在MBean服务器中注册这个实例。第二种方法:使用createMBean方法,将创建和注册MBean的两步操作简化为一步操作。

registerMBean方法对于本地使用来说更加简单,但是不能远程使用。createMBean方法可以远程使用,但是有时候要注意类加载的问题。

如果MBean实现了MBeanRegistration接口,那么当MBean在一个MBean服务器中注册或注销时,这个MBean便可以执行一些动作。

2.2 在MBean服务器中访问MBean

给定一个ObjectName name对象和一个MBeanServer mbs对象,你就可以在这个例子中访问属性和操作了:

  1. int cacheSize = mbs.getAttribute(name, "CacheSize");
  2. Attribute newCacheSize =
  3. new Attribute("CacheSize", new Integer(2000));
  4. mbs.setAttribute(name, newCacheSize);
  5. mbs.invoke(name, "save", new Object[0], new Class[0]);

换句话说,如果你有一个Java接口,而这个接口相当于是MBean的管理接口,那么你就可以按照以下示例使用MBean代理:

  1. ConfigurationMBean conf =
  2. JMX.newMBeanProxy(mbs, name, ConfigurationMBean.class);
  3. int cacheSize = conf.getCacheSize();
  4. conf.setCacheSize(2000);
  5. conf.save();

使用MBean代理仅仅是为了便利。第二个示例结束时也会调用和第一个示例相同的MBeanServer操作。

可以通过MBean服务器查询MBean,作为查询条件的MBean名称应当匹配特定的模式,而且MBean的属性也应当满足一些约束。可以使用ObjectName类来构造名称模式,并且使用Query类来构造约束。然后,queryNamesqueryMBeans方法便会执行查询。

2.3 MBean的生命周期

当在MBean服务器中注册或注销某个MBean时,如果想要及时得到通知,那么这个MBean可以实现MBeanRegistration接口。另外,preRegister方法使得MBean能够取得MBeanServer对象的引用,并且能够获取它在MBean服务器之内的ObjectName对象。

3. 注意

通知是Notification类或子类的实例。除了它的Java类之外,它还有一个能够将其和其他通知区分的类型字符串,而这些通知都是同一个类的实例。

需要发送通知的MBean必须实现NotificationBroadcasterNotificationEmitter接口。通常,MBean可以继承NotificationBroadcasterSupport类,或者委托给上述类的实例。示例如下所示:

  1. public class Configuration extends NotificationBroadcasterSupport
  2. implements ConfigurationMBean {
  3. ...
  4. private void updated() {
  5. Notification n = new Notification(...);
  6. sendNotification(n);
  7. }
  8. }

如果某个对象实现了NotificationListener接口,那么它便可以用作接收通知的监听器。你可以使用MBeanServer.addNotificationListener(ObjectName, NotificationListener, NotificationFilter, Object)方法,向一个MBean添加一个监听器。如果你想要只接收感兴趣的通知,那么你可以有选择地为这个方法提供一个过滤器。过滤器是一种实现了NotificationFilter接口的对象。

某个MBean可能是一个监听器,它负责接收同一个MBean服务器中的其他MBean发送的通知。在这种情况中,这个MBean会实现NotificationListener接口,并且会使用MBeanServer.addNotificationListener(ObjectName, ObjectName, NotificationFilter, Object)方法进行监听。

4. 远程访问MBean

你可以通过一个连接器远程访问一个MBean服务器。这种连接器使得远程的Java应用程序能够访问MBean服务器,访问方式几乎和在本地访问MBean服务器相同。javax.management.remote包定义了这些连接器。

JMX规范还定义了一种适配器的概念。适配器可以将SNMP协议或HTML协议的请求相互转换,然后访问MBean服务器。例如,SNMP GET操作可能会导致调用MBean服务器的getAttribute方法。

4.1 JMX规范的不同版本之间的互操作性

当客户端通过JMX的远程API连接至服务器时,客户端和服务器的JMX规范的版本有可能不同。本文描述的JMX规范的版本为1.4。以前的版本有1.0、1.1和1.2(没有1.3版本)。标准的JMX远程API(JMX Remote API)是可以向1.2之前的版本兼容的。因此,在基于标准的部署过程中,只需要关注1.2版本开始出现的互操作性问题。

JMX规范的每个版本都会继续实现以前版本的功能特性。因此,当客户端的版本要比服务器的更老时,就不会出现任何互操作性的问题。

当客户端的版本要比服务器的更新时,就不能使用某些更新的功能特性,正如下面的章节所述。通过检查MBeanServerDelegateSpecificationVersion属性,客户端便可以确定服务器的版本。

4.2 如果远程MBean服务器的版本是1.2
  • 你不能在ObjectName的关键字属性中使用通配符,例如:domain:type=Foo,name=*。你仍然可以使用能够匹配整个属性的通配符,例如:*:**:type=Foo,*

  • 你不能在查询中使用Query.isInstanceOf方法。

  • 正如在javax.management.monitor包的文档中所述,你不能在监控器的observed属性中使用诸如HeapMemoryUsage.used这样的点分语法。