CORBAサーバー・アプリケーションの作成

     前  次    新規ウィンドウで目次を開く  新規ウィンドウで索引を開く  PDFとして表示 - 新規ウィンドウ  Adobe Readerを取得 - 新規ウィンドウ
コンテンツはここから始まります

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

この章では、CORBAサーバー・アプリケーションの作成に含まれる基本手順について説明します。この章で示される手順は決定ではありません。特定のサーバー・アプリケーションでは他の手順を踏む必要がある可能性もあり、一部の手順の順序を変更する必要がある場合もあります。ただし、すべてのCORBAサーバー・アプリケーションの開発プロセスでは、各手順を共有しています。

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

この章では、最初に手順の概要を示し、このマニュアル全体を通して使用する開発ツールとコマンドもリストします。特定のデプロイメント環境では追加のソフトウェア開発ツールを使用する場合があるため、この章でリストおよび説明しているツールとコマンドも確定的ではありません。

この章では、Oracle Tuxedoソフトウェアで提供されているBasic Universityサンプル・アプリケーションの例を示します。Basic Universityサンプル・アプリケーションの詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。このマニュアル全体を通して使用されるツールとコマンドの詳細は、CORBAプログラミング・リファレンスを参照してください。

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

 


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

サーバー・アプリケーションを作成する基本的なステップは、次のとおりです。

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

Oracle Tuxedoソフトウェアには、表2-1に示す開発ツールとコマンドも用意されています。

表2-1 開発ツールとコマンド
ツール
説明
IDLコンパイラ
アプリケーションのOMG IDLファイルをコンパイルします。
genicf
実装構成ファイル(ICFファイル)を生成します(このファイルを修正して、デフォルト以外のオブジェクト・アクティブ化ポリシーとトランザクション・ポリシーを指定できます)。
buildobjserver
CORBAサーバー・アプリケーションの実行可能イメージを作成します。
tmloadcf
TUXCONFIGファイルを作成します(このファイルは、サーバー・アプリケーションの構成を指定するCORBAドメインのバイナリ・ファイルです)。
「tmadmin」
一部のサンプル・アプリケーションで使用されるトランザクション・アクティビティのログを作成します。

 


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

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

<span style=インタフェースAccountの継承特性" id="wp1032682"/>

IDLコンパイラで生成されるファイルを表2-2で説明します

表2-2 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コマンド構文の意味は次のとおりです。

注意: 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でオブジェクトのアクティブ化ポリシーとトランザクション・ポリシーを指定する方法」を参照してください。

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:サーバー・オブジェクトの作成

サーバー・オブジェクトの実装は、他の言語オブジェクトの実装とは異なります。サーバー・オブジェクトのヘッダー・クラスはすでに作成されており、サーバー・オブジェクト・クラスはすでにインスタンス化されています。サーバー・オブジェクトを作成するには、事前にパッケージ化されたサーバー・オブジェクト・クラスの特定のメソッドのセットを実装します。実装するメソッドについては、この項で説明します。

サーバー・オブジェクトを作成するには、一般的なテキスト・エディタを使用して新規ファイルを作成し、表2-3に示すオペレーションを実装します。

表2-3 サーバー・オブジェクトの作成
オペレーション
説明
Server::initialize();
サーバー・アプリケーションの起動後に、TPフレームワークはサーバー・アプリケーション初期化プロセスの最後のステップとしてこのオペレーションを呼び出します。このオペレーション内で、特定のサーバー・アプリケーションに必要な初期化タスクをいくつか実行します。このオペレーション内で提供する内容は、「サーバー・アプリケーションの初期化」を参照してください。
Server::create_servant();
既存のサーバントでは処理できないクライアント・リクエストが到着すると、TPフレームワークはこのオペレーションを呼び出して、アクティブにするCORBAオブジェクトのOMG IDLインタフェースのインタフェース・リポジトリIDを渡します。このオペレーション内で提供する内容は、「サーバントの作成」を参照してください。
Server::release();
TPフレームワークは、サーバー・アプリケーションの停止時にこのオペレーションを呼び出します。このオペレーションには、サーバー・アプリケーションで管理されるオブジェクト・ファクトリの登録解除およびその他の停止タスクを実行するためのコードが含まれます。このオペレーションで提供する内容は、「サーバー・アプリケーションのリリース」を参照してください。

