この章では、CORBAサーバー・アプリケーションの作成に含まれる基本手順について説明します。この章で示される手順は決定ではありません。特定のサーバー・アプリケーションでは他の手順を踏む必要がある可能性もあり、一部の手順の順序を変更する必要がある場合もあります。ただし、すべてのCORBAサーバー・アプリケーションの開発プロセスでは、各手順を共有しています。
この章では、最初に手順の概要を示し、このマニュアル全体を通して使用する開発ツールとコマンドもリストします。特定のデプロイメント環境では追加のソフトウェア開発ツールを使用する場合があるため、この章でリストおよび説明しているツールとコマンドも確定的ではありません。
この章では、Oracle Tuxedoソフトウェアで提供されているBasic Universityサンプル・アプリケーションの例を示します。Basic Universityサンプル・アプリケーションの詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。このマニュアル全体を通して使用されるツールとコマンドの詳細は、CORBAプログラミング・リファレンスを参照してください。
マルチスレッドCORBAサーバー・アプリケーションの作成の詳細は、第4章「マルチスレッドCORBAサーバー・アプリケーションの作成」を参照してください。
サーバー・アプリケーションを作成する基本的なステップは、次のとおりです。
ステップ1: サーバー・アプリケーション用のOMG IDLファイルのコンパイル
ステップ2: 各インタフェースのオペレーションを実装するメソッドの記述
ステップ3: サーバー・オブジェクトの作成
ステップ4: メモリー内でのオブジェクトの振る舞いの定義
ステップ5: サーバー・アプリケーションのコンパイルとリンク
ステップ6: サーバー・アプリケーションのデプロイ
Oracle Tuxedoソフトウェアには、表2-1に示す開発ツールとコマンドも用意されています。
Oracle Tuxedoドメインで実行されるアプリケーションのクライアント部分とサーバー部分の基本構造は、アプリケーションのOMG IDLファイルの文によって決定されます。アプリケーションのOMG IDLファイルをコンパイルすると、IDLコンパイラは、idl
コマンドで指定したオプションに応じて、次の図に示すファイルの一部またはすべてを生成します。共有コンポーネントは、サーバー・アプリケーションを作成するために修正する生成済ファイルです。
Account
の継承特性" id="wp1032682"/>
IDLコンパイラで生成されるファイルを表2-2で説明します
表2-1にリストされているファイルを生成するには、次のコマンドを入力します。
idl [options] idl-filename [icf-filename]
options
は、IDLコンパイラへの1つ以上のコマンドライン・オプションを表します。コマンドライン・オプションについては、CORBAプログラミング・リファレンスで説明されています。実装ファイルを生成する場合は、-i
オプションを指定する必要があります。idl-filename
は、アプリケーションのOMG IDLファイルの名前を表します。 icf-filename
は、アプリケーションの実装構成ファイル(ICFファイル)の名前を表すオプション・パラメータであり、オブジェクト・アクティブ化ポリシーの指定、およびスケルトン・ファイルと実装ファイルを生成するインタフェース数の制限に使用します。ICFファイルの使用方法は、「ステップ4: メモリー内でのオブジェクトの振る舞いの定義」で説明されています。注意: | CORBA 2.3機能をサポートするためにWebLogic Enterprise 5.1で変更されたプラグマのC++ IDLコンパイラ実装は、IDLファイルに影響することがあります。CORBA 2.3機能は、pragma接頭辞定義が影響する範囲を変更します。プラグマは、インクルードされたIDLファイルに含まれる定義には影響せず、インクルードされたIDLファイルで行われたpragma接頭辞定義はインクルード・ファイルの外部にあるオブジェクトには影響しません。 |
C++ IDLコンパイラは、pragma接頭辞の処理を修正するように変更されました。この変更はオブジェクトのリポジトリIDに影響し、_narrow
などの一部のオペレーションで障害を引き起こすことがあります。
idl
コマンドなどのIDLコンパイラの詳細は、CORBAプログラミング・リファレンスを参照してください。
次のコマンドラインは、OMG IDLファイルunivb.idl
に対して、クライアント・スタブ・ファイル、スケルトン・ファイルおよび初期実装ファイルをスケルトン・ヘッダー・ファイルおよび実装ヘッダー・ファイルとともに生成します。
idl -i univb.idl
idl
コマンドの詳細は、CORBAプログラミング・リファレンスを参照してください。Oracle Tuxedo Universityサンプル・アプリケーション用のこれらのファイルの生成の詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。
注意: | デフォルト以外のオブジェクト・アクティブ化またはトランザクション・ポリシーの指定を計画している場合、またはスケルトン・ファイルと実装ファイルを生成するインタフェース数の制限を計画している場合は、実装構成ファイル(ICF)を生成および変更し、ICFファイルをIDLコンパイラに渡す必要があります。詳細は、「ICFでオブジェクトのアクティブ化ポリシーとトランザクション・ポリシーを指定する方法」を参照してください。 |
IDLコンパイラには、インタフェースのtieクラス・テンプレートの生成に使用できる-T
コマンドライン・オプションも用意されています。CORBAアプリケーションでのtieクラスの実装の詳細は、「デレゲーション・ベースのインタフェース実装」を参照してください。
サーバー・アプリケーション・プログラマのタスクは、アプリケーションのOMG IDLファイルで定義した各インタフェースのオペレーションを実装するメソッドの記述です。
Tobj_ServantBase::activate_object()
およびTobj_ServantBase::deactivate_object()
オペレーション。 Tobj_ServantBase::activate_object()
およびTobj_ServantBase::deactivate_object()
オペレーション内に、オブジェクトのアクティブ化または非アクティブ化に関連する手順を実行するコードを記述します。これには、オブジェクトの永続状態のディスクからの読取りとディスクへの書込みが含まれます。オブジェクトにこれらのオペレーションを実装する場合は、実装ヘッダー・ファイルを編集し、これらのオペレーションを使用する各実装にオペレーションの定義を追加する必要もあります。
サーバー・アプリケーションの実装ファイルをすべて手動で作成することもできますが、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()
);
Registrar
オブジェクトのインタフェース・リポジトリIDをタイプ・コードから抽出して指定します。University::_tc_Registrar->id()
Registrar
オブジェクトに対して作成されたオブジェクト参照は、そのオブジェクト参照を作成したRegistrarFactory
オブジェクトと同じグループにルーティングされます。CORBA::NVlist::_nil()
オブジェクト参照がルーティングされるグループに影響するルーティング基準の指定については、第8章「Oracle TuxedoのCORBAサーバー・アプリケーションのスケーリング」を参照してください。
サーバー・オブジェクトの実装は、他の言語オブジェクトの実装とは異なります。サーバー・オブジェクトのヘッダー・クラスはすでに作成されており、サーバー・オブジェクト・クラスはすでにインスタンス化されています。サーバー・オブジェクトを作成するには、事前にパッケージ化されたサーバー・オブジェクト・クラスの特定のメソッドのセットを実装します。実装するメソッドについては、この項で説明します。
サーバー・オブジェクトを作成するには、一般的なテキスト・エディタを使用して新規ファイルを作成し、表2-3に示すオペレーションを実装します。
サーバー・アプリケーションには、サーバー・オブジェクトのインスタンスが1つのみあります。サーバー・アプリケーションで複数のCORBAオブジェクト実装を管理している場合、作成するServer::initialize()
、Server::create_servant()
およびServer::release()
オペレーションには、これらすべての実装に適用するコードを含める必要があります。
これらのほとんどのタスクに対して作成するコードには、TPフレームワークとの対話が含まれます。次以降の項で、これらの各サーバー・オブジェクト・オペレーションに必要なコードについて説明し、Basic Universityサンプル・アプリケーションのサンプル・コードを示します。
サーバー・オブジェクトで最初に実装するオペレーションは、サーバー・アプリケーションを初期化するオペレーションです。このオペレーションは、Oracle Tuxedoシステムがサーバー・アプリケーションを起動するときに呼び出されます。TPフレームワークは、サーバー・アプリケーションの起動シーケンス中にサーバー・オブジェクトの次のオペレーションを呼び出します。
CORBA::Boolean Server::initialize(int argc, char** argv)
Oracle TuxedoドメインのUBBCONFIG
ファイルのSERVERS
セクションで特定のサーバー・アプリケーションのCLOPT
パラメータに指定したコマンドライン・オプションは、Server::initialize()
オペレーションにargc
およびargv
として渡されます。サーバー・アプリケーションへの引数の受渡しの詳細は、Oracle Tuxedoアプリケーション実行時の管理を参照してください。サーバー・アプリケーションへの引数の受渡しの例は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。
Server::initialize()
オペレーションに、次の処理を行うコードを含めます(該当する場合)。
クライアント・アプリケーションで簡単に特定できるファクトリをサーバー・アプリケーションで管理する場合は、そのファクトリをFactoryFinderオブジェクトに登録するコードを作成する必要があります(通常、このコードはサーバー・アプリケーション初期化プロセスの最後のステップとして呼び出されます)。
サーバー・アプリケーションで管理されるファクトリを登録するコードを記述するには、次の手順に従います。
この手順には、「ファクトリの実装」のページ 2-7で説明されているように、オブジェクト参照の作成が含まれます。この手順では、TP::create_object_reference()
オペレーションへの呼出しを含め、ファクトリのOMG IDLインタフェースのインタフェース・リポジトリIDを指定します。次の例では、s_v_fact_ref
変数で表されるRegistrarFactory
ファクトリへのオブジェクト参照を作成します。
University::RegistrarFactory s_v_fact_ref =
TP::create_object_reference(
University::_tc_RegistrarFactory->id(),
object_id,
CORBA::NVList::_nil()
);
このステップでは、サーバー・アプリケーションで管理される各ファクトリについて次のオペレーションを呼び出します。
TP::register_factory (CORBA::Object_ptr factory_or,
const char* factory_id);
TP::register_factory()
オペレーションは、サーバー・アプリケーションのファクトリをFactoryFinderオブジェクトに登録します。このオペレーションには、次の入力パラメータが必要です。
次の例は、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フレームワークはサーバー・オブジェクトで次のオペレーションを呼び出します。
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()
オペレーションには、単一の入力引数が必要です。引数では、サーバントを作成しているオブジェクトの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; // unknown interface
}
Oracle Tuxedoシステム管理者がtmshutdown
コマンドを入力すると、TPフレームワークはOracle Tuxedoドメインで実行している各サーバー・アプリケーションのサーバー・オブジェクトで次のオペレーションを呼び出します。
void Server::release()
Server::release()
オペレーション内で、サーバー・アプリケーションに固有の次のようなアプリケーション固有クリーンアップ・タスクを実行できます。
停止のリクエストを受信したサーバー・アプリケーションは、他のリモート・オブジェクトからのリクエストを受信することができなくなります。このことは、管理タスクであるサーバー・アプリケーションの停止の順序に影響します。たとえば、あるサーバー・プロセスがあるとして、2番目のサーバー・プロセスのServer::release()
オペレーションにその最初のサーバー・プロセスの呼出しが含まれている場合は、最初のサーバー・プロセスを停止しないでください。
サーバー停止時に、サーバー・アプリケーションの各ファクトリを登録解除するために次の呼出しを含める必要があります。
TP::unregister_factory (CORBA::Object_ptr factory_or,
const char* factory_id)
TP::unregister_factory()
オペレーションの呼出しは、Server::release()
実装の最初のアクションとして行う必要があります。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()にも注意してください。これは、ファクトリの登録に使用されるインタフェース名とも同じです。
「オブジェクト状態の管理」で説明しているように、オブジェクト・アクティブ化ポリシーとトランザクション・ポリシーの割当てによって、またオプションでアプリケーションで制御される非アクティブ化機能を使用して、オブジェクトが非アクティブ化される原因となるイベントを決定します。
ICFファイルにオブジェクト・アクティブ化ポリシーとトランザクション・ポリシーを指定し、TP::deactivateEnable()
オペレーションを介してアプリケーションで制御される非アクティブ化を実装します。この項では、Basic Universityサンプル・アプリケーションを例として使用して、両方のメカニズムの実装方法を説明します。
Oracle Tuxedoソフトウェアは、「オブジェクトのアクティブ化ポリシー」で説明している表2-4のアクティブ化ポリシーをサポートします。
Oracle Tuxedoソフトウェアは、第6章「トランザクションのCORBAサーバー・アプリケーションへの統合」で説明している次のトランザクション・ポリシーもサポートします。
これらのポリシーをアプリケーションのオブジェクトに割り当てるには、次の手順に従います。
genicf
コマンドを入力することで、ICFファイルを生成します。# genicf university.idl
前のコマンドはファイルuniversity.icf
を生成します。
method
であり、デフォルトのトランザクション・アクティブ化ポリシーはoptional
であることに注意してください。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 );
};
};
RegistrarFactory
インタフェースに対してスケルトン・ファイルと実装ファイルが生成されないようにするには、次の行を削除します。implementation RegistrarFactory_i
{
activation_policy ( method );
transaction_policy ( optional );
implements ( UniversityB::RegistrarFactory );
};
サーバー・オブジェクトとオブジェクト実装のコードの記述が完了したら、サーバー・アプリケーションをコンパイルおよびリンクします。
CORBAサーバー・アプリケーションのコンパイルとリンクには、buildobjserver
コマンドを使用します。buildobjserver
コマンドの形式は次のとおりです。
buildobjserver [-o servername] [options]
buildobjserver
コマンドの構文要素を次に説明します。
Universityサンプル・アプリケーションのコンパイルとリンクに関する詳細情報は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。buildobjserver
コマンドの詳細情報は、Oracle Tuxedoコマンド・リファレンスを参照してください。
マルチスレッドCORBAサーバー・アプリケーションの設計と構築には特別な考慮事項があります。「buildobjserverコマンドの使い方」を参照してください。
注意: | Oracle TuxedoソフトウェアをIBM AIX 4.3.3システムで実行している場合は、-brtl コンパイラ・オプションを使用してCORBAアプリケーションを再コンパイルする必要があります。 |
システム管理者は、この項で要約した手順を使用してCORBAサーバー・アプリケーションをデプロイします。Universityサンプル・アプリケーションのビルドとデプロイの詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。
サーバー・アプリケーションをデプロイするには、次の手順に従います。
UBBCONFIG
ファイルとも呼ばれるアプリケーションの構成ファイルを一般的なテキスト・エディタで作成します。TUXDIR
環境変数を設定します。この環境変数は、Oracle Tuxedoソフトウェアがインストールされている場所を指します。TUXCONFIG
ファイルを作成します。 tmloadcf -yapplication-
ubbconfig
-file
コマンドライン引数application-
ubbconfig
-file
は、アプリケーションのUBBCONFIG
ファイルの名前を表します。このコマンドを実行するには古いTUXCONFIG
ファイルを削除することが必要な場合があります。
tmboot -y
Universityサンプル・アプリケーションの構成の詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。CORBAアプリケーションのUBBCONFIG
ファイルの作成の詳細は、Oracle Tuxedoアプリケーションの設定を参照してください。
クライアント・アプリケーションがCORBAオブジェクトに対するオペレーションを呼び出すと、呼出しの結果として例外が戻されることがあります。クライアント・アプリケーションに戻される可能性のある有効な例外は次のとおりです。
Oracle Tuxedoシステムは、「例外のサーバー・アプリケーション・ビュー」で説明するように、これらのCORBA定義制限に違反しないように動作します。
クライアント・アプリケーションに公開されている例外のセットは限られているため、クライアント・アプリケーションは原因があいまいな例外を捕捉することがあります。可能な場合には、Oracle Tuxedoシステムがこのような例外をユーザー・ログの説明メッセージで補足します(これは、エラー条件の検出とデバッグに役立ちます)。このようなケースについて、次の項で説明します。
Oracle Tuxedoシステムは、TPオブジェクトに対するオペレーションが呼び出されたときにアプリケーションに次のタイプの例外を戻すことがあります。
TobjS_c.h
ファイルで定義されたCORBA UserExceptions
。このファイルで定義されている例外のOMG IDLは次のとおりです。interface TobjS {
exception AlreadyRegistered { };
exception ActivateObjectFailed { string reason; };
exception ApplicationProblem { };
exception CannotProceed { };
exception CreateServantFailed { string reason; };
exception DeactivateObjectFailed { string reason; };
exception IllegalInterface { };
exception IllegalOperation { };
exception InitializeFailed { string reason; };
exception InvalidDomain { };
exception InvalidInterface { };
exception InvalidName { };
exception InvalidObject { };
exception InvalidObjectId { };
exception InvalidServant { };
exception NilObject { string reason; };
exception NoSuchElement { };
exception NotFound { };
exception OrbProblem { };
exception OutOfMemory { };
exception OverFlow { };
exception RegistrarNotAvailable { };
exception ReleaseFailed { string reason; };
exception TpfProblem { };
exception UnknownInterface { };
}
サーバー・アプリケーションは、クライアント呼出しの処理中に次の場所で例外を生成することがあります。
サーバー・アプリケーションは次のいずれかのタイプの例外を生成することがあります。
TobjS_c.h
ファイルで定義されたCORBAユーザー定義例外。次の例外は、Oracle Tuxedoシステムがトラブルシューティングに役立つユーザー・ログにメッセージを送信できるようにサーバー・アプリケーションで使用することを目的としています。interface TobjS {
exception ActivateObjectFailed { string reason; };
exception CreateServantFailed { string reason; };
exception DeactivateObjectFailed { string reason; };
exception InitializeFailed { string reason; };
exception ReleaseFailed { string reason; };
}
サーバー・アプリケーション・コードで生成され、サーバー・アプリケーションで捕捉されないすべての例外は、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システムは、次のいずれかの条件に該当しないかぎりそれらをクライアント・アプリケーションに戻します。
always
トランザクション・ポリシーがあり、オブジェクトが呼び出されたときにOracle Tuxedoシステムがトランザクションを自動的に開始した場合。この場合、トランザクションはOracle Tuxedoシステムによって自動的にロールバックされます。クライアント・アプリケーションはトランザクションを認識しないため、Oracle Tuxedoシステムは、クライアントがトランザクションを開始した場合に生成されるCORBA:: TRANSACTION_ROLLEDBACK
例外ではなく、CORBA::OBJ_ADAPTER
CORBAシステム例外を生成します。TobjS_c.h
で定義されている場合。この場合、例外はCORBA::BAD_OPERATION
例外に変換され、クライアント・アプリケーションに戻されます。また、次のメッセージがユーザー・ログに送信されます。"WARN: Application didn't catch TobjS exception. TP Framework throwing CORBA::BAD_OPERATION."
例外がTobjS::IllegalOperation
の場合は、次の補足メッセージが書き込まれ、アプリケーションのコーディング・エラーの可能性が開発者に警告されます。
"WARN: Application called TP::deactivateEnable() illegally and didn't catch TobjS exception."
この状況は、transaction
アクティブ化ポリシーを持つオブジェクトの内部でTP::deactivateEnable()
オペレーションが呼び出された場合に発生することがあります。(アプリケーションで制御される非アクティブ化は、トランザクション・バウンド・オブジェクトに対してサポートされません。)
CORBA::INTERNAL
例外がクライアントに戻されます。これは通常、オブジェクトがアクティブなプロセスでの重大なシステムの問題を示しています。 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フレームワークは、これらのメッセージをユーザー・ログにのみ書き込みます。クライアント・アプリケーションには戻されません。
これらのメッセージは、表2-5に示す、オプションの理由文字列を持つ例外で指定します。
メッセージ文字列をユーザー・ログに送信するには、次の例のように例外に文字列を指定します。
throw CreateServantFailed("Unknown interface");
これらの例外をスローする場合は、理由文字列パラメータが必要です。これらのいずれかの例外で文字列を指定しない場合は、次の例のように二重引用符文字を使用する必要があります。
throw ActivateObjectFailed("");
サーバー・オブジェクトの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()
オペレーションで使用しますが、オブジェクト実装とファクトリが異なる実行可能ファイルにある場合は不一致が発生することがあります。この潜在的な問題は診断が困難です。
この潜在的な問題を回避するために、開発中に次の防御的なプログラミング方針を検討できます。このコードは、ソフトウェアの本番バージョンでは許容できないパフォーマンスの低下をもたらす可能性があるため、アプリケーションのデバッグ・バージョンにのみ含める必要があります。
TP::create_object_reference()
オペレーションを呼び出す直前に、インタフェース・リポジトリをチェックして必要なインタフェースが存在するかどうかを確認するコードを含めます。すべてのアプリケーションOMG IDLが最新であり、インタフェース・リポジトリにロードされていることを確認してください。このチェックでインタフェースIDが見つからない場合は、不一致であることを想定できます。TP::create_object_reference()
オペレーションの呼出しに続いて、オブジェクトを"ping"するコードを含めます。つまり、コードはオブジェクトに対して任意のオペレーション(通常は何も行わないオペレーション)を呼び出します。この呼出しでCORBA::OBJECT_NOT_EXIST
例外が発生する場合は、インタフェースIDの不一致が存在します。オブジェクトの"ping"によってオブジェクトがアクティブになり、アクティブ化に関連するオーバーヘッドが発生することに注意してください。 Tobj_ServantBase::deactivate_object()
オペレーションは、オブジェクトのアクティブ化境界に達したときに呼び出されます。オプションで、このオペレーションの実装で永続状態をディスクに書き込むことができます。このオペレーションで発生した例外はクライアント・アプリケーションに戻されないことに注意してください。クライアント・アプリケーションは、オブジェクトがトランザクションに関与していないかぎり、このオペレーションで発生したエラー条件を認識しません。したがって、このオペレーションを介した状態の書込みに成功したかどうかをクライアント・アプリケーションが知る必要がある場合は、トランザクションを使用することをお薦めします。
状態の書込みにTobj_ServantBase::deactivate_object()
オペレーションを使用することに決め、クライアント・アプリケーションが書込みオペレーションの結果を知る必要がある場合は、次の操作を実行することをお薦めします。
method
またはtransaction
アクティブ化ポリシーを使用して行うことができ、TP::deactivateEnable()
オペレーションがトランザクション境界内で呼び出される場合はprocess
アクティブ化ポリシーで行うこともできます。COSTransactions::Current::rollback_only()
オペレーションを呼び出して、トランザクションがロールバックされるようにします。これにより、クライアント・アプリケーションが次のいずれかの例外を受け取ります。 トランザクションが使用されていない場合は、Tobj_ServantBase::deactivate_object()
オペレーションを使用するかわりに、オブジェクトに対する個々のオペレーションのスコープ内でオブジェクト状態を書き込むことをお薦めします。これにより、エラーが発生した場合に、オペレーションはクライアント・アプリケーションに戻される例外を生成できます。
「サーバント・プールとステートレス・オブジェクト」で説明したように、サーバント・プールはメソッド・バウンド・オブジェクトまたはトランザクション・バウンド・オブジェクトのオブジェクト・インスタンス化のコストを削減する手段を提供します。
通常、オブジェクトの非アクティブ化中(つまり、TPフレームワークがTobj_ServantBase::deactivate_object()
オペレーションを呼び出すとき)、TPフレームワークはオブジェクトのサーバントを削除します。ただし、サーバント・プールが使用されるときは、TPフレームワークはオブジェクトの非アクティブ化時にサーバントを削除しません。かわりに、サーバー・アプリケーションはプール内でサーバントへのポインタを維持します。当該プールでサーバントによって満たされる後続のクライアント・リクエストが受信されると、サーバー・アプリケーションはサーバントを再使用して新規オブジェクトIDを割り当てます。サーバントがプールから再使用されるとき、TPフレームワークは新規サーバントを作成しません。
Server::initialize()
オペレーションで、サーバント・プールを設定するコードを記述します。プールは1つ以上のサーバントへのポインタのセットから構成され、プールのコードはプールに維持される特定のクラスのサーバント数を指定します。Tobj_ServantBase::deactive_object()
オペレーションで、TP::application_responsibility()
オペレーションを実装します。TP::application_responsibility()
オペレーションの実装で、TPフレームワークによってTobj_ServantBase::deactivate_object()
オペレーションが呼び出されるときにサーバントへのポインタをサーバント・プールに配置するコードを提供します。Server::create_servant()
オペレーションの実装で、クライアント・リクエストの到着時に次の操作を実行するコードを記述します。注意: | TP::application_responsibility() オペレーションのサポートは、このリリースで変更されました。詳細は、CORBAプログラミング・リファレンスを参照してください。 |
Oracle Tuxedo CORBAアプリケーションでオブジェクトを実装するには、継承とデレゲーションの2つの主要な方法があります。オブジェクトがPOAスケルトン・クラスから継承し、したがってCORBAオブジェクトである場合、そのオブジェクトは継承によって実装されているといいます。
一方、POAスケルトン・クラスからの継承が難しいか実際的ではないCORBAアプリケーションでは、C++オブジェクトを使用する場合もあります。たとえば、POAスケルトン・クラスから継承するために大量のリライトが必要なC++オブジェクトがある場合などです。オブジェクトのtieクラスを作成して、この非CORBAオブジェクトをCORBAアプリケーションで使用できます。このtieクラスはPOAスケルトン・クラスから継承し、tieクラスにはこれらのオペレーションの実装用のレガシー・クラスに委任する1つ以上のオペレーションが含まれます。レガシー・クラスは、デレゲーションによってCORBAアプリケーションで実装されます。
デレゲーション・ベースのインタフェース実装を作成するには、IDLコンパイラの-T
コマンドライン・オプションを使用して、OMG IDLファイルで定義されたインタフェースごとにtieクラス・テンプレートを生成します。
CORBAアプリケーションでのtieクラスの使用は、サーバー・オブジェクトでのServer::create_servant()
オペレーションの実装方法にも影響します。次の各項では、Oracle Tuxedo製品でのtieクラスの使用方法を詳細に説明し、これらのクラスをインスタンス化するためのServer::create_servant()
オペレーションの実装方法も説明します。
Oracle Tuxedo CORBAでは、tieクラスはサーバントであるため、基本的にレガシー・クラスのラッパー・オブジェクトとして機能します。
表2-1に、レガシー・オブジェクトのラッパーとして機能するインタフェースAccount
の継承特性を示します。レガシー・オブジェクトには、オペレーションop1
の実装が含まれます。tieクラスはop1
をレガシー・クラスに委任します。
Account
の継承特性" id="wp1025920"/>
tieクラスはクライアント・アプリケーションに対して透過的です。クライアント・アプリケーションからは、tieクラスはクライアント・アプリケーションが呼び出すオブジェクトの完全な実装のように見えます。tieクラスはすべてのオペレーションをユーザーが提供するレガシー・クラスに委任します。また、tieクラスには次のものが含まれます。
tieクラスはOracle Tuxedo CORBAに固有ではなく、CORBAアプリケーションでデレゲーションを実装する唯一の方法ではありません。ただし、tieクラスに対するOracle Tuxedo CORBAの便利な機能により、これらのtieクラスの基本的なコンストラクタ、デストラクタおよびハウスキーピング・オペレーションに対して行う必要のあるコーディングの量を大幅に減らすことができます。
Oracle Tuxedoドメインのアプリケーションでtieクラスを作成するには、次の手順に従います。
-T
オプションを使用してOMG IDLファイルをコンパイルします。 IDLコンパイラは、スケルトンの名前に文字列_tie
を追加したC++テンプレート・クラスを生成します。IDLコンパイラは、このテンプレート・クラスをスケルトン・ヘッダー・ファイルに追加します。
IDLコンパイラは、tieクラスの実装ファイルを生成しません。このファイルは次の手順で説明するように手動で作成する必要があります。
Server::create_servant()
オペレーションで、レガシー・オブジェクトをインスタンス化するコードを記述します。 次の例では、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 オプションを含める必要があります。このオプションは、多重定義シンボル・エラーを回避するために必要なサーバー・スケルトン・ヘッダー・ファイル(_s.h )がインクルードされるすべての場所にC++コンパイラがサーバー・スケルトン定義ファイル(_s.cpp )を自動的にインクルードすることを防ぎます。Tru64 C++でのtieクラスなどのクラス・テンプレートとの使用の詳細は、Compaqのマニュアルを参照してください。 |