カスタム MBean による WebSphere Application Server 管理システムの拡張
WebSphere プロセスのいずれか 1 つに新規の Java™ Management Extensions (JMX) MBean (詳しくは JMX 1.x 仕様を参照) を提供および登録することにより、WebSphere® Application Server 管理システムを拡張することができます。
このタスクについて
JMX MBean は、論理の特定部分の管理インターフェースを表します。 製品の標準のインフラストラクチャー内にあるすべての管理対象リソースは、JMX MBean として表されます。 さまざまな方法で、独自の MBean を作成し、その MBean を任意の WebSphere プロセスで稼働している JMX MBeanServer に登録することができます。 詳しくは、MBean Java アプリケーション・プログラミング・インターフェース (API) に関する文書を参照してください。このインフォメーション・センターでは、 をクリックします。
手順
タスクの結果
MBean の作成および登録方法に関係なく、新規の MBean コード用に、適正な Java 2 セキュリティー権限をセットアップする必要があります。WebSphere AdminService および MBeanServer は、Java 2 セキュリティー権限を使用して厳重に保護されているので、自分のコード・ベースに権限を明示的に付与しないと、これらのクラスのメソッドを呼び出そうとした場合に、セキュリティー例外がスローされます。 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() + "!";
}
}