5 JMXを使用したドメインの構成の管理

この章では、JMXを使用してWebLogic Server ドメインの構成を管理する方法について説明します。MBean属性を編集する方法、変更の表示と取消しを行う方法、変更のアクティブ化を追跡する方法、および暗号化されたMBean属性値の設定と取得を行う方法について説明します。例外の編集と処理を行うためのベスト・プラクティスも記載されています。

この章の内容は以下のとおりです。

WebLogic Serverドメインの変更、および変更のアクティブ化のプロセスを理解するには、Oracle WebLogic Serverドメイン構成の理解構成の変更の管理を参照してください。

MBean属性の編集:主なステップ

MBean属性を編集するには、次の手順に従います。

  1. 編集セッションの開始

    MBean属性に対するすべての編集は編集セッションのコンテキスト内で行われます。各WebLogic Serverドメインの内部では、一度に1つの編集セッションのみをアクティブにすることができます。ユーザーが編集セッションを開始すると、WebLogic Serverは他のユーザーが保留中の構成MBean階層にアクセスできないようにロックします。「ロックの管理」を参照してください。

  2. MBean属性の変更または新しいMBean作成

    MBean属性の変更や新しいMBeanの作成を行うと、保留中の構成MBeanのメモリー内の階層が更新されます。これらの変更を保存する前に編集セッションを終了すると、保存されていない変更は破棄されます。

  3. 保留中の構成ファイルへの変更の保存

    メモリー内の階層に対して十分な変更を行ったら、その変更内容をドメインの保留中の構成ファイルに保存します。保存した変更は、アクティブ化されるか明示的に元に戻されるまで、保留中の構成ファイル内に保持されます。保存した変更をアクティブ化する前に編集セッションを終了した場合は、以降の編集セッションで、本人または他のだれかがその変更をアクティブ化できます。

    アクティブ化する前に繰返し変更を行って保存することができます。たとえば、サーバーを作成して保存できます。その後で、新しいサーバーのリスニング・ポートとリスニング・アドレスを構成してその変更を保存できます。このようにコードを編集すると、エラーの修正や検証がしやすくなります。

  4. 保存した変更のアクティブ化

    変更をアクティブ化すると、WebLogic Serverは保存された保留中の構成ファイルをドメイン内のすべてのサーバーにコピーします。各サーバーは変更を評価して、その変更を使用できるかどうかを示します。使用できる場合、各サーバーはアクティブな構成ファイルと、構成MBeanのメモリー内の階層を更新します。

  5. サーバーの再起動を必要とする変更内容で更新されたサーバー・インスタンスがあれば、再起動します。

MBeanの編集および編集のアクティブ化の例については、「例:管理ポートの変更」を参照してください。

編集セッションの開始

編集セッションを開始するには、次の手順に従います。

  1. 編集MBeanサーバーへの接続を開始します。

    接続はjava.management.MBeanServerConnection型のオブジェクトを返します。

    「MBeanサーバーへのリモート接続の作成」を参照してください。

  2. ConfigurationManagerMBeanのオブジェクト名を取得します。

    ConfigurationManagerMBeanは、編集セッションの開始および停止、構成に対する変更の保存、取消しおよびアクティブ化を行うためのメソッドを提供します。(Oracle WebLogic Server MBeanリファレンスConfigurationManagerMBeanを参照してください。)

    各ドメインはConfigurationManagerMBeanのインスタンスを1つだけ持ち、そのインスタンスはEditServiceMBean ConfigurationManager属性に格納されます。EditServiceMBeanはすべての編集操作のエントリ・ポイントです。簡単な固定のオブジェクト名を持ち、編集MBeanサーバー内の他のすべてのMBeanにアクセスするための属性と操作が含まれています。

    ConfigurationManagerMBeanオブジェクト名を取得するには、次のメソッドを使用します。

    MBeanServerConnection.getAttribute(
        ObjectName object-name, String attribute)
    

    前のメソッド構文で、

    • object-name: リテラル"com.bea:Name=EditService,Type=weblogic.management.mbeanservers.edit.EditServiceMBean"。これはEditServiceMBeanのオブジェクト名です。

    • attribute: リテラルConfigurationManager。これはConfigurationManagerMBeanを含むEditServiceMBeanの属性の名前です。

  3. 編集セッションの開始

    編集セッションを開始するには、ConfigurationManagerMBean startEdit(int waitTime, int timeout)操作を呼び出します。各要素の説明は次のとおりです。

    • waitTime: 編集MBean階層でロックを確立するために、ConfigurationManagerMBeanが待機するミリ秒数を指定します。管理者権限を持たない限り、他の編集が進行中の場合にロックを確立することはできません(「ロックの管理」を参照してください) 。

    • timeout: 編集セッションを完了しなければならないミリ秒数を指定します。編集を保存またはアクティブ化する前に時間切れになると、保存されていない変更はすべて破棄されます。

    startEdit操作は次のいずれかを返します。

    • 指定した時間内に編集ツリーでロックを確立できない場合は、weblogic.management.mbeanservers.edit.EditTimedOutExceptionをスローします。

    • 編集ツリーを正常にロックした場合は、DomainMBeanのオブジェクト名を返します。これが編集MBean階層のルートになります。

