ライフサイクル・リスナの開発

ライフサイクル・リスナのモジュールは、アプリケーション・サーバ環境内で短期、または長期の間、動作させる手段として、Javaベースのタスクとして提供します。 短い期間のタスクの例としては、シングルトンのインスタンス化があります。 また、長い期間のタスク例として、RMIサーバの起動から停止までの管理などがあります。 これらのモジュールは、サーバの開始時に自動的に初期化され、それ以降、サーバのライフサイクルの中における様々なフェーズで通知を受けます。

 
サーバのライフサイクル・イベント

ライフサイクル・モジュールは、サーバのライフサイクルの中で下記のイベントに応じた受け入れ準備をしており、イベントを受け取るとそのイベントに応じた該当タスクを実行します。

これらのイベントは、LifecycleEventクラスで定義されます。

これらのイベントに受け入れ準備をするライフサイクル・モジュールは、LifecycleListenerインタフェースを実装し、domain.xmlファイルの中で構成化されます。

 
LifecycleListenerインタフェース

ライフサイクル・モジュールを生成することは、com.nec.webotx.appserv.server.LifecycleListenerインタフェースを実装する、カスタマイズされたクラスを構成することです。 開発者は、複数のライフサイクル・モジュールを生成して、同時に実行することができます。

LifecycleListenerインタフェースでは、以下のメソッドを定義します。

LifecycleListenerインタフェースのサンプル実装を以下のように、LifecycleListenerImpl.javaファイルとして示します。 このソースコードをライフサイクル・イベントのテスト用としても使用できます。

package com.nec.webotx.sample;

import java.util.Properties;
import com.nec.webotx.appserv.server.*;

/**
* LifecycleListenerImplは、LifecycleListenerインタフェースのダミー実装です。
* この実装は、ライフサイクル・インタフェースのメソッドから様々なイベントを
* 確認します。
*/

public class LifecycleListenerImpl implements LifecycleListener {

    /** サーバ・ライフサイクル・イベントを受け取ります。
    * @param event 関連付けられるイベント
    * @throws 例外条件に対応したServerLifecycleException
    *
    * domain.xmlの中にlifecycle-module要素としてこのモジュールを構成します。
    *
    * <applications>
    *     <lifecycle-module name="test"
    *                 class-name="com.nec.webotx.sample.LifecycleListenerImpl"
    *                 is-failure-fatal="false">
    *         <property name="foo" value="fooval"/>
    *     </lifecycle-module>
    * </applications>
    *
    * 致命的な条件に対しては、domain.xmlの中のis-failure-fatalにtrueを
    * 設定してください。
    */
    public void handleEvent(LifecycleEvent event) throws ServerLifecycleException
    {
        LifecycleEventContext context = event.getLifecycleEventContext();

        context.log("got event" + event.getEventType() + " event data: "
            + event.getData());

        Properties props;

        if (LifecycleEvent.INIT_EVENT == event.getEventType()) {
            context.log("LifecycleListener: INIT_EVENT");

            props = (Properties) event.getData();

            // handle INIT_EVENT
            return;
        }

        if (LifecycleEvent.STARTUP_EVENT == event.getEventType()) {
            context.log("LifecycleListener: STARTUP_EVENT");

            // handle STARTUP_EVENT
            return;
        }

        if (LifecycleEvent.READY_EVENT == event.getEventType()) {
            context.log("LifecycleListener: READY_EVENT");

            // handle READY_EVENT
            return;
        }

        if (LifecycleEvent.SHUTDOWN_EVENT== event.getEventType()) {
            context.log("LifecycleListener: SHUTDOWN_EVENT");

            // handle SHUTDOWN_EVENT
            return;
        }

        if (LifecycleEvent.TERMINATION_EVENT == event.getEventType()) {
            context.log("LifecycleListener: TERMINATE_EVENT");

            // handle TERMINATION_EVENT
            return;
        }
    }
}

 
LifecycleEventクラス

com.nec.webotx.appserv.server.LifecycleEventクラスは、サーバ・ライフサイクル・イベントを定義します。 イベントに関連するメソッドは下記のとおりです。

LifecycleEventインスタンスは、前の章で説明したLifecycleListener.handleEventメソッドに渡されます。

 
サーバのライフサイクル・イベント・コンテキスト

com.nec.webotx.appserv.server.LifecycleEventContextインタフェースは、サーバに関する実行時情報を提供します。 ライフサイクル・イベント・コンテキストは、LifecycleEventクラスがサーバの初期化でインスタンス化される時に生成されます。 LifecycleEventContextインタフェースは、下記のメソッドを定義しています。

 
ライフサイクル・モジュールの作成と配備
 
ライフサイクル・モジュールの作成

