Tuxedo CORBA サーバ アプリケーションの開発方法

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

Oracle Tuxedo CORBA サーバ アプリケーションの作成手順

この章では、CORBA サーバ アプリケーションを作成するための手順について説明します。この章で説明する手順は、決定的なものではありません。サーバ アプリケーションによっては、ほかの手順を行う必要があります。また、これらの手順のいくつかについては順番を変更することができます。ただし、これらの手順は、すべての CORBA サーバ アプリケーションの開発プロセスに共通のものです。

ここでは、以下の内容について説明します。

この章では、最初に手順の要約と、このマニュアルで使用する開発ツールおよび開発コマンドのリストを示します。デプロイメント環境によっては、ほかのソフトウェア開発ツールも使用します。このため、この章で説明するツールとコマンドも決定的なものではありません。

この章では、Oracle Tuxedo ソフトウェアに付属の Basic University サンプル アプリケーションの中の例を使用します。Basic University サンプル アプリケーションの詳細については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。このマニュアルで使用するツールとコマンドの詳細については、『Tuxedo CORBA プログラミング リファレンス』を参照してください。

マルチスレッド CORBA サーバ アプリケーションの作成については、「マルチスレッド CORBA サーバ アプリケーションの作成」を参照してください。

 


CORBA サーバ アプリケーション開発プロセスの概要

サーバ アプリケーションを作成するための基本的な手順は次のとおりです。

ステップ 1: サーバ アプリケーション用の OMG IDL ファイルのコンパイル
ステップ 2: 各インタフェースのオペレーションを実装するメソッドの記述
ステップ 3: サーバ オブジェクトの作成
ステップ 4: メモリ内でのオブジェクトの振る舞いの定義
ステップ 5: サーバ アプリケーションのコンパイルとリンク
ステップ 6: サーバ アプリケーションのデプロイ

Oracle Tuxedo ソフトウェアには、次の開発ツールと開発コマンドが用意されています。

ツール
説明
IDL コンパイラ
アプリケーションの OMG IDL ファイルをコンパイルする。
genicf
実装コンフィグレーション ファイル (ICF ファイル) を生成する。このファイルを修正して、非デフォルト オブジェクトのアクティブ化ポリシーとトランザクション ポリシーを指定できる。
buildobjserver
CORBA サーバ アプリケーションの実行可能イメージを作成できる。
tmloadcf
TUXCONFIG ファイルを作成する。これは、サーバ アプリケーションのコンフィグレーションを指定する CORBA ドメイン用のバイナリ ファイル。
tmadmin
特に、トランザクション アクティビティのログを作成します。これは、いくつかのサンプル アプリケーションで使用される。

 


ステップ 1: サーバ アプリケーション用の OMG IDL ファイルのコンパイル

Oracle Tuxedo ドメインで実行されるアプリケーションのクライアントおよびサーバ部分の基本構造は、そのアプリケーションの OMG IDL ファイルに記述される文によって決定されます。アプリケーションの OMG IDL ファイルをコンパイルする場合、IDL コンパイラは、idl コマンドで指定するオプションに応じて、次の図に示すファイルの一部または全部を生成します。影付きのコンポーネントは、サーバ アプリケーションを作成するために修正するファイルです。

表 2-1 に、IDL コンパイラによって生成されるファイルを示します。

表 2-1 IDL コンパイラによって生成されるファイル
ファイル
デフォルト名
説明
クライアント スタブ ファイル
application_c.cpp
要求を送信するために生成されたコードを格納する。
クライアント スタブ ヘッダ ファイル
application_c.h
OMG IDL ファイルで指定された各インタフェースと型のクラス定義を格納する。
スケルトン ファイル
application_s.cpp
OMG IDL ファイルで指定した各インタフェース用のスケルトンが含まれる。スケルトンは、実行時にクライアント要求をサーバ アプリケーション内の適切なオペレーションにマップする。
スケルトン ヘッダ ファイル
application_s.h
スケルトンのクラス定義を格納する。
実装ファイル
application_i.cpp
OMG IDL ファイルで指定されたインタフェースのオペレーションを実装するメソッドのシグニチャを格納する。
実装ヘッダ ファイル
application_i.h
OMG IDL ファイルで指定された各インタフェースの初期クラス定義を格納する。

IDL コンパイラの使い方

表 2-1 に示したファイルを生成するには、次のコマンドを入力します。

idl [options] idl-filename [icf-filename]

idl コマンド構文のパラメータは次のとおりです。

注意 : WebLogic Enterprise 5.1 では、プラグマの C++ IDL コンパイラ実装が変更され、CORBA 2.3 機能がサポートされるようになりました。これにより、IDL ファイルが影響を受ける場合があります。CORBA 2.3 機能は、プラグマ接頭辞定義が影響を及す可能性があるスコープを変更します。プラグマはインクルードされる IDL ファイルに含まれる定義には影響を及さず、またインクルードされる IDL ファイル内で行われるプラグマ接頭辞定義はそれらのファイルの外部のオブジェクトに影響を及しません。

C++ IDL コンパイラは、プラグマ接頭辞の処理を訂正するよう変更されました。この変更はオブジェクトのリポジトリ ID に影響を与えるため、_narrow などのオペレーションでエラーが発生する場合があります。

このようなエラーを防ぐには、次のことを行います。

IDL コンパイラと idl コマンドの詳細については、『Tuxedo CORBA プログラミング リファレンス』を参照してください。

スケルトンと実装ファイルの生成

