利用自訂 MBean 延伸 WebSphere Application Server 管理系統
您可以在一個 WebSphere 程序中,提供和登錄新的 Java™ Management Extensions (JMX) MBean(請參閱「JMX 1.x 規格」,以取得詳細資料)來延伸 WebSphere® Application Server 管理系統。
關於這項作業
JMX MBean 代表特定邏輯片段的管理介面。 標準產品基礎架構中所有受管理的資源都是以 JMX MBean 來代表。 您可以利用很多方法來建立您自己的 MBean,並將它們登錄在任何 WebSphere 程序所執行的 JMX MBeanServer 中。 如需相關資訊,請參閱 MBean Java 應用程式設計介面 (API) 文件。在這個資訊中心,請按一下 。
程序
結果
不論用來建立及登錄 MBean 的方法為何,您都必須為新的 MBean 程式碼設定適當的 Java 2 安全許可權。 WebSphere AdminService 和 MBeanServer 受到 Java 2 安全許可權的嚴格保護,如果您沒有將基本許可權明確授予程式碼,當您試圖呼叫這些類別的方法時,系統會擲出安全異常狀況。 如果您將 MBean 當作應用程式的一部分來提供,您可以在作為應用程式 meta 資料的一部分而提供的 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);
// 受套件保護的 STATE 常數。
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 是以 STOPPED 狀態來起始設定。
private String state = STATE_STOPPED;
public SampleState() {
if (tc.isEntryEnabled()) Tr.entry(tc,"<init>");
// 在 "state" 起始設定期間,會將 State 起始設定, // 但也可以在這裡,在建構子中起始設定。
/*
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);
/**
* 從多重呼叫的 MBean 作業傳回聚集結果,這個作業
* 會在所有服務者 MBean 的各結果中進行編譯,且會
* 針對呼叫的方法,各傳回單一的回覆值。
*
* @param methodName MBean 方法名稱
* @param params MBean 方法參數
* @param signatures MBean 方法簽章
* @param servantMBeanResults dynamicproxy 多重播送呼叫
* 所呼叫的各個服務者 MBean
* 實例的結果。
* 附註:這個值可以是 "null",也可以是
* "null" 陣列(如果方法的回覆值
* 是 "void" 的話)。這個方法的實作
* 必須處理這個情況,以
* 避免 <code>NullPointerException</code>.
* @param stateObject
* MBean 提供者已提供 <code>StateObject</code>,供
* CR 中的 dynamicproxy MBean 用來管理它的狀態。附註:這個物件
* 有可能是空值,如果未指定 "stateObjectClass" 或在這個
* dynamicproxy MBean 的起始設定期間發生內部錯誤。
* 實作必須適當處理 "null" 輸入。
*
* @return MBean XML 定義給指定的 MBean 作業
* 的聚集結果。
*/
public Object aggregateResults(String methodName,
Object[] params,
String[] signatures,
Object[] servantMBeanResults,
StateObject stateObject) {
if (tc.isEntryEnabled()) Tr.entry(tc,"aggregateResults",methodName);
// 如您從 SampleStateMBean 的 MBeanDescriptor 中所能見到, // 它宣告下列四個方法:
// 1. String getMBeanName() [proxyInvokeType == unicall]
// 2. String getState() [proxyInvokeType == multicall]
// 3. void setState(String) [proxyInvokeType == multicall]
// 4. void initializeState() [proxyInvokeType == multicall]
//
// 從這些方法中,唯一需要聚集的方法
// 是 #2 getState 方法,它是一個多重呼叫的 MBean 作業,且
// 會傳回一個可聚集的值。
//
// 在這個範例中,我們只是取出每個服務者的 getState MBean
// 要求結果,將它們連結成一個長字串來
// 顯示每個服務者的狀態。
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();
}
// 如果我們也有一個會傳回例如 int 的範例方法
// getNumberOfMBeans(),它可以採用類似的方式
// 並在這裡一併新增各服務者的 getNumberOfMBeans() 結果。
/* 為了不存在的方法而新增的範例: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() + "!";
}
}