MBean属性の変更または新しいMBean作成

既存のMBeanの属性値を変更する、新しいMBeanを作成する、またはMBeanを削除するには、次の手順に従います。

  1. 編集ツリーの階層を移動して、編集するMBeanのオブジェクト名を取得します。MBeanを作成または削除するには、適切なファクトリ・メソッドを含むMBeanのオブジェクト名を取得します。
  2. MBean属性の値を変更するには、MBeanServerConnection.setAttribute(object-name, attribute)メソッドを呼び出します。各要素の説明は次のとおりです。
    • object-name: 編集するMBeanのオブジェクト名。

    • attribute: javax.management.Attributeオブジェクト。変更するMBean属性の名前とその新しい値が格納されます。

    MBeanを作成するには、そのMBeanの作成メソッドを呼び出します。たとえば、ServerMBeanのインスタンスを作成するファクトリ・メソッドは、DomainMBeancreateServer(String name)です。Oracle WebLogic Server MBeanリファレンスでは、各MBeanのファクトリ・メソッドの場所が説明されています(「ServerMBean」を参照)。

  3. (オプション)複数のステップに分けて編集を行う場合は、ConfigurationManagerMBean validate()操作を呼び出して、各ステップの後に変更を検証することを検討してください。

    validateメソッドでは、未保存のすべての変更が、MBean属性間の依存関係に関する要件を満たしているかどうかを検証し、1つの属性の値が設定されただけでは行うことのできないその他のチェックを実施します。

    検証エラーが見つかった場合、validate()操作はweblogic.management.mbeanservers.edit.ValidationException型の例外をスローします。「編集処理によって送出される例外の型」を参照してください。

    save()操作も保存前に変更を検証するので、ここでの検証はオプションです。

保留中の構成ファイルへの変更の保存

ConfigurationManagerMBean save()操作を呼び出して変更を保存します。

保存した変更のアクティブ化

保存した変更をドメイン内でアクティブ化するには、次の手順に従います。

  1. ConfigurationManagerMBean activate(long timeout)操作を呼び出します。timeoutには、操作が完了する必要のあるミリ秒数を指定します。

    activate操作はActivationTaskMBeanのインスタンスのオブジェクト名を返します。このインスタンスにはアクティブ化リクエストに関する情報が含まれています。「変更の表示と取消し」を参照してください

    activate操作が成功するかタイムアウトすると、編集可能なMBean階層でロックが解放されます。

  2. JMXConnector.close()を呼び出して、MBeanサーバーへの接続を閉じます。

例:管理ポートの変更

例5-1のサンプル・コードでは、ドメインのWebLogic Server管理コンソールにアクセスするために使用するコンテキスト・パスを変更しています。この動作はDomainMBean ConsoleContextPath属性で定義されます。

サンプル・コードに関する以下の点に留意してください。

例5-1 例: 管理コンソールのコンテキスト・パスの変更

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;

import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;

public class EditWLSMBeans {
   private static MBeanServerConnection connection;
   private static JMXConnector connector;
   private static final ObjectName service;