サーバー・アプリケーションには、サーバー・オブジェクトのインスタンスが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オブジェクトに登録するコードを作成する必要があります(通常、このコードはサーバー・アプリケーション初期化プロセスの最後のステップとして呼び出されます)。

サーバー・アプリケーションで管理されるファクトリを登録するコードを記述するには、次の手順に従います。

  1. ファクトリのオブジェクト参照を作成します。
  2. この手順には、「ファクトリの実装」のページ 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()
    );
  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フレームワークはサーバー・オブジェクトで次のオペレーションを呼び出します。

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()にも注意してください。これは、ファクトリの登録に使用されるインタフェース名とも同じです。

 


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

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

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

以降の項で説明する内容は次のとおりです。

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

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

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

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

トランザクション・ポリシー
説明
always
このオブジェクトに対するオペレーションが呼び出されると、このポリシーによってTPフレームワークはこのオブジェクトのトランザクションを開始します(アクティブなトランザクションがまだない場合)。TPフレームワークがトランザクションを開始した場合、TPフレームワークはオペレーションが正常に完了するとトランザクションをコミットし、オペレーションで例外が発生するとトランザクションをロールバックします。
optional
このオブジェクトに対するオペレーションが呼び出されると、TPフレームワークはトランザクションがアクティブな場合にこのオブジェクトをトランザクションに含めます。トランザクションがアクティブでない場合は、このオブジェクトに対する呼出しはこのオブジェクトに対して定義されたアクティブ化ポリシーに従って続行されます。
これはデフォルトのトランザクション・ポリシーです。
never
このオブジェクトがトランザクション中に呼び出された場合、TPフレームワークはエラー条件を生成します。
ignore
このオブジェクトに対するオペレーションが呼び出されたときにトランザクションがアクティブな場合、トランザクションはオペレーション呼出しが完了するまで一時停止します。このトランザクション・ポリシーにより、このトランザクション・ポリシーが割り当てられているオブジェクトにはトランザクションを伝播できません。

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

  1. 次の例のようにアプリケーションのOMG IDLファイルを入力として指定してgenicfコマンドを入力することで、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:サーバー・アプリケーションのコンパイルとリンク

サーバー・オブジェクトとオブジェクト実装のコードの記述が完了したら、サーバー・アプリケーションをコンパイルおよびリンクする必要があります。

注意: 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アプリケーションを再コンパイルする必要があります。

 


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

システム管理者は、この項で要約した手順を使用してCORBAサーバー・アプリケーションをデプロイします。Universityサンプル・アプリケーションのビルドとデプロイの詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。

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

  1. サーバー・アプリケーションの実行可能ファイルを、目的のOracle Tuxedoドメインに属するマシンの適切なディレクトリに配置します。
  2. UBBCONFIGファイルとも呼ばれるアプリケーションの構成ファイルを一般的なテキスト・エディタで作成します。
  3. CORBAサーバー・アプリケーションを起動するマシンに、次の環境変数を設定します。
    • UBBCONFIGファイルのTUXCONFIGエントリと完全に一致する必要のある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サンプル・アプリケーションの構成の詳細は、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フレームワークは、これらのメッセージをユーザー・ログにのみ書き込みます。クライアント・アプリケーションには戻されません。

これらのメッセージは、表2-5に示す、オプションの理由文字列を持つ例外で指定します。

表2-5 例外
例外
例外を生成する可能性のあるコールバック・メソッド
ActivateObjectFailed
Tobj_ServantBase::activate_object()
DeactivateObjectFailed
Tobj_ServantBase::deactivate_object()
CreateServantFailed
Server::create_servant()
InitializeFailed
Server::initialize()
ReleaseFailed
Server::release()

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