次のコマンドラインは、OMG IDL ファイル univb.idl のクライアント スタブ ファイル、スケルトン ファイル、初期実装ファイル、スケルトン ヘッダ ファイル、および実装ヘッダ ファイルを生成します。

idl -i univb.idl

idl コマンドの詳細については、『Tuxedo CORBA プログラミング リファレンス』を参照してください。Oracle Tuxedo University サンプル アプリケーション用のこれらのファイルを生成する方法については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。

注意 : 非デフォルトのオブジェクトのアクティブ化ポリシーまたはトランザクション ポリシーを指定する場合、または生成するスケルトン ファイルと実装ファイルのインタフェースの数を制限する場合、実装コンフィグレーション ファイル (ICF) を生成し、この ICF ファイルを IDL コンパイラに受け渡す必要があります。詳細については、「ICF でオブジェクトのアクティブ化ポリシーとトランザクション ポリシーを指定する方法」を参照してください。

tie クラスの生成

IDL コンパイラには、インタフェースの tie クラス テンプレートを生成するために使用できる -T コマンドライン オプションも用意されています。CORBA アプリケーションの tie クラスの実装については、「デレゲーション ベースのインタフェース実装」を参照してください。

 


ステップ 2: 各インタフェースのオペレーションを実装するメソッドの記述

サーバ アプリケーション プログラマは、アプリケーションの OMG IDL ファイルで定義した各インタフェースのオペレーションを実装するメソッドを記述します。

実装ファイルには以下のものが含まれます。

IDL コンパイラによって生成される実装ファイル

サーバ アプリケーションの実装ファイルはすべて手動で作成できますが、実装ファイルを記述する出発点として、IDL コンパイラが生成する実装ファイルを使用することもできます。IDL コンパイラによって生成される実装ファイルには、アプリケーションのインタフェース用に定義された各オペレーションを実装するメソッドのシグニチャが含まれます。

通常、この実装ファイルは、IDL コンパイラを呼び出すコマンドで -i オプションを指定することによって 1 度だけ作成します。アプリケーションのインタフェースを繰り返し修正し、これらのインタフェースのオペレーション (オペレーション シグニチャを含む) を変更した場合は、必要なすべての変更を実装ファイルに追加してこれらの変更を反映させる必要があります。

ファクトリの実装

「クライアント アプリケーションがサーバ アプリケーションの CORBA オブジェクトをアクセスおよび操作する方法」で説明したように、クライアント アプリケーションがサーバ アプリケーションによって管理されるオブジェクトを簡単に検索できるようにするためには、ファクトリを作成する必要があります。ファクトリは実装するほかの CORBA オブジェクトに似ていますが、FactoryFinder オブジェクトに登録する必要があります。ファクトリの登録については、「ファクトリを作成および登録するコードの記述」を参照してください。

ファクトリの主要な機能は、オブジェクト参照を作成することです。ファクトリは、TP::create_object_reference() オペレーションを呼び出すことによってこれを実行します。TP::create_object_reference() オペレーションでは、次の入力パラメータが必要となります。

たとえば、Basic University サンプル アプリケーションでは、RegistrarFactory インタフェースは、次のように 1 つのオペレーションだけを指定します。

University::Registrar_ptr RegistrarFactory_i::find_registrar()

RegistrarFactory オブジェクトの find_registrar() オペレーションには、Registrar オブジェクトの参照を作成するための TP::create_object_reference() オペレーションへの次の呼び出しが含まれています。

CORBA::Object_var v_reg_oref =
TP::create_object_reference(
University::_tc_Registrar->id(),
object_id,
CORBA::NVlist::_nil()
);

このサンプル コードでは、次のことに留意してください。

 


ステップ 3: サーバ オブジェクトの作成

Server オブジェクトの実装は、ほかの言語オブジェクトの実装とは異なります。Server オブジェクトのヘッダ クラスは既に作成されており、Server オブジェクト クラスは既にインスタンス化されています。Server オブジェクトを作成するには、パッケージ済みの Server オブジェクト クラスの特定のメソッド セットを実装します。この節では、実装するこれらのメソッドについて説明します。

Server オブジェクトを作成するには、一般のテキスト エディタで新しいファイルを作成し、次のオペレーションを実装します。

オペレーション
説明
Server::initialize();
サーバ アプリケーションの起動後、TP フレームワークはサーバ アプリケーション初期化プロセスの最後のステップとしてこのオペレーションを呼び出す。このオペレーションでは、特定のサーバ アプリケーションで必要な複数の初期化タスクを実行する。このオペレーションで提供するものについては、「サーバ アプリケーションの初期化」を参照。
Server::create_servant();
既存のサーバントで処理できないクライアント要求が送信されると、TP フレームワークはこのオペレーションを呼び出して、アクティブ化される CORBA オブジェクトの OMG IDL インタフェースのインタフェース リポジトリ ID を受け渡す。このオペレーションで提供するものについては、「サーバントの作成」を参照。
Server::release();
TP フレームワークは、サーバ アプリケーションを停止するときにこのオペレーションを呼び出す。このオペレーションには、サーバ アプリケーションで管理されるオブジェクト ファクトリの登録を削除し、ほかの停止タスクを実行するためのコードが含まれる。このオペレーションで提供するものについては、「サーバ アプリケーションのリリース」を参照。

