使用定制 MBean 扩展 WebSphere Application Server 管理系统
可以提供和注册新的 Java™ 管理扩展 (JMX) MBean(请参阅 JMX 1.x 规范获取详细信息)在 WebSphere 的一个进程中扩展 WebSphere® Application Server 管理系统。
关于此任务
JMX MBean 代表特殊逻辑段的管理接口。标准产品基础结构中的所有受管资源都以 JMX MBeans 表示。有很多方法可以创建您自已的 MBean,并且可以将他们注册到以任何 WebSphere 进程方式运行的 JMX MBeanServer。有关更多信息,请参阅 MBean Java 应用程序编程接口 (API) 文档。 在此信息中心中,单击 。
过程
结果
不管用于创建并注册 MBean 的方法如何,您必须为新 MBean 代码设置适当的 Java 2 安全许可权。使用 Java 2 安全许可权可以严格保护 WebSphere AdminService 和 MBeanServer,且如果您没有将基本许可权显式授予代码,那么尝试调用这些类的方法时,系统会抛出安全性异常。如果您正在提供您的 MBean 作为应用程序的一部分,那么可以在作为一部分应用程序元数据提供的 was.policy 文件中设置许可权。如果您正在使用 CustomService 接口或其他不作为应用程序传递的代码,那么您可以编辑节点配置中的 library.policy 文件,或者甚至为特定安装编辑 properties 目录中的 server.policy 文件。
![[z/OS]](../images/ngzos.gif)
示例:SampleStateMBean MBean
MBeanDescriptor
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MBean SYSTEM "MbeanDescriptor.dtd">
<MBean type="SampleStateMBean"
aggregationHandlerClass="com.ibm.ws390.sample.SampleStateAggregationHandler"
eventHandlerClass="com.ibm.ws390.sample.SampleStateEventHandler"
invocationHandlerClass="com.ibm.ws390.sample.SampleStateInvocationHandler"
stateObjectClass="com.ibm.ws390.sample.SampleState"
version="6.0"
platform="dynamicproxy"
description="Sample State MBean for the documentation example.">
<attribute description="The name of the MBean."
getMethod="getMBeanName" name="mbeanName" type="java.lang.String"
proxyInvokeType="unicall"/>
<attribute description="The state of the MBean." name="state"
getMethod="getState" setMethod="setState" type="java.lang.String"
proxyInvokeType="multicall" proxySetterInvokeType="multicall"/>
<operation
description="Initialize the State MBean."
impact="ACTION" name="initializeState" role="operation"
targetObjectType="objectReference" type="void" proxyInvokeType="multicall">
<signature>
<parameter description="The name of the MBean."
name="mbeanName" type="java.lang.String"/>
<parameter description="The initial state of the MBean."
name="mbeanName" type="java.lang.String"/>
</signature>
</operation>
<notification name="j2ee.state.starting" severity="6" log="false"
description="This sample state MBean is in starting state.">
<notificationType>j2ee.state.starting</notificationType>
</notification>
<notification name="j2ee.state.running" severity="6" log="false"
description="This sample state MBean is in running state.">
<notificationType>j2ee.state.running</notificationType>
</notification>
<notification name="j2ee.state.stopping" severity="6" log="false"
description="This sample state MBean is in stopping state.">
<notificationType>j2ee.state.stopping</notificationType>
</notification>
<notification name="j2ee.state.stopped" severity="6" log="false"
description="This sample state MBean is in stopped state.">
<notificationType>j2ee.state.stopped</notificationType>
</notification>
</MBean>
SampleState 实现
package com.ibm.ws390.sample;
import com.ibm.ejs.ras.Tr;
import com.ibm.ejs.ras.TraceComponent;
import java.io.Serializable;
import com.ibm.websphere.management.dynamicproxy.StateObject;
public class SampleState extends StateObject {
private static TraceComponent tc =
Tr.register(SampleState.class,"SampleState",null);
// Package protected STATE constants.
static final String STATE_STARTING = "j2ee.state.starting";
static final String STATE_RUNNING = "j2ee.state.running";
static final String STATE_STOPPING = "j2ee.state.stopping";
static final String STATE_STOPPED = "j2ee.state.stopped";
// Dynamicproxy State is initialized with STOPPED state.
private String state = STATE_STOPPED;
public SampleState() {
if (tc.isEntryEnabled()) Tr.entry(tc,"<init>");
// State is initialized during "state" initialization,
// but can also be initialized here in the constructor as well.
/*
state = "WebSphere Application Server for z/OS ready for e-business";
*/
if (tc.isEntryEnabled()) Tr.exit(tc,"<init>");
}
public synchronized String getState() {
if (tc.isEntryEnabled()) Tr.entry(tc,"getState");
if (tc.isEntryEnabled()) Tr.exit(tc,"getState",state);
return state;
}
public synchronized void setState(String state) {
if (tc.isEntryEnabled()) Tr.entry(tc,"setState",state);
this.state = state;
if (tc.isEntryEnabled()) Tr.exit(tc,"setState");
}
public synchronized String getStateObjectInfo() {
return state;
}
}
SampleStateAggregationHandler 实现
package com.ibm.ws390.sample;
import com.ibm.websphere.management.dynamicproxy.AggregationHandler;
import com.ibm.websphere.management.dynamicproxy.StateObject;
import com.ibm.ejs.ras.Tr;
import com.ibm.ejs.ras.TraceComponent;
public class SampleStateAggregationHandler implements AggregationHandler {
private static TraceComponent tc =
Tr.register(SampleStateAggregationHandler.class,"SampleState",null);
/**
* Return an aggregated result from a multicall Mbean operation which
* compiles through all servant MBeans' results and returns a respective
* single return value for an invoked method.
*
* @param methodName MBean method name
* @param params MBean method parameters
* @param signatures MBean method signatures
* @param servantMBeanResults Result of each servant MBean instances
* invoked by the dynamicproxy multicast
* invocation.
* Note: this value can be "null" OR can be
* an array of "null"s in case return value
* of the method is "void." Implementation
* of this method MUST handle this case to
* avoid a <code>NullPointerException</code>.
* @param stateObject
* MBean provider provided <code>StateObject</code> used by
* dynamicproxy MBean in CR to manage its state. Note: this object
* MAY BE null if "stateObjectClass" was not specified OR internal
* error occurred during initialization of this dynamicproxy MBean.
* Implmentation MUST properly handle "null" input.
*
* @return aggregated result as defined by MBean xml for specified
* MBean operation.
*/
public Object aggregateResults(String methodName,
Object[] params,
String[] signatures,
Object[] servantMBeanResults,
StateObject stateObject) {
if (tc.isEntryEnabled()) Tr.entry(tc,"aggregateResults",methodName);
// As you can see from the MBeanDescriptor of SampleStateMBean,
// it declares the following four methods:
// 1. String getMBeanName() [proxyInvokeType == unicall]
// 2. String getState() [proxyInvokeType == multicall]
// 3. void setState(String) [proxyInvokeType == multicall]
// 4. void initializeState() [proxyInvokeType == multicall]
//
// From these methods, the only one that requires aggregation
// is #2 getState method which is a multicall MBean operation AND
// it returns a value that can be aggregated.
//
// In this example, we simply take each servants' getState MBean
// request result and concatenate them into one long String that
// displays each servants' state.
if (methodName.equals("getState")) {
StringBuffer stateBuf = new StringBuffer();
for (int i=0; i<servantMBeanResults.length; i++) {
stateBuf.append("SERVANT #" + i + " state ==|" +
servantMBeanResults[i] + "|== ");
}
return stateBuf.toString();
}
// If we also had an example method which returns say an int,
// getNumberOfMBeans(), it can take the similar approach
// and to add each servants' getNumberOfMBeans() result together here.
/* example added for non-existent method: int getNumberOfMBeans()
else if (methodName.equals("getNumberOfMBeans")) {
int aggregatedResult = 0;
for (int i=0; i<servantMBeanResults.length; i++) {
aggregatedResult += (int) servantMBeanResults[i];
}
return aggregatedResult;
}
*/
return methodName + " is NOT handled by " + getClass().getName() + "!";
}
}