throw CreateServantFailed("Unknown interface");

これらの例外をスローする場合は、理由文字列パラメータが必要です。これらのいずれかの例外で文字列を指定しない場合は、次の例のように二重引用符文字を使用する必要があります。

throw ActivateObjectFailed("");

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

サーバー・オブジェクトの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::initialize()オペレーションで、サーバント・プールを設定するコードを記述します。プールは1つ以上のサーバントへのポインタのセットから構成され、プールのコードはプールに維持される特定のクラスのサーバント数を指定します。
  2. プールされたサーバントのTobj_ServantBase::deactive_object()オペレーションで、TP::application_responsibility()オペレーションを実装します。TP::application_responsibility()オペレーションの実装で、TPフレームワークによってTobj_ServantBase::deactivate_object()オペレーションが呼び出されるときにサーバントへのポインタをサーバント・プールに配置するコードを提供します。
  3. サーバー・オブジェクトのServer::create_servant()オペレーションの実装で、クライアント・リクエストの到着時に次の操作を実行するコードを記述します。
    1. プールをチェックして、リクエストを満たせるサーバントがあるかどうかを確認します。
    2. サーバントが存在しない場合は、サーバントを作成し、それに対してTobj_ServantBase::activate_object()オペレーションを呼び出します。
    3. サーバントが存在する場合は、それに対してTobj_ServantBase::activate_object()オペレーションを呼び出し、クライアント・リクエストに含まれているオブジェクトIDを割り当てます。
注意: TP::application_responsibility()オペレーションのサポートは、このリリースで変更されました。詳細は、CORBAプログラミング・リファレンスを参照してください。

 


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

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

一方、POAスケルトン・クラスからの継承が難しいか実際的ではないCORBAアプリケーションでは、C++オブジェクトを使用する場合もあります。たとえば、POAスケルトン・クラスから継承するために大量のリライトが必要なC++オブジェクトがある場合などです。オブジェクトのtieクラスを作成して、この非CORBAオブジェクトをCORBAアプリケーションで使用できます。このtieクラスはPOAスケルトン・クラスから継承し、tieクラスにはこれらのオペレーションの実装用のレガシー・クラスに委任する1つ以上のオペレーションが含まれます。レガシー・クラスは、デレゲーションによってCORBAアプリケーションで実装されます。

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

デレゲーション・ベースのインタフェース実装を作成するには、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をレガシー・クラスに委任します。

図2-1 インタフェースAccountの継承特性

<span style=インタフェースAccountの継承特性" id="wp1025920"/>

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

tieクラスを使用する条件

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

tieクラスの使用は、次のいずれかの状況でお薦めします。

tieクラスは、次の場合には推奨されません

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

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

  1. アプリケーションの任意のオブジェクトに対するのと同様に、OMG IDLファイルのtieクラスに対してインタフェース定義を作成します。
  2. -Tオプションを使用してOMG IDLファイルをコンパイルします。
  3. IDLコンパイラは、スケルトンの名前に文字列_tieを追加したC++テンプレート・クラスを生成します。IDLコンパイラは、このテンプレート・クラスをスケルトン・ヘッダー・ファイルに追加します。

    IDLコンパイラは、tieクラスの実装ファイルを生成しません。このファイルは次の手順で説明するように手動で作成する必要があります。

  4. tieクラスの実装ファイルを作成します。実装ファイルには、オペレーションをレガシー・クラスに委任するコードが含まれます。
  5. サーバント・オブジェクトの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オプションを含める必要があります。このオプションは、多重定義シンボル・エラーを回避するために必要なサーバー・スケルトン・ヘッダー・ファイル(_s.h)がインクルードされるすべての場所にC++コンパイラがサーバー・スケルトン定義ファイル(_s.cpp)を自動的にインクルードすることを防ぎます。Tru64 C++でのtieクラスなどのクラス・テンプレートとの使用の詳細は、Compaqのマニュアルを参照してください。

  先頭に戻る       前  次