どのサーバ アプリケーションにも、Server オブジェクトのインスタンスは 1 つしか存在しません。サーバ アプリケーションが複数の CORBA オブジェクト実装を管理する場合、記述する Server::initialize()Server::create_servant()、および Server::release() オペレーションにはこれらの実装すべてに適用するコードを組み込む必要があります。

これらのタスクの大部分のコードには、TP フレームワークとの対話が含まれます。以降の節では、これらの Server オブジェクト オペレーションのそれぞれに対して必要なコードについて説明し、Basic University サンプル アプリケーションのサンプル コードを示します。

サーバ アプリケーションの初期化

Server オブジェクトに実装する最初のオペレーションは、サーバ アプリケーションを初期化するオペレーションです。このオペレーションは、Oracle Tuxedo システムがサーバ アプリケーションを起動するときに呼び出されます。TP フレームワークは、サーバ アプリケーションの起動シーケンス中に Server オブジェクトの次のオペレーションを呼び出します。

CORBA::Boolean Server::initialize(int argc, char** argv) 

Oracle Tuxedo ドメインの UBBCONFIG ファイルの SERVERS セクションに指定する特定のサーバ アプリケーション用の CLOPT パラメータは、Server::initialize() オペレーションに argc および argv として受け渡されます。サーバ アプリケーションへの引数の受け渡しについては、『Oracle Tuxedo アプリケーション実行時の管理』を参照してください。サーバ アプリケーションに引数を受け渡す例については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。

Server::initialize() オペレーションの中には、該当する場合、次のことを行うコードを組み込みます。

ファクトリを作成および登録するコードの記述

クライアント アプリケーションがオブジェクトを簡単に検索できるようにするためのファクトリをサーバ アプリケーションが管理する場合、そのファクトリを FactoryFinder オブジェクトに登録するコードを記述する必要があります。このコードは、通常サーバ アプリケーション初期化プロセスの最後のステップとして呼び出されます。

サーバ アプリケーションによって管理されるファクトリを登録するコードを記述するには、次のことを行います。

  1. ファクトリのオブジェクト参照を作成します。
  2. このステップでは、「ファクトリの実装」で説明したとおりオブジェクト参照を作成します。 このステップでは、TP::create_object_reference() オペレーションの呼び出しを組み込み、OMG IDL インタフェースのインタフェース リポジトリ ID を指定します。次の例では、RegistrarFactory ファクトリのオブジェクト参照 (s_v_fact_ref 変数で表される) が作成されます。

    University::RegistrarFactory s_v_fact_ref =
    TP::create_object_reference(
    University::_tc_RegistrarFactory->id(),
    object_id,
    CORBA::NVList::_nil()
    );
  3. ファクトリを Oracle Tuxedo ドメインに登録します。
  4. このステップでは、サーバ アプリケーションによって管理される各ファクトリに対して次のオペレーションを呼び出します。

    TP::register_factory (CORBA::Object_ptr factory_or,
    const char* factory_id);

    TP::register_factory() オペレーションは、サーバ アプリケーションのファクトリを FactoryFinder オブジェクトに登録します。このオペレーションでは、次の入力パラメータが必要です。

    • 前述のステップ 1 で作成した、ファクトリのオブジェクト参照。
    • ファクトリ オブジェクトのインタフェース タイプ コードに基づく文字列識別子。これは、ファクトリの OMG IDL インタフェースのインタフェース リポジトリ ID を識別するために使用される。
    • 次の例では、RegistrarFactory ファクトリが Oracle Tuxedo ドメインに登録されます。

      TP::register_factory(s_v_fact_ref.in(),
      University::_tc_RegistrarFactory->id());

      University::_tc_RegistrarFactory->id() パラメータに注目してください。これは、TP::create_object_reference() オペレーションで指定したパラメータと同じです。このパラメータは、オブジェクトの OMG IDL インタフェースのインタフェース リポジトリ ID をそのタイプ コードから抽出します。

サーバントの作成

サーバ アプリケーション初期化プロセスが完了したら、サーバ アプリケーションはクライアント要求を処理できる状態になります。CORBA オブジェクトのオペレーションに対する要求が到着し、それを処理するサーバントがメモリ内に存在しない場合、TP フレームワークは Server オブジェクトの次のオペレーションを呼び出します。

Tobj_Servant Server::create_servant(const char* interfaceName)

Server::create_servant() オペレーションには、クライアント要求によって必要とされるオブジェクトのサーバントをインスタンス化するコードが含まれます。たとえば、C++ では、このコードにはオブジェクトのインタフェース クラスの new 文が組み込まれます。

Server::create_servant() オペレーションでは、サーバントは OID に関連付けられません。サーバントと OID の関連付けは、TP フレームワークがそのサーバントの Tobj_ServantBase::activate_object() オペレーション (オブジェクトのインスタンス化を完了させるオペレーション) を呼び出したときに行われます。オブジェクトのコンストラクタで OID をオブジェクトに関連付けることはできません。同様に、サーバントと OID の関連付けの解除は、TP フレームワークがそのサーバントの deactivate_object() オペレーションを呼び出したときに行われます。

Oracle Tuxedo システムでのこうしたサーバントの振る舞いにより、TP フレームワークは、オブジェクトの非アクティブ化後、別のオブジェクトのインスタンス化のためにサーバントを使用できます。したがって、オブジェクトの Tobj_ServantBase::deactivate_object() オペレーションの呼び出しによってそのオブジェクトのデストラクタも呼び出されるとは考えないでください。サーバ アプリケーションでサーバント プール機能を使用する場合、オブジェクトの Tobj_ServantBase::deactivate_object() オペレーションに TP::application_responsibility() オペレーションを実装して、サーバントへのポインタを後で使用できるようにサーバント プールに受け渡すことができます。サーバント プールについては、「サーバント プール」を参照してください。