   // Initializing the object name for EditServiceMBean
   // so it can be used throughout the class.
   static {
      try {
        service = new ObjectName(
           "com.bea:Name=EditService,Type=weblogic.management.mbeanservers.
            edit.EditServiceMBean");
      } catch (MalformedObjectNameException e) {
         throw new AssertionError(e.getMessage());
      }
   }

   /**
   * ----------------------------------------------------------
   * Methods to start an edit session.
   * NOTE: Error handling is minimal to help you see the 
   *       main steps in editing MBeans. Your code should
   *       include logic to catch and process exceptions.
   * ----------------------------------------------------------
   */

   /*
   * Initialize connection to the Edit MBean Server.
   */
   public static void initConnection(String hostname, String portString,
      String username, String password) throws IOException,
      MalformedURLException {

      String protocol = "t3";
      Integer portInteger = Integer.valueOf(portString);
      int port = portInteger.intValue();
      String jndiroot = "/jndi/";
      String mserver = "weblogic.management.mbeanservers.edit";

      JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,
      jndiroot + mserver);

      Hashtable h = new Hashtable();
      h.put(Context.SECURITY_PRINCIPAL, username);
      h.put(Context.SECURITY_CREDENTIALS, password);
      h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
         "weblogic.management.remote");
         connector = JMXConnectorFactory.connect(serviceURL, h);
         connection = connector.getMBeanServerConnection();
   }

   /**
   * Start an edit session.
   */
   public ObjectName startEditSession() throws Exception {
      // Get the object name for ConfigurationManagerMBean.
      ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
         "ConfigurationManager");

      // Instruct MBeanServerConnection to invoke
      // ConfigurationManager.startEdit(int waitTime int timeout).
      // The startEdit operation returns a handle to DomainMBean, which is
      // the root of the edit hierarchy.
      ObjectName domainConfigRoot = (ObjectName) 
         connection.invoke(cfgMgr,"startEdit", 
         new Object[] { new Integer(60000),
         new Integer(120000) }, new String[] { "java.lang.Integer",
         "java.lang.Integer" });
      if (domainConfigRoot == null) {
         // Couldn't get the lock
         throw new Exception("Somebody else is editing already");
      }
      return domainConfigRoot;

   /**
   * ----------------------------------------------------------
   * Methods to change MBean attributes.
   * ----------------------------------------------------------
   */

   /**
   * Modify the DomainMBean's ConsoleContextPath attribute.
   */
   public void editConsoleContextPath(ObjectName cfgRoot) throws Exception {
      // The calling method passes in the object name for DomainMBean.
      // This method only needs to set the value of an attribute
      // in DomainMBean.
      Attribute adminport = new Attribute("ConsoleContextPath", new String(
         "secureConsoleContext"));
      connection.setAttribute(cfgRoot, adminport);
      System.out.println("Changed the Administration Console context path to " +
         "secureConsoleContext");
   }

   /**
   * ----------------------------------------------------------
   * Method to activate edits.
   * ----------------------------------------------------------
   */
   public ObjectName activate() throws Exception {
      // Get the object name for ConfigurationManagerMBean.
      ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
         "ConfigurationManager");
      // Instruct MBeanServerConnection to invoke
      // ConfigurationManager.activate(long timeout).
      // The activate operation returns an ActivationTaskMBean.
      // You can use the ActivationTaskMBean to track the progress
      // of activating changes in the domain.
      ObjectName task = (ObjectName) connection.invoke(cfgMgr, "activate",
         new Object[] { new Long(120000) }, new String[] { "java.lang.Long" });
      return task;
   }

   public static void main(String[] args) throws Exception {
      String hostname = args[0];
      String portString = args[1];
      String username = args[2];
      String password = args[3];

      EditWLSMBeans ewb = new EditWLSMBeans();

      // Initialize a connection with the MBean server.
      initConnection(hostname, portString, username, password);

      // Get an object name for the Configuration Manager.
      ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
         "ConfigurationManager");

      // Start an edit session.
      ObjectName cfgRoot = ewb.startEditSession();
      // Edit the server log MBeans.
      ewb.editConsoleContextPath(cfgRoot);

      // Save and activate.
      connection.invoke(cfgMgr, "save", null, null);
      ewb.activate();

      // Close the connection with the MBean server.
      connector.close();
   }
}

編集操作によってスローされる例外の型