ライフサイクル・モジュールを作成するためには、下記に示すステップで組み立てていきます。

  1. 作業用ディレクトリを作成し、その中にモジュールのコンテンツをコピーします。
     
  2. JARファイルを生成するために、次のコマンドを実行します。
     
    jar -cvf moudle_name.jar *
 
ライフサイクル・モジュールの配備

ライフサイクル・モジュールは、下記のツールを使って配備することができます。

otxadminコマンド

ライフサイクル・モジュールを配備するためには、otxadmin create-lifecycle-moduleコマンドを用います。 その構文は次のとおりです。一部のオプショナル・パラメータには既定値を示しています。

otxadmin create-lifecycle-module --user user --classname classname [--classpath classpath] [--loadorder load_order_number] [--failurefatal=false] [--enabled=true] [--description text_description] [--property (name=value)[:name=value]*] modulename

otxadminコマンドの一般的なオプショナルのパラメータ (--password--passwordfile--host--port--terse--echo--interactive) に関しては、運用管理コマンド リファレンスマニュアルを参照してください。

(例)
otxadmin create-lifecycle-module --user admin --classname RMIServer MyRMIServer

ライフサイクル・モジュールを配備解除するためには、otxadmin delete-lifecycle-moduleコマンドを用います。 その構文は次のとおりです。一部のオプショナル・パラメータには既定値が適用されます。

otxadmin delete-lifecycle-module --user user modulename
 
(例)
otxadmin delete-lifecycle-module --user admin MyRMIServer

配備済みライフサイクル・モジュールに一覧を得るためには、otxadmin list-lifecycle-modulesコマンドを用います。 その構文は次のとおりです。一部のオプショナル・パラメータには既定値が適用されます。

otxadmin list-lifecycle-modules --user user
 
(例)
otxadmin delete-lifecycle-module --user admin
 
ライフサイクル・モジュールの構成情報

ライフサイクル・モジュール配備中に、lifecycle-module要素がdomain.xmlファイルに生成されます。 管理者は、その構成を変更するために、このファイルを編集することができます。 propertyサブ要素は、入力パラメータを指定することを可能にします。 以下に例を示します。

<lifecycle-module name="customStartup"
        enabled="true"
        class-name="com.acme.CustomStartup"
        classpath="/apps/customStartup"
        load-order="200"
        is-failure-fatal="true">
    <description>custom startup module to do my tasks</description>
    <property name="rmiServer" value="acme1:7070" />
    <property name="timeout" value="30" />
</lifecycle-module>

is-failure-fataltrue(既定値はfalse)に設定される場合、ライフサイクル・モジュールの動作に失敗すると、シャットダウン時か終了時ではなく、サーバの初期化時か開始時に、サーバ動作を停止に働かせることに注意してください。

ライフサイクル・モジュールを配備した後、それを活性化するためにはサーバを再起動しなければなりません。 サーバはモジュールをインスタンス化し、サーバの初期化でライフサイクル・イベント・リスナとしてモジュールを登録します。

 
サーバのライフサイクル・モジュールで考慮する点

初期化または開始の中で割り当てられたリソースは、シャットダウンまたは終了の中で解放されるべきです。 ライフサイクル・モジュール・クラスは、メイン・サーバ・スレッドから同期して呼ばれます。したがって、これらのクラスがサーバをブロックしないことを保証することが重要です。 それに適合するならば、ライフサイクル・モジュールはスレッドを生成してもよいです。しかし、これらのスレッドはシャットダウンと終了の段階の中でスレッド処理を中止しなければなりません。

LifeCycleModule Classloaderは、ライフサイクル・モジュール用の親クラスローダです。 各ライフサイクル・モジュールのdomain.xml内におけるclasspath値は、そのクラスローダを構築するために使用されます。 classloaderを構築するために使用される。 ライフサイクル・モジュールによって必要とされる全ての支援クラスは、LifeCycleModule Classloader、あるいはその親やConnector Classloaderで利用可能でなければなりません。

運用者、またはモジュール開発者は、server.policyファイルを適切に設定することを保証しなければなりません。また、System.exec()を実行しようとするライフサイクル・モジュールは、セキュリティ・アクセス妨害を引き起こすかもしれません。

ライフサイクル・モジュールへの構成済みプロパティは、INIT_EVENTイベント内でプロパティとして渡されます。 JNDIネーミング・コンテキストは、INIT_EVENTイベント内においては利用できません。 ライフサイクル・モジュールがネーミング・コンテキストを必要とする場合、それはSTARTUP_EVENTREADY_EVENTSHUTDOWN_EVENTイベントの中で得ることができます。

 
APIリファレンス
ライフサイクル・リスナ API 仕様