Server::create_servant() オペレーションでは、入力引数が 1 つ必要です。この引数は、サーバントを作成するためのオブジェクトの OMG IDL インタフェースのインタフェース ポジトリ ID を含む文字列を指定します。

このオペレーション用に記述するコードには、サーバ アプリケーションによって管理されるオブジェクトの OMG IDL インタフェースのインタフェース リポジトリ ID を指定します。実行時に、Server::create_servant() オペレーションは、要求によって指定されたオブジェクトに対して必要なサーバントを返します。

次のコードは、Basic University サンプル アプリケーションの University サーバ アプリケーションの Server::create_servant() オペレーションを実装します。

Tobj_Servant Server::create_servant(const char* intf_repos_id)
{
if (!strcmp(intf_repos_id, University::_tc_RegistrarFactory->id())) {
return new RegistrarFactory_i();
}
if (!strcmp(intf_repos_id, University::_tc_Registrar->id())) {
return new Registrar_i();
}
if (!strcmp(intf_repos_id, University::_tc_CourseSynopsisEnumerator->id())) {
return new CourseSynopsisEnumerator_i();
}
return 0; // 未知のインタフェース
}

サーバ アプリケーションのリリース

Oracle Tuxedo システム管理者が tmshutdown コマンドを入力すると、TP フレームワークは、Oracle Tuxedo ドメインで実行される各サーバ アプリケーションの Server オブジェクトの次のオペレーションを呼び出します。

void Server::release()

Server::release() オペレーションでは、次のような、サーバ アプリケーションに応じたアプリケーション固有のクリーンアップ タスクを実行できます。

サーバ アプリケーションが停止要求を受信すると、そのサーバ アプリケーションはほかのリモート オブジェクトから要求を受信することができなくなります。これは、管理者がサーバ アプリケーションを停止する順番に影響を与えます。たとえば、あるサーバ プロセスへの Server::release() オペレーションの呼び出しが別のサーバ プロセスに含まれている場合、最初のサーバ プロセスは停止してはなりません。

サーバの停止中に、次の呼び出しを組み込んでサーバ アプリケーションの各ファクトリの登録を削除できます。

TP::unregister_factory (CORBA::Object_ptr factory_or,
const char* factory_id)

TP::unregister_factory() オペレーションの呼び出しは、Server::release() 実装の最初のアクションの 1 つである必要があります。TP::unregister_factory() オペレーションは、サーバ アプリケーションのファクトリへの登録を削除します。このオペレーションでは、次の入力引数が必要です。

次の例では、Basic サンプル アプリケーションで使用されている RegistrarFactory ファクトリへの登録が削除されます。

TP::unregister_factory(s_v_fact_ref.in(), UnivB::_tc_RegistrarFactory->id());

このサンプル コードでは、グローバル変数 s_v_fact_ref の使い方に注目してください。 この変数は、RegistrarFactory オブジェクトを登録した Server::initialize() オペレーションで設定されたもので、ここで再び使用されます。

また、UnivB::_tc_RegistrarFactory->id() パラメータにも注目してください。これも、ファクトリの登録に使用されたインタフェース名と同じです。

 


ステップ 4: メモリ内でのオブジェクトの振る舞いの定義

「オブジェクト状態の管理」で説明したように、オブジェクトのアクティブ化ポリシーとトランザクション ポリシーを割り当て、オプションでアプリケーション制御の非アクティブ化機能を使用することによって、オブジェクトを非アクティブ化するイベントを指定します。

オブジェクトのアクティブ化ポリシーとトランザクション ポリシーは ICF ファイルに指定し、アプリケーション制御の非アクティブ化は TP::deactivateEnable() オペレーションを介して使用します。この節では、Basic University サンプル アプリケーションを例として使用して、これらのメカニズムを実装する方法について説明します。

ここでは、次のことについて説明します。

ICF でオブジェクトのアクティブ化ポリシーとトランザクション ポリシーを指定する方法

Oracle Tuxedo ソフトウェアは、「オブジェクトのアクティブ化ポリシー」で説明した次のアクティブ化ポリシーをサポートしています。

アクティブ化ポリシー
説明
method
オブジェクトのオペレーションの呼び出しの間だけオブジェクトをアクティブ化する。
transaction
オペレーションが呼び出されたときにオブジェクトをアクティブ化する。オブジェクトがトランザクション範囲内でアクティブ化された場合、そのオブジェクトはトランザクションがコミットまたはロールバックされるまでは、アクティブ化されたままである。
process
オペレーションが呼び出されたときにオブジェクトをアクティブ化し、次のいずれかが起こったときのみオブジェクトを非アクティブ化する。
  • サーバ アプリケーションの存在するプロセスが停止された。
  • オブジェクトが自身の TP::deactivateEnable() オペレーションを呼び出した。

Oracle Tuxedo ソフトウェアは、第 6 章「トランザクションの CORBA サーバ アプリケーションへの統合」で説明する次のトランザクション ポリシーもサポートしています。