表5-1では、編集操作中にWebLogic Serverがスローする可能性があるすべての例外の型について説明します。WebLogic Serverがこのような例外をスローすると、MBeanサーバーはjavax.management.MBeanExceptionで例外をラップします。(Java SE 8 API仕様MBeanException (http://docs.oracle.com/javase/8/docs/api/javax/management/MBeanException.html)を参照してください。)

表5-1 編集操作によってスローされる例外の型

例外の型 スローされる場合
EditTimedOutException

編集セッションを開始するリクエストがタイムアウトした場合。

NotEditorException

ロックを取得せずにMBeanを編集しようとした場合、または、管理ユーザーが現在のロックを取り消して編集セッションを開始する場合。

ValidationException

MBean属性の値を、誤ったデータ型、許容される範囲外の値、指定された値ではない値、他の属性との依存関係に適合しない値などに設定した場合。

変更の表示と取消し

以下の節では、編集セッション中に行った変更の操作について説明します。

WebLogic Serverはjavax.management.openmbean.CompositeType型のChangeオブジェクトに変更を記述します。Java SE 8 API仕様CompositeType (http://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeType.html)を参照してください。

JMXを通じて、現在のサーバー・セッション中にのみ発生したドメインの構成の変更に関する情報にアクセスできます。WebLogic Serverは構成ファイルのアーカイブを保持しますが、JMXを通じてアーカイブされたデータを利用したり、アーカイブのバージョンを比較したりはできません。

保存されていない変更の表示

MBean属性を変更するたびに、WebLogic Serverはその変更に関する情報が含まれるChangeオブジェクトを作成します。変更を保存するまでは、これらのオブジェクトにConfigurationManagerMBean Changes属性からアクセスできます。Oracle WebLogic Server MBeanリファレンスConfigurationManagerMBeanを参照してください。

編集セッションを終了するときに、保存されていない変更は破棄されます。

保存されていない変更を表示するには、次の手順に従います。

  1. 編集セッションを開始して、少なくとも1つのMBean属性を変更します。
  2. ConfigurationManagerMBean Changes属性の値を取得して、その出力をObject[]型の変数に割り当てます。
  3. 配列内のオブジェクトごとにObject.toString()を呼び出して、変更の説明を出力します。

    Changejavax.management.openmbean.CompositeTypeなので、配列内の各項目をCompositeTypeとしてキャストし、変更に対してCompositeTypeのメソッドを呼び出すこともできます。Java SE 8 API仕様CompositeType (http://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeType.html)を参照してください。

例5-2 保存されていない変更を表示するサンプル・メソッド

public void listUnsaved() throws Exception {
   ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
   "ConfigurationManager");
   Object[] list = (Object[])connection.getAttribute(cfgMgr, "Changes");
   int length = (int) list.length;
   for (int i = 0; i < length; i++) {
      System.out.println("Unsaved change: " + list[i].toString());
   }
}

例5-2のコードでは、保存されていない変更を表示するメソッドを作成します。呼出し側メソッドは編集MBeanサーバーとの接続をすでに確立しているものとします。

アクティブ化されていない変更の表示

変更が保存されると、WebLogic Serverは保留中の構成ファイルで変更を永続化します。編集セッションを開始したユーザーがConfigurationManagerMBean undoUnactivatedChanges()操作(アクティブ化されていない変更を保留中ファイルから元に戻す)を呼び出さない限り、複数の編集セッションにわたる場合でも、変更は保留中の構成ファイルに保持されます。

ConfigurationManagerMBean UnactivatedChanges属性には、保存されていない変更と、保存されてまだアクティブ化されていない変更の両方のChangeオブジェクトが格納されます。(保存されてまだアクティブ化されていない変更のみを格納する属性はありません。)Oracle WebLogic Server MBeanリファレンスConfigurationManagerMBeanのアクティブ化されていない変更を参照してください。

現在の編集セッション中に保存してまだアクティブ化していない変更、または以前の編集セッションで保存されてまだアクティブ化されていない変更を表示するには、次の手順に従います。

  1. 編集セッションを開始して、少なくとも1つのMBean属性を変更します。
  2. ConfigurationManagerMBean UnactivatedChanges属性の値を取得して、その出力をObject[]型の変数に割り当てます。
  3. 配列内のオブジェクトごとにObject.toString()を呼び出して、変更の説明を出力します。

    Changejavax.management.openmbean.CompositeTypeなので、配列内の各項目をCompositeTypeとしてキャストし、変更に対してCompositeTypeのメソッドを呼び出すこともできます。Java SE 7 API仕様CompositeType (http://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeType.html)を参照してください。

例5-3 アクティブ化されていない変更を表示するサンプル・メソッド

public void listUnactivated() throws Exception {
   ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
   "ConfigurationManager");
   Object[] list = (Object[])connection.getAttribute(cfgMgr,
      "UnactivatedChanges");
   int length = (int) list.length;
   for (int i = 0; i < length; i++) {
      System.out.println("Unactivated changes: " + list[i].toString());
   }
}

例5-3のコードでは、アクティブ化されていない変更を表示するメソッドを作成します。呼出し側メソッドは編集MBeanサーバーとの接続をすでに確立しているものとします。

現在のアクティブ化タスクにある変更の表示

変更をアクティブ化すると、WebLogic ServerはActivationTaskMBeanのインスタンスを作成します。このインスタンスには、アクティブ化される変更ごとに1つのChangeオブジェクトが格納されます。このActivationTaskMBeanには、次のいずれかからアクセスできます。

  • ConfigurationManagerMBean activate()メソッド - 現在のアクティブ化タスクを表すActivationTaskMBeanのオブジェクト名を返します。

  • ConfigurationManagerMBean CompletedActivationTasks属性 - 現在の管理サーバーのインスタンス化中に作成されたすべてのActivationTaskMBeanインスタンスのリストが含まれている可能性があります。「メモリーに格納されているすべてのアクティブ化タスクの表示」を参照してください。

現在のアクティブ化タスクにある変更のみを表示するには、次の手順に従います。

  1. 編集セッションの開始
  2. activate操作の出力をjavax.management.ObjectName型のインスタンス変数に割り当てます。
  3. ActivationTaskMBean Changes属性の値を取得して、その出力をObject[]型の変数に割り当てます。
  4. 配列内のオブジェクトごとにObject.toString()を呼び出して、変更の説明を出力します。

    Changejavax.management.openmbean.CompositeTypeなので、配列内の各項目をCompositeTypeとしてキャストし、変更に対してCompositeTypeのメソッドを呼び出すこともできます。Java SE 8 API仕様CompositeType (http://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeType.html)を参照してください。

例5-4 現在のアクティブ化タスクにある変更を表示するサンプル・メソッド

public void activateAndList() 
   throws Exception {
   ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
      "ConfigurationManager");
   ObjectName task = (ObjectName) connection.invoke(cfgMgr, "activate",
      new Object[] { new Long(120000) }, new String[] { "java.lang.Long" });
   Object[] changes = (Object[])connection.getAttribute(task, "Changes");
   int i = (int) changes.length;
   for (int i = 0; i< i; i++) {
      System.out.println("Changes activated: " + changes[i].toString());
   }
}

例5-4のコードでは、現在の編集セッションでアクティブ化されたすべての変更を表示するメソッドを作成します。呼出し側メソッドは編集MBeanサーバーとの接続をすでに確立しているものとします。

変更の取消し

ConfigurationManagerMBeanには、編集セッション中に行われた変更を取り消すための2つの操作があります。

  • undo

    保存されていない変更を元に戻します。

  • undoUnactivatedChanges

    保存されているかどうかに関わらず、まだアクティブ化されていないすべての変更を元に戻します。以前の編集セッションで他のユーザーが変更を保存して、その変更をアクティブ化していない場合に、ConfigurationManagerMBean undoUnactivatedChanges()操作を呼び出すと、それらの変更も元に戻されます。

    このメソッドを呼び出した後、保留中の構成ファイルは、アクティブなサーバーが使用している動作中の構成ファイルと同じになります。

変更を取り消すには、編集セッションを開始して、ConfigurationManagerMBean undoまたはundoUnactivatedChanges操作を呼び出します。

たとえば:

connection.invoke(cfgMgr, "undo", null, null); 

変更のアクティブ化の追跡

activate操作を呼び出すときにWebLogic Serverが作成する各ActivationTaskMBeanでは、変更のリストを保持する他に、変更をアクティブ化したユーザー、アクティブ化タスクのステータス、変更がアクティブ化された時刻が記述されます。

管理サーバーはActivationTaskMBeanのインスタンスをメモリー内にのみ保持します。つまり、インスタンスは永続化されず、管理サーバーを停止するときに破棄されます。ActivationTaskMBeanインスタンスにはChangeオブジェクトのリスト(各オブジェクトはMBean属性の1つの変更を表す)が含まれているため、メモリーを大量に使用します。メモリーを節約するため、デフォルトでは、管理サーバーはごく最近のActivationTaskMBeanインスタンスしかメモリー内に保持しません。デフォルトを変更するには、ConfigurationManagerMBean CompletedActivationTasksCount属性の値を増やします。

以下の節では、ActivationTaskMBeanのインスタンスの操作について説明します。

現在のアクティブ化タスクのステータスの表示

activate操作を呼び出すと、WebLogic Serverはアクティブ化タスクを表現するActivationTaskMBeanインスタンスを返します。

ActivationTaskMBean State属性は、アクティブ化タスクのステータスを表します。この属性にはint値が格納され、ActivationTaskMBeanは各int値の定数を定義します。Oracle WebLogic Server MBeanリファレンスActivationTaskMBeanを参照してください。

現在のアクティブ化タスクのステータスを表示するには、次の手順に従います。

  1. 編集セッションを開始して、少なくとも1つのMBean属性を変更します。
  2. ConfigurationManagerMBean activate(long timeout)操作を呼び出して、その出力をActivationTaskMBean型の変数に割り当てます。
  3. ActivationTaskMBean State属性の値を取得します。

メモリーに格納されているすべてのアクティブ化タスクの表示

activate操作が返すActivationTaskMBeanは1つのアクティブ化タスクのみを表します。管理サーバーは、ユーザーがパージするまでこのActivationTaskMBeanをメモリー内に保持します(「完了したアクティブ化タスクのメモリーからのパージ」を参照)。パージしないと、アクティブ化タスクの数はConfigurationManagerMBean CompletedActivationTasksCount属性の値を超えます。

現在メモリーに格納されているすべてのActivationTaskMBeanインスタンスにアクセスするには、次の手順に従います(例5-5を参照してください)。

  1. 編集MBeanサーバーに接続します。(編集セッションを開始する必要はありません。)
  2. ConfigurationManagerMBean CompletedActivationTasks属性の値を取得して、その出力をObject[]型の変数に割り当てます。
  3. (オプション)配列内のオブジェクトごとに、ActivationTaskMBeanの属性(UserStateなど)の値を取得して出力します。

    Oracle WebLogic Server MBeanリファレンスActivationTaskMBeanを参照してください。

  4. (オプション)配列内のオブジェクトごとに、Changes属性の値を取得します。Object.toString()を呼び出して、Changeオブジェクトの値を出力します。

例5-5 メモリー内のすべてのアクティブ化タスクを表示するサンプル・メソッド

public void listActivated() throws Exception {
   ObjectName cfgMgr = (ObjectName) connection.getAttribute(service,
   "ConfigurationManager");
   ObjectName[] list = (ObjectName[])connection.getAttribute(cfgMgr,
      "CompletedActivationTasks");
   System.out.println("Listing completed activation tasks.");
   int length = (int) list.length;
   for (int i = 0; i < length; i++) {
      System.out.println("Activation task " + i);
      System.out.println("User who started activation: " +
         connection.getAttribute(list[i], "User"));
      System.out.println("Task state: " + connection.getAttribute(list[i],
         "State"));
      System.out.println("Start time: " + connection.getAttribute(list[i],
         "StartTime"));

      Object[] changes = (Object[])connection.getAttribute(list[i], "Changes");
      int l = (int) changes.length;
      for (int y = 0; y < l; y++) {
         System.out.println("Changes activated: " + changes[y].toString());
      }
   }
}

完了したアクティブ化タスクのメモリーからのパージ

ActivationTaskMBeanインスタンスにはChangeオブジェクトのリスト(各オブジェクトはMBean属性の1つの変更を表す)が含まれているため、メモリーを大量に使用します。

管理サーバーでメモリー不足になった場合は、完了したアクティブ化タスクをメモリーからパージできます。その後でConfigurationManagerMBean CompletedActivationTasksCount属性の値を減らします。

完了したアクティブ化タスクをメモリーからパージするには、編集MBeanサーバーに接続して、ConfigurationManagerMBean purgeCompletedActivationTasks操作を呼び出します。

たとえば:

connection.invoke(cfgMgr, "purgeCompletedActivationTasks", null, null);

ロックの管理

変更によって保留中の構成MBean階層が矛盾した状態にならないように、一度に1人のユーザーだけがMBeanを編集できます。ユーザーがConfigurationManagerMBean startEdit操作を呼び出すと、ConfigurationManagerMBeanは他のユーザーが編集セッションを開始できないように(ロック)します。

以下のアクションによってロックが解除されます。

  • ConfigurationManagerMBean activate操作が成功するか、タイムアウトします。

    ActivationTaskMBean waitForTaskCompletion操作を使用すると、アクティブ化プロセスが完了するまでブロックできます。

  • ConfigurationManagerMBean stopEdit操作が成功します。

  • 他のユーザーがロックを取得しているときに、管理者権限を持つユーザーがConfigurationManagerMBean cancelEdit操作を呼び出します。

    たとえば、connection.invoke(cfgMgr, "cancelEdit", null, null);

  • あるユーザーIDにより編集セッションが開始され、別のプロセスが同じユーザーIDで編集セッションを開始します。

    たとえば、WebLogic Server管理コンソールを使用して編集セッションを開始し、その後でWebLogic Scripting Tool (WLST)を使用して同じユーザーIDで編集セッションを開始することができます。WLSTのセッションによってWebLogic Server管理コンソールのセッションのロックは解除されます。

    別のプロセスが同じユーザーIDで編集セッションを開始しないようにするには、startEdit操作にbooleanの値trueを渡して、排他的なロックを取得します。Oracle WebLogic Server MBeanリファレンスstartEdit(waitTimeInMillis, timeOutInMillis, exclusive)を参照してください。

ロックが解除されると、保存されていないすべての変更は失われます。

ベスト・プラクティス:編集と例外処理の推奨パターン

編集するコードを複数のtry-catchブロックに整理することをお薦めします。そのようにすると、特定の型のエラーを捕捉して適切に対応できます。たとえば、編集が無効な場合に編集セッション全体を破棄するのではなく、その変更を保存して、例外をスローし、無効な変更をアクティブ化せずに終了することができます。

JMXエージェントはすべての例外をjavax.management.MBeanException型の汎用的な例外でラップします。JMXクライアントはMBeanException.getTargetException()を使用して、ラップされた例外のラップを解除することができます。

以下のような構成を利用することを検討してください(例5-6の擬似コードを参照してください) 。

  • 編集MBeanサーバーに接続し、編集セッションを開始し、変更を行って保存するtryブロック。

    このtryブロックの後、MBeanException内にラップされた以下の型の例外ごとに1つのcatchブロック。

    • EditTimedOutException

      ConfigurationManagerMBean startEdit()操作が指定された時間内にロックを取得できない場合、この例外がスローされます。

    • NotEditorException

      編集セッションがタイムアウトするか、管理者がユーザーの編集セッションを取り消した場合、この例外がスローされます(「ロックの管理」を参照してください。)

    • ValidationException

      誤ったデータ型、許容される範囲外の値、指定された値ではない値、他の属性との依存関係に適合しない値などをMBeanに設定した場合、この例外がスローされます。

      ValidationExceptionを処理するコードの内部には、検証エラーを修正する、またはConfigurationManagerMBean stopEdit()操作を呼び出して編集セッションを停止するtryブロックを入れます。tryブロックで編集セッションを停止する場合、そのcatchブロックではNotEditorExceptionを無視する必要があります。この例外は、保留中の構成MBean階層でのロックを失ったことを表しますが、ここでは変更を破棄してロックを解放しようとしているので、この例外がスローされてもエラー状態ではありません。

  • 保存された変更をアクティブ化するtryブロック。

    ConfigurationManager activate(long timeout)操作はActivationTaskMBeanのインスタンスを返します。このインスタンスには、アクティブ化タスクに関する情報が格納されています。activate()のタイムアウト期間を1分間に設定して、その後でActivationTaskMBean State属性の値をチェックすることをお薦めします。

    Stateに定数STATE_COMMITTEDが含まれている場合、変更はドメインで正常にアクティブ化されたことになります。この時点でreturn文を使用して編集作業を終了できます。アクティブ化タスクが成功すると、startEdit()で作成したロックが解放されます。

    Stateに別の値が含まれている場合、アクティブ化はactivate(long timeout)で指定したタイムアウト期間中に成功しなかったことになります。ActivationTaskMBean Error属性の値を取得すると原因を見つけられます。

    このtryブロックの後、ラップされた以下の型の例外を捕捉する1つのcatchブロック。

    NotEditorException 
    

    変更をアクティブ化するときにこの例外がスローされた場合は、編集セッションがタイムアウトしたか管理者によって取り消されたために、変更はアクティブ化されません。

  • (オプション)保存された変更を取り消すtryブロック。

    クラスがアクティブ化のtryブロックで終了(return)しない場合、アクティブ化タスクは成功しなかったことになります。保存されている変更が、将来の試行でアクティブ化されないようにするには、ConfigurationManagerMBean undoUnactivatedChanges()操作を呼び出します。

    そうしない場合、保存されている変更は保留中の構成ファイルに保持されます。次回、あるユーザーが保存した変更をアクティブ化しようとすると、WebLogic Serverはそのユーザーが保存した変更と一緒に、保存されている変更をアクティブ化しようとします。

    このtryブロックの後、ラップされた以下の型の例外を無視する1つのcatchブロック。

    NotEditorException 
    
  • 編集セッションを停止するtryブロック。

    アクティブ化タスクが失敗した場合に変更を破棄する場合は、元のタイムアウト期間が経過するのを待つ必要はありません。編集を直ちに停止できます。

    このtryブロックの後、以下の型の例外を無視する1つのcatchブロック。

    NotEditorException 
    
  • ActivationTaskMBean Error属性に格納されている例外をスローします。

例5-6 編集と例外処理のコードの概要

try {
   //Initialize the connection and start the edit session
...
   ObjectName domainConfigRoot = (ObjectName) connection.invoke(cfgMgr,
      "startEdit", 
      new Object[] { new Integer(30000), new Integer(300000) },
      new String[] { "java.lang.Integer", "java.lang.Integer" });

   // Modify the domain 
   ...
   // Save your changes
    connection.invoke(cfgMgr, "save", null, null);

} catch (MBeanException e) {
   Exception targetException = e.getTargetException();
   if (targetException instanceof EditTimedOutException) {
      // Could not get the lock. Notify user
      ...
      throw new MyAppCouldNotStartEditException(e);
   }
   if (targetException instanceof NotEditorException) {
      ...
      throw new MyAppEditSessionFailed(e);
   }
   if (targetException instanceof ValidationException) {
      ...
      try {
        connection.invoke(cfgMgr, "stopEdit", null, null);
      // A wrapped NotEditorException here indicates that you no longer have a
      // lock on the pending configuration MBean hierarchy; however, 
      // because you want to abandon changes and release your lock anyway,
      // it is not an error condition for this exception to be thrown 
      // and you can safely ignore it.
      } catch (MBeanException e) {
         Exception targetException = e.getTargetException();
         if (targetException instanceof NotEditorException) {
            //ignore
         }
      }
      throw new MyAppEditChangesInvalid(e);
   }
   else {
   throw MBeanException (e);
   }
}

// Changes have been saved, now activate them
try {
   // Activate the changes
   ActivationTaskMBean task = (ObjectName) connection.invoke(cfgMgr,
      "activate",
      new Object[] { new Long(60000) }, 
      new String[] { "java.lang.Long" });
   // Everything worked, just return.
   String status = (String) connection.getAttribute(task, "State");
   if (status.equals("4"))
   return;
   // If there is an activation error, use ActivationTaskMBean.getError
   // to get information about the error
   failure = connection.getAttribute(task, "Error");
// If you catch a wrapped NotEditorException, your changes were not activated
// because your edit session ended or was cancelled by an administrator.
// Throw the wrapped exception.
} catch (MBeanException e) {
   Exception targetException = e.getTargetException();
   if (targetException instanceof NotEditorException) {
      ...
      throw new MyAppEditSessionFailed(e);
   }
}

// If your class executes the remaining lines, it is because activating your
// saved changes failed.
// Optional: You can undo the saved changes that failed to activate. If you
// do not undo your saved changes, they will be activated the next time 
// someone attempts to activate changes.
// try {
//     {
//      connection.invoke(cfgMgr, "undoUnactivatedChanges", null, null);
// catch(MBeanException e) {
//   Exception targetException = e.getTargetException();
//   if (targetException instanceof NotEditorException) {
//      ...
//      throw new MyAppEditSessionFailed(e);
//   }
// }

// Stop the edit session
try {
   connection.invoke(cfgMgr, "stopEdit", null, null);
   // If your activation attempt fails and you are ready to abandon
   // changes, there is no need to wait until your original timeout 
   // period to expire. You can stop editing immediately 
   // and you can safely ignore any wrapped NotEditorException.
} catch (MBeanException e) {
   Exception targetException = e.getTargetException();
   if (targetException instanceof NotEditorException) {
      //ignore
   }
}
...
// Output the information about the error that caused the activation to
// fail.
throw new MyAppEditSessionFailed(connection.getAttribute(task, "Error"));

暗号化された値の設定と取得

権限のないアクセスからパスワードなどの重要なデータを保護するために、WebLogic Server構成MBeanのいくつかの属性は暗号化されます。そうした属性の値はドメインのconfig.xmlファイルに暗号化された文字列として保持され、メモリー内の値は暗号化されたバイト配列として表されます。暗号化されている属性は、名前がEncryptedで終わります。たとえばServerMBeanでは、IIOPプロトコルを介したアクセスの保護に使用されるパスワードがDefaultIIOPPasswordEncryptedという名前の属性として公開されます。後方互換性をサポートし、リモートのJMXクライアントがWebLogic Server MBeanのパスワードを設定できるようにするため、暗号化される各属性では、値を暗号化して設定するための、安全性がやや低い手段を提供しています。

以下の節では、暗号化された属性の扱い方について説明します。

暗号化された属性の値の設定(推奨技術)

この方法を使用するには、(例5-7を参照してください) 。

  1. MBean属性をホストしている同じWebLogic Server JVMで、バイト配列に値を書き込みます。
  2. バイト配列をweblogic.management.EncryptionHelper.encrypt( byte[])メソッドに渡し、その戻り値をMBeanServerConnection.setAttributeメソッドに渡します。

    暗号化された配列を変数には割り当てないでください。変数に割り当てると、ガベージ・コレクションが行われてメモリーが再割当てされるまで、暗号化されていないバイト配列がメモリー内に保持されます。

  3. weblogic.management.EncryptionHelper.clear()メソッドを使用して、元のバイト配列を消去します。

例5-7 例:暗号化された属性の値の設定(推奨技術)

public void editDefaultIIOPPassword(ObjectName cfgRoot) throws Exception {
   // Get the ServerMBean from the DomainMBean
   ObjectName server = (ObjectName) connection.invoke(cfgRoot,
      "lookupServer", new Object[] { "myserver" },
   new String[] { "java.lang.String" });
   // Get new password from standard in. Assign it to a byte array.
   System.out.println("Enter new password and press enter: ");
   byte userinput[] = new byte[10];
   System.in.read(userinput);
   // Encrypt the byte array and set it as the encrypted
   // attribute value.
   Attribute newpassword = new Attribute("DefaultIIOPPasswordEncrypted",
      weblogic.management.EncryptionHelper.encrypt(userinput));
   connection.setAttribute(server, newpassword);
   System.out.println("New password is set to: " + 
      connection.getAttribute(server, "DefaultIIOPPasswordEncrypted"));
   // Clear the byte array.
   weblogic.management.EncryptionHelper.clear(userinput);
   }

暗号化された属性の値の設定(互換性のある技術)

9.0より前では、JMXクライアントは暗号化された値を設定するための別の方法を使用していました。JMXクライアントはこの互換性のある方法を引続き使用できます。また、リモートJMXクライアントから暗号化された値を設定する場合は、この方法のみを使用できます。互換性のある方法では、暗号化されていないパスワードを格納するStringを作成するので、安全性が低くなります。WebLogic ServerがStringを暗号化されたバイト配列に変換しても、ガベージ・コレクションが行われてメモリーが再割当てされるまで、Stringはメモリー内に残ります。

互換性のある方法を使用するには、次の手順に従います。

  1. 値をStringに書き込みます。
  2. StringをパラメータとしてMBeanServerConnection.setAttributeメソッドに渡します。ただし、暗号化された属性の値を設定するかわりに、対応する暗号化されていない属性の値を設定します。

    WebLogic ServerはStringを暗号化されたバイト配列に変換し、それをCustomIdentityKeyStorePassPhraseEncryptedとして設定します(CustomIdentityKeyStorePassPhraseの値は設定しません)。

    たとえば、リモートJMXクライアントからCustomIdentityKeyStorePassPhraseEncryptedを設定するには、CustomIdentityKeyStorePassPhraseという属性に対してMBeanServerConnection.setAttributeを呼び出します。

たとえば:

public void editDefaultIIOPPassword(ObjectName cfgRoot, String password) 
    throws Exception {
    // Get the ServerMBean from the DomainMBean
    ObjectName server = (ObjectName) connection.invoke(cfgRoot, "lookupServer",
        new Object[]{"myserver"},new String[]{"java.lang.String"});
    Attribute newpassword = new Attribute("DefaultIIOPPassword",
       "mypassword");
    connection.setAttribute(server, newpassword);
} 

暗号化された値のバックアップ

パスワードのバックアップ・コピーを作成するには、MBeanの暗号化された値のゲッター・メソッドを使用して、暗号化されたバイト配列を取得します。次に、バイト配列の値をファイルに書き込みます。WebLogic Serverでは、暗号化されている値を復号化するAPIまたは他のユーティリティは提供していません。

パスワードの値を回復する必要がある場合は、保存した値をバイト配列に読み込んで、それをパラメータとしてMBeanServerConnection.setAttributeメソッドに渡すことができます(「暗号化された属性の値の設定(推奨技術)」を参照してください) 。

ノート:

WebLogic Serverドメインでは独自の暗号化アルゴリズムを使用しているため、パスワードの暗号化されていない値がすべてのドメインで同じ場合でも、ドメインごとに別々にパスワードをバックアップして回復する必要があります。

各ドメインで暗号化された同じパスワードをバックアップするかわりに、MBeanの対応する暗号化されていない値のゲッター・メソッドを使用できます。このゲッターはパスワードを復号化してStringにコピーします。ガベージ・コレクションが行われてメモリーが再割当てされるまで、Stringはメモリーから消去されません。