トランザクション ポリシー
説明
always
このオブジェクトのオペレーションが呼び出されると、このポリシーによって TP フレームワークはそのオブジェクトのトランザクションを開始する (アクティブ化されているトランザクションが存在しない場合)。TP フレームワークがトランザクションを開始した場合、TP フレームワークは、オペレーションが正常に完了した場合はトランザクションをコミットし、例外が発生した場合はトランザクションをロールバックする。
optional
このオブジェクトのオペレーションが呼び出されると、このポリシーによって TP フレームワークはこのオブジェクトをトランザクションに組み込む (トランザクションがアクティブ化されている場合)。アクティブ化されているトランザクションが存在しない場合、このオブジェクトに対して定義されているアクティブ化ポリシーに従ってこのオブジェクトの呼び出しが続行される。
このトランザクション ポリシーはデフォルト。
never
TP フレームワークは、このオブジェクトがトランザクション中に呼び出された場合にエラー状態を生成する。
ignore
このオブジェクトが呼び出されたときにトランザクションがアクティブ化されている場合、そのトランザクションはオペレーション呼び出しが完了するまで中断する。このトランザクション ポリシーにより、このポリシーが割り当てられているオブジェクトにトランザクションが伝達されるのを防ぐことができる。

これらのポリシーをアプリケーションのオブジェクトに割り当てるには、次の手順に従います。

  1. 次の例のように、genicf コマンドを入力し、アプリケーションの OMG IDL ファイルを入力として指定して、ICF ファイルを生成します。
  2. # genicf university.idl

    このコマンドによって、university.icf というファイルが生成されます。

  3. ICF ファイルを編集して、アプリケーションのインタフェースごとにアクティブ化ポリシーを指定します。次の例に、Basic University サンプル アプリケーション用に生成された ICF ファイルを示します。デフォルトのオブジェクトのアクティブ化ポリシーは method で、デフォルトのトランザクションアクティブ化ポリシーは optional であることに注意してください。
  4. module POA_UniversityB
    {
    implementation CourseSynopsisEnumerator_i
    {
    activation_policy ( method );
    transaction_policy ( optional );
    implements ( UniversityB::CourseSynopsisEnumerator );
    };
    };
    module POA_UniversityB
    {
    implementation Registrar_i
    {
    activation_policy ( method );
    transaction_policy ( optional );
    implements ( UniversityB::Registrar );
    };
    };
    module POA_UniversityB
    {
    implementation RegistrarFactory_i
    {
    activation_policy ( method );
    transaction_policy ( optional );
    implements ( UniversityB::RegistrarFactory );
    };
    };
  5. 生成するスケルトン ファイルと実装ファイルのインタフェースの数を制限する場合、それらのインタフェースを実装する実装ブロックを ICF ファイルから削除できます。前掲の ICF コードの例では、RegistrarFactory インタフェースのスケルトン ファイルと実装ファイルが生成されないようにするには、次の行を削除します。
  6. implementation RegistrarFactory_i
    {
    activation_policy ( method );
    transaction_policy ( optional );
    implements ( UniversityB::RegistrarFactory );
    };
  7. ICF ファイルを IDL コンパイラに受け渡して、指定されたポリシーに対応するスケルトン ファイルと実装ファイルを生成します。詳細については、「スケルトンと実装ファイルの生成」を参照してください。

 


ステップ 5: サーバ アプリケーションのコンパイルとリンク

Server オブジェクトとオブジェクト実装のコードの記述が済んだら、サーバ アプリケーションをコンパイルおよびリンクします。

CORBA サーバ アプリケーションをコンパイルおよびリンクするには、buildobjserver コマンドを使用します。buildobjserver コマンドの形式は次のとおりです。

buildobjserver [-o servername] [options]

buildobjserver コマンドの構文要素を次に説明します。

University サンプル アプリケーションのコンパイルとリンクの詳細については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。buildobjserver コマンドの詳細については、『Tuxedo コマンド リファレンス』を参照してください。

マルチスレッド CORBA サーバ アプリケーションの設計とビルドには、特別な考慮事項が存在します。詳細については、「buildobjserver コマンドの使い方」を参照してください。

注意 : IBM AIX 4.3.3 システム上で Oracle Tuxedo ソフトウェアを実行する場合、-brtl コンパイラ オプションを使用して CORBA アプリケーションを再コンパイルする必要があります。

 


ステップ 6: サーバ アプリケーションのデプロイ

システム管理者は、この節で説明する手順を使用して CORBA サーバ アプリケーションをデプロイします。University サンプル アプリケーションのビルドとデプロイの詳細については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。

サーバ アプリケーションをデプロイするには、以下の手順に従います。

  1. サーバ アプリケーションの実行可能ファイルを、目的の Oracle Tuxedo ドメインの一部であるマシンの適切なディレクトリに格納します。
  2. 一般のテキスト エディタを使用して、アプリケーションのコンフィグレーション ファイル (UBBCONFIG ファイル) を作成します。
  3. CORBA サーバ アプリケーションを起動するマシンで、次の環境変数を設定します。
    • TUXCONFIG。この変数は、UBBCONFIG ファイルの TUXCONFIG エントリと正確に一致する必要がある。この変数は、アプリケーションの UBBCONFIG ファイルの格納場所またはパスを表す。
    • APPDIR。この変数は、アプリの実行可能ファイルが存在するディレクトリを表す。
  4. Oracle Tuxedo ドメインで稼働しているすべてのマシン、または Oracle Tuxedo ドメインに接続されているすべてのマシンで、TUXDIR 環境変数を設定します。この環境変数は、Oracle Tuxedo ソフトウェアがインストールされている場所を指し示します。
  5. 次のコマンドを入力して、TUXCONFIG ファイルを作成します。
  6. tmloadcf -y application-ubbconfig-file

    コマンドライン引数の application-ubbconfig-file は、アプリケーションの UBBCONFIG ファイルの名前を表します。古い TUXCONFIG ファイルを削除してからこのコマンドを実行しなければならない場合があることに注意してください。

  7. 次のコマンドを入力して、CORBA サーバ アプリケーションを起動します。
  8. tmboot -y

    UBBCONFIG ファイルを再ロードせずにサーバ アプリケーションを再起動できます。

University サンプル アプリケーションの詳細については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。CORBA アプリケーション用の UBBCONFIG ファイルの作成の詳細については、『Oracle Tuxedo アプリケーションの設定』を参照してください。

 


開発とデバッグのヒント

ここでは、以下の内容について説明します。

CORBA 例外とユーザ ログの使い方

ここでは、以下の内容について説明します。

例外のクライアント アプリケーション ビュー

クライアント アプリケーションが CORBA オブジェクトのオペレーションを呼び出した場合、その呼び出しの結果として例外が返される場合があります。クライアント アプリケーションに返される有効な例外は次のとおりです。

Oracle Tuxedo システムは、これらの CORBA 定義の制限に違反することがないよう動作します。詳細については、「例外のサーバ アプリケーション ビュー」で説明します。

クライアント アプリケーションが認識する例外セットは制限されているので、クライアント アプリケーションは原因が不明な例外を捕捉する場合があります。Oracle Tuxedo システムは、こうした例外を可能な限りユーザ ログの説明メッセージで補足します。このメッセージは、エラー状態の検出とデバッグに役立ちます。これらのケースについては、次の節で説明します。

例外のサーバ アプリケーション ビュー

ここでは、以下の内容について説明します。

Oracle Tuxedo システムによって生成され、アプリケーション コードによって捕捉される例外

Oracle Tuxedo システムは、TP オブジェクトのオペレーションが呼び出された場合、次の例外をアプリケーションに返す場合があります。

CORBA オブジェクトのオペレーションの呼び出し中にアプリケーション コードによって生成された例外を Oracle Tuxedo システムが処理する方法

サーバ アプリケーションは、クライアント呼び出し中に次の場所で例外を生成する場合があります。

サーバ アプリケーションは次のタイプの例外を生成する可能性があります。

サーバ アプリケーション コードによって生成され、サーバ アプリケーションによって捕捉されないすべての例外は、Oracle Tuxedo システムによって捕捉されます。これらの例外が捕捉されると、次のいずれかの処理が発生します。

以下の節では、CORBA オブジェクトに対するクライアント呼び出し中にサーバ アプリケーションによって生成される例外を Oracle Tuxedo システムがどのように処理するかについて説明します。

Server::create_servant() オペレーションで生成された例外

例外が Server::create_servant() オペレーションで生成された場合、次の処理が行われます。

Tobj_ServantBase::activate_object() オペレーションで生成された例外

例外が Tobj_ServantBase::activate_object() オペレーションで生成された場合、次の処理が行われます。

オペレーション実装で生成された例外

Oracle Tuxedo システムでは、オペレーション実装は、CORBA システム例外、またはクライアント アプリケーションによって認識され、OMG IDL に定義されるユーザ定義例外のいずれかを送出する必要があります。これらのタイプの例外がオペレーション実装によって送出された場合、Oracle Tuxedo システムは次のいずれかの状態が存在しない限り、それらをクライアント アプリケーションに返します。

CORBA 仕様で定義されているとおり、クライアントに送り返される応答には、オペレーション実装からの結果値か、オペレーション実装で送出された例外のいずれかが含まれ、両方が含まれることはありません。最初のケース、つまり、応答ステータス値が NO_EXCEPTION の場合、応答にはオペレーションの戻り値と任意の inout または out 引数値が含まれます。それ以外のケース、つまり、応答ステータス値が USER_EXCEPTION または SYSTEM_EXCEPTION の場合、応答には例外のエンコーディングが含まれます。

Tobj_ServantBase::deactivate_object() オペレーションで生成された例外

例外が Tobj_ServantBase::deactivate_object() オペレーションで生成された場合、次の処理が発生します。

オブジェクト インスタンスの受け渡し時に生成された CORBA マーシャリング例外

ORB は、オブジェクト インスタンスをオブジェクト参照としてマーシャリングできません。たとえば、次のコードでファクトリ参照を受け渡すと、Oracle Tuxedo システムで CORBA マーシャリング例外が発生します。

connection::setFactory(this);

オブジェクト インスタンスを受け渡すには、次の例のように、プロキシ オブジェクト参照を作成して、そのプロキシを代わりに受け渡します。

CORBA::Object myRef = TP::get_object_reference();
ResultSetFactory factoryRef = ResultSetFactoryHelper::_narrow(myRef);
connection::setFactoryRef(factoryRef);

コールバック メソッドのエラー状態の検出

Oracle Tuxedo システムには、メッセージ文字列を指定できる定義済みの例外セットが用意されています。TP フレームワークは、アプリケーション コードが次のコールバック メソッドでエラーを取得した場合、これらのメッセージ文字列をユーザ ログに書き込みます。

これらの例外は、例外の発生原因に関する明確な情報を送信するための便利なデバッグ支援機能として使用できます。TP フレームワークは、これらのメッセージをユーザ ログにのみ書き込みます。これらのメッセージは、クライアント アプリケーションには返されません。

これらのメッセージは、次の例外で指定します。これらの例外では、オプションで reason 文字列を指定できます。

例外
この例外を生成するコールバック メソッド
ActivateObjectFailed
Tobj_ServantBase::activate_object()
DeactivateObjectFailed
Tobj_ServantBase::deactivate_object()
CreateServantFailed
Server::create_servant()
InitializeFailed
Server::initialize()
ReleaseFailed
Server::release()

メッセージ文字列をユーザ ログに送るには、次の例のように、その文字列を例外に指定します。

throw CreateServantFailed("Unknown interface");

これらの例外を送出する場合、reason 文字列パラメータが指定されている必要があります。これらの例外の 1 つで reason 文字列を指定しない場合は、次の例のように、二重引用符を入力する必要があります。

throw ActivateObjectFailed("");

OMG IDL インタフェースのバージョンと修正に関する一般的な注意事項

Server オブジェクトの Server::create_servant() オペレーションの実装は、そのインタフェース ID に基づいてオブジェクトをインスタンス化します。このインタフェース ID は、ファクトリが TP::create_object_reference() オペレーションを呼び出したときにファクトリに指定されるインタフェース ID と同じである必要があります。インタフェース ID が一致しない場合、通常 Server::create_servant() オペレーションで例外が発生するか、または NULL サーバントが返されます。この場合、Oracle Tuxedo システムは、CORBA::OBJECT_NOT_EXIST 例外をクライアント アプリケーションに返します。Oracle Tuxedo システムは、TP::create_object_reference() オペレーションでインタフェース ID の検証を行いません。

このような状態は、開発の過程で、インタフェースの異なるバージョンが開発されるか、IDL ファイルに対して多くの変更が行われる場合に発生する可能性があります。OMG IDL にインタフェース ID の文字列定数を指定し、これらの定数をファクトリと Server::create_servant() オペレーションで使用する場合でも、オブジェクト実装とファクトリが異なる実行可能ファイルに存在する場合は、不一致が発生する可能性があります。多くの場合、この問題の診断は困難です。

こうした問題を避けるには、開発中に次の予防的プログラミング手法を検討する必要があります。このコードは、アプリケーションのデバッグ バージョンにのみ記述する必要があります。実働バージョンでは受け入れられない性能の低下が発生する可能性があるからです。

Tobj_ServantBase::deactivate_object() での状態処理に関する注意

Tobj_ServantBase::deactivate_object() オペレーションは、オブジェクトのアクティブ化境界に達したときに呼び出されます。このオペレーションの実装では、オプションで永続状態をディスクに書き込むことができます。このオペレーションで生成された例外はクライアント アプリケーションに返されないことを理解しておくことが重要です。クライアント アプリケーションは、オブジェクトがトランザクションに参加していない限り、このオペレーションで生成されたエラー状態を認識しません。このため、このオペレーションで状態が正常に書き込まれたかどうかを知ることが重要である場合は、トランザクションを使用することをお勧めします。

Tobj_ServantBase::deactivate_object() オペレーションで状態を書き込むことを選択し、クライアント アプリケーションがその書き込みオペレーションの結果を知る必要がある場合、次のことを行うことをお勧めします。

トランザクションを使用しない場合は、Tobj_ServantBase::deactivate_object() オペレーションを使用せずに、オブジェクトの個々のオペレーションのスコープの中でオブジェクト状態を書き込むことをお勧めします。エラーが発生した場合、オペレーションはクライアント アプリケーションに返される例外を生成できます。

 


サーバント プール

「サーバント プールと状態をステートレス オブジェクト」で説明したように、サーバント プールを使用すると、メソッド バウンド オブジェクトとトランザクション バウンド オブジェクトのオブジェクト インスタンス化のコストを削減できます。

サーバント プールの機能

通常、オブジェクトの非アクティブ化中 (TP フレームワークが Tobj_ServantBase::deactivate_object() オペレーションを呼び出したとき) に、TP フレームワークはオブジェクトのサーバントを削除します。ただし、サーバント プールを使用する場合、TP フレームワークはオブジェクトの非アクティブ化時にサーバントを削除しません。代わりに、サーバ アプリケーションはプール内のサーバントへのポインタを保持します。それ以降、そのプール内のサーバントによって処理可能な要求がクライアントから送られてくると、サーバ アプリケーションはそのサーバントを再利用して新しいオブジェクト ID を割り当てます。サーバントがプールから再利用される場合、TP フレームワークは新しいサーバントを作成しません。

サーバント プールの実装方法

サーバント プールは、以下の手順で実装します。

  1. Server オブジェクトの Server::initialize() オペレーションに、サーバント プールをセットアップするコードを記述します。サーバント プールは 1 つまたは複数のサーバントへのポインタのセットで構成され、サーバント プールのコードでは特定のクラスのサーバントをプールでどのくらい保持するのかを指定します。
  2. プールされたサーバントの Tobj_ServantBase::deactive_object() オペレーションに、TP::application_responsibility() オペレーションを実装します。TP::application_responsibility() オペレーションの実装には、TP フレームワークが Tobj_ServantBase::deactivate_object() オペレーションを呼び出したときにサーバント プールにサーバントへのポインタを格納するコードを記述します。
  3. Server オブジェクトの Server::create_servant() オペレーションの実装に、クライアント要求が到着したときに次のことを行うコードを記述します。
    1. プールをチェックして、その要求を満たすことができるサーバントが存在するかどうかを調べる。
    2. サーバントが存在しない場合は、サーバントを作成してその Tobj_ServantBase::activate_object() オペレーションを呼び出す。
    3. サーバントが存在する場合は、その Tobj_ServantBase::activate_object() オペレーションを呼び出して、クライアント要求に含まれているオブジェクト ID を割り当てる。
注意 : このリリースでは、TP::application_responsibility() オペレーションのサポートが変更されています。詳細については、『Tuxedo CORBA プログラミング リファレンス』を参照してください。

 


デレゲーション ベースのインタフェース実装

Oracle Tuxedo CORBA アプリケーションでオブジェクトを実装する主要な方法は、継承とデレゲーションの 2 つです。オブジェクトが POA スケルトン クラスから継承され、それによって CORBA オブジェクトとなった場合、そのオブジェクトは継承によって実装されたと言われます。

ただし、POA スケルトン クラスからの継承が困難または不可能な C++ オブジェクトを CORBA アプリケーションで使用したい場合もあります。たとえば、POA スケルトン クラスから継承するために大幅な書き換えが必要な C++ オブジェクトなどです。こうした非 CORBA オブジェクトを CORBA アプリケーションで使用するには、そのオブジェクト用の tie クラスを作成します。tie クラスは、POA スケルトン クラスから継承されます。また、tie クラスには 1 つまたは複数のオペレーションが含まれ、それらは実装のためにレガシー クラスに委譲されます。これにより、レガシー クラスはデレゲーションによって CORBA アプリケーションに実装されます。

Oracle Tuxedo システムの tie クラスについて

デレゲーション ベースのインタフェース実装を作成するには、IDL コンパイラの -T コマンドライン オプションを使用して、OMG IDL ファイルに定義されている各インタフェースに対する tie クラス テンプレートを生成します。

CORBA アプリケーションで tie クラスを使用する場合、Server オブジェクトに Server::create_servant() オペレーションを実装する方法も変わります。以降の節では、Oracle Tuxedo 製品で tie クラスを使用する方法についてさらに詳しく説明し、Server::create_servant() オペレーションを実装してこれらのクラスをインスタンス化する方法についても説明します。

Oracle Tuxedo CORBA では、tie クラスはサーバントであり、したがって基本的にレガシー クラスのラッパー オブジェクトとして機能します。

次の図に、レガシー オブジェクトのラッパーとして機能する、Account インタフェースの継承の特性を示します。レガシー オブジェクトには、オペレーション op1 の実装が含まれています。tie クラスは、op1 をレガシー クラスに委譲します。

tie クラスは、クライアント アプリケーションからは見えません。クライアント アプリケーションには、tie クラスは自身が呼び出すオブジェクトの完全な実装のように見えます。tie クラスは、ユーザが提供するレガシー クラスにすべてのオペレーションを委譲します。さらに、tie クラスには次のものが含まれます。

tie クラスを使用する条件

tie クラスは Oracle Tuxedo CORBA に固有のものではなく、CORBA アプリケーションでデレゲーションを実装するための唯一の方法でもありません。ただし、Oracle Tuxedo CORBA の tie クラス用の便利な機能を使用すると、それらの tie クラスの基本的なコンストラクタ、デストラクタ、およびハウスキーピング オペレーションに必要なコーディングの量を大幅に減らすことができます。

tie クラスは、次のいずれかの状況で使用することをお勧めします。

次の場合、tie クラスの使用はお勧めしません

CORBA アプリケーションに tie クラスを作成する方法

Oracle Tuxedo ドメインのアプリケーションに tie クラスを作成するには、次の手順に従います。

  1. アプリケーションのオブジェクトと同じように、OMG IDL ファイルに tie クラスのインタフェース定義を作成します。
  2. -T オプションを使用して、OMG IDL ファイルをコンパイルします。
  3. IDL コンパイラは、C++ テンプレート クラスを生成します。このクラスはスケルトンの名前を取り、その後ろに _tie という文字列が付加されます。IDL コンパイラは、このテンプレート クラスをスケルトン ヘッダ ファイルに追加します。

    IDL コンパイラは、tie クラスの実装ファイルを生成しないことに注意してください。このファイルは、次のステップで説明するように手動で作成する必要があります。

  4. tie クラスの実装ファイルを作成します。実装ファイルには、そのオペレーションをレガシー クラスに委譲するコードを記述します。
  5. Server オブジェクトの Server::create_servant() オペレーションに、レガシー オブジェクトをインスタンス化するコードを記述します。
  6. 次の例では、tie クラス POA_Account_tie のサーバントが作成され、レガシー クラス LegacyAccount がインスタンス化されます。

    Account * Account_ptr = new LegacyAccount();
    AccountFactoryServant = new POA_Account_tie<LegacyAccount> (Account_ptr)
注意 : UNIX 用の Compaq C++ Tru64 コンパイラで tie クラスをコンパイルする場合、buildobjserver コマンドで使用される CFLAGS または CPPFLAGS 環境変数の定義に -noimplicit_include オプションを指定する必要があります。このオプションを指定すると、C++ コンパイラはサーバ スケルトン ヘッダ ファイル (_s.h) がインクルードされる場所にサーバ スケルトン定義ファイル (_s.cpp) を自動的に組み込みません。これは、複数定義のシンボル エラーを回避するために必要です。Tru64 C++ で tie クラスなどのクラス テンプレートを使用する方法については、Compaq の出版物を参照してください。

  ページの先頭       前  次