![]() |
![]() |
![]() |
![]() |
![]() |
この章では、Oracle Tuxedoソフトウェアに用意されているBasic Universityサンプル・アプリケーションの例を使用します。Basic Universityサンプル・アプリケーションの詳細は、『CORBA Universityサンプル・アプリケーション・ガイド』を参照してください。このマニュアル全体を通して使用されるツールとコマンドの詳細は、『CORBAプログラミング・リファレンス』を参照してください。Oracle Tuxedoソフトウェアには、表2-1に示す開発ツールとコマンドも用意されています。
表2-1 開発ツールとコマンド Oracle Tuxedoドメインで実行されるアプリケーションのクライアント部分とサーバー部分の基本構造は、アプリケーションのOMG IDLファイルの文によって決定されます。アプリケーションのOMG IDLファイルをコンパイルすると、IDLコンパイラは、idlコマンドで指定したオプションに応じて、次の図に示すファイルの一部またはすべてを生成します。共有コンポーネントは、サーバー・アプリケーションを作成するために修正する生成済ファイルです。表2-2に、IDLコンパイラで生成されるファイルの説明を示します
表2-2 IDLコンパイラで生成されるファイル application_c.cpp application_c.h application_s.cpp application_s.h application_i.cpp application_i.h
• optionsは、IDLコンパイラへの1つ以上のコマンド行オプションを表します。コマンド行オプションについては、『CORBAプログラミング・リファレンス』で説明されています。実装ファイルを生成する場合は、-iオプションを指定する必要があります。
• idl-filenameは、アプリケーションのOMG IDLファイルの名前を表します。
• icf-filenameは、アプリケーションの実装構成ファイル(ICFファイル)の名前を表すオプション・パラメータであり、オブジェクトのアクティブ化ポリシーの指定、およびスケルトン・ファイルと実装ファイルを生成するインタフェース数の制限に使用します。ICFファイルの使用方法は、「ステップ4: メモリー内でのオブジェクトの振る舞いの定義」で説明されています。C++ IDLコンパイラはプラグマ接頭辞の処理を修正するように変更されています。この変更は、オブジェクトのリポジトリIDに影響を与え、_narrowなど、一部の操作に障害が発生する可能性があります。次のコマンド行は、OMG IDLファイルunivb.idlに対して、クライアント・スタブ・ファイル、スケルトン・ファイルおよび初期実装ファイルをスケルトン・ヘッダー・ファイルおよび実装ヘッダー・ファイルとともに生成します。idlコマンドの詳細は、『CORBAプログラミング・リファレンス』を参照してください。Oracle Tuxedo Universityサンプル・アプリケーション用のこれらのファイルの生成の詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。IDLコンパイラには、インタフェースのtieクラス・テンプレートの生成に使用できる-Tコマンド行オプションも用意されています。CORBAアプリケーションでのtieクラスの実装の詳細は、「デレゲーション・ベースのインタフェース実装」を参照してください。
• Tobj_ServantBase::activate_object()およびTobj_ServantBase::deactivate_object()操作内に、オブジェクトのアクティブ化または非アクティブ化に関連するステップを実行するコードを記述します。これには、オブジェクトの永続状態のディスクからの読取りとディスクへの書込みが含まれます。オブジェクトにこれらの操作を実装する場合は、実装ヘッダー・ファイルを編集し、これらの操作を使用する各実装に操作の定義を追加する必要もあります。通常は、IDLコンパイラを呼び出すコマンドで-iオプションを使用して、この実装ファイルを1回のみ生成します。アプリケーションのインタフェースを反復的に修正し、操作のシグネチャなど、それらのインタフェースの操作を変更する場合は、必要なすべての変更を実装ファイルに追加して、それらの変更を反映します。ファクトリの主要機能は、TP::create_object_reference()操作を呼び出すことでオブジェクト参照を作成することです。TP::create_object_reference()操作には次の入力パラメータが必要です。たとえば、Basic Universityサンプル・アプリケーションでは、RegistrarFactoryインタフェースは次の1つの操作のみ指定します。RegistrarFactoryオブジェクトに対するfind_registrar()操作には、Registrarオブジェクトへの参照を作成するためのTP::create_object_reference()操作への次の呼出しが含まれます。
• 次のパラメータは、Registrarオブジェクトのインタフェース・リポジトリIDをタイプ・コードから抽出して指定します。
• 次のパラメータはルーティング基準が使用されないことを指定し、その結果として、Registrarオブジェクトに対して作成されたオブジェクト参照は、そのオブジェクト参照を作成したRegistrarFactoryオブジェクトと同じグループにルーティングされます。
表2-3 サーバー・オブジェクトの作成 サーバー・アプリケーションには、サーバー・オブジェクトのインスタンスが1つのみあります。サーバー・アプリケーションで複数のCORBAオブジェクト実装を管理している場合、記述するServer::initialize()、Server::create_servant()およびServer::release()操作には、これらすべての実装に適用するコードを含める必要があります。Oracle TuxedoドメインのUBBCONFIGファイルのSERVERSセクションで特定のサーバー・アプリケーションのCLOPTパラメータに指定したコマンド行オプションは、Server::initialize()操作にargcおよびargvとして渡されます。サーバー・アプリケーションへの引数の受渡しの詳細は、Oracle Tuxedoアプリケーション実行時の管理を参照してください。サーバー・アプリケーションへの引数の受渡しの例は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。このステップでは、2-7ページの「ファクトリの実装」という項の説明に従ってオブジェクト参照を作成します。このステップでは、TP::create_object_reference()操作への呼出しを含め、ファクトリのOMG IDLインタフェースのインタフェース・リポジトリIDを指定します。次の例では、s_v_fact_ref変数で表されるRegistrarFactoryファクトリへのオブジェクト参照を作成します。次の例は、RegistrarFactoryファクトリをOracle Tuxedoドメインに登録します。パラメータUniversity::_tc_RegistrarFactory->id()に注意してください。これは、TP::create_object_reference()操作で指定したパラメータと同じです。このパラメータは、オブジェクトのOMG IDLインタフェースのインタフェース・リポジトリIDをそのタイプコードから抽出します。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()操作を実装します。Oracle Tuxedoシステム管理者がtmshutdownコマンドを入力すると、TPフレームワークはOracle Tuxedoドメインで実行している各サーバー・アプリケーションのサーバー・オブジェクトで次の操作を呼び出します。停止のリクエストを受信すると、サーバー・アプリケーションは他のリモート・オブジェクトからのリクエストを受信できなくなります。このことはサーバー・アプリケーションの停止順序に影響を与えますが、これは管理タスクです。たとえば、サーバー・プロセスの停止は、2番目のサーバー・プロセスのServer::release()操作に最初のサーバー・プロセスの呼出しが含まれている場合は行わないでください。TP::unregister_factory()操作の呼出しは、Server::release()実装の最初のアクションとして行う必要があります。TP::unregister_factory()操作では、サーバー・アプリケーションのファクトリの登録が解除されます。この操作では、次の入力引数が必要です。次の例は、Basicサンプル・アプリケーションで使用されているRegistrarFactoryファクトリを登録解除します。前のサンプル・コードのグローバル変数s_v_fact_refの使用方法に注意してください。この変数は、RegistrarFactoryオブジェクトを登録したServer::initialize()操作で設定され、ここで再度使用されています。パラメータUnivB::_tc_RegistrarFactory->id()にも注意してください。これは、ファクトリの登録に使用されるインタフェース名とも同じです。ICFファイルにオブジェクトのアクティブ化ポリシーとトランザクション・ポリシーを指定し、TP::deactivateEnable()操作を介してアプリケーションで制御される非アクティブ化を実装します。この項では、Basic Universityサンプル・アプリケーションを例として使用して、両方のメカニズムの実装方法を説明します。
表2-4 アクティブ化ポリシー
• オブジェクトによる自身のTP::deactivateEnable()操作の呼出し。
1. 次の例のようにアプリケーションのOMG IDLファイルを入力として指定してgenicfコマンドを入力することで、ICFファイルを生成します。前のコマンドはファイルuniversity.icfを生成します。
2. ICFファイルを編集し、アプリケーションの各インタフェースのアクティブ化ポリシーを指定します。次の例は、Basic Universityサンプル・アプリケーション用に生成されたICFファイルを示しています。デフォルトのオブジェクトのアクティブ化ポリシーはmethodであり、デフォルトのトランザクション・アクティブ化ポリシーはoptionalです。
3. スケルトン・ファイルと実装ファイルを生成するインタフェース数を制限する場合は、これらのインタフェースを実装する実装ブロックをICFファイルから削除します。前のICFコードを例として使用した場合、RegistrarFactoryインタフェースに対してスケルトン・ファイルと実装ファイルが生成されないようにするには、次の行を削除します。
4.
注意: CORBAサーバー・アプリケーションをコンパイルとリンクするには、buildobjserverコマンドを使用する必要があります。buildobjserver [-o servername] [options]
• -o servernameは、このコマンドで生成されるサーバー・アプリケーションの名前を表します。
• optionsは、buildobjserverコマンドのコマンド行オプションを表します。Universityサンプル・アプリケーションのコンパイルとリンクの詳細は、『CORBA Universityサンプル・アプリケーション・ガイド』を参照してください。buildobjserverコマンドの詳細情報は、Oracle Tuxedoコマンド・リファレンスを参照してください。
注意: Oracle TuxedoソフトウェアをIBM AIX 4.3.3システムで実行している場合は、-brtlコンパイラ・オプションを使用してCORBAアプリケーションを再コンパイルする必要があります。自分またはシステム管理者が、この項で説明されている手順に従ってCORBAサーバー・アプリケーションをデプロイします。Universityサンプル・アプリケーションのビルドとデプロイの詳細は、『CORBA Universityサンプル・アプリケーション・ガイド』を参照してください。
•
• アプリケーションの実行可能ファイルが存在するディレクトリを表すAPPDIR。
4. Oracle Tuxedoドメインで実行されているかOracle Tuxedoドメインに接続されているすべてのマシンにTUXDIR環境変数を設定します。この環境変数は、Oracle Tuxedoソフトウェアがインストールされている場所を指します。
5. 次のコマンドを入力してTUXCONFIGファイルを作成します。コマンド行引数application-ubbconfig-fileは、アプリケーションのUBBCONFIGファイルの名前を表します。このコマンドを実行するには古いTUXCONFIGファイルを削除することが必要な場合があります。Universityサンプル・アプリケーションの構成の詳細は、『CORBA Universityサンプル・アプリケーション・ガイド』を参照してください。CORBAアプリケーションのUBBCONFIGファイルの作成の詳細は、Oracle Tuxedoアプリケーションの設定を参照してください。クライアント・アプリケーションがCORBAオブジェクトに対する操作を呼び出すと、呼出しの結果として例外が返されることがあります。次の有効な例外のみをクライアント・アプリケーションに返すことができます。
•
•
• 発生した例外がTobjS::CreateServantFailedの場合は、メッセージがユーザー・ログに送信されます。例外のコンストラクタで理由の文字列が提供されている場合は、理由文字列もメッセージの一部として書き込まれます。
•
• 発生した例外がTobjS::ActivateObjectFailedの場合は、メッセージがユーザー・ログに送信されます。例外のコンストラクタで理由の文字列が提供されている場合は、理由文字列もメッセージの一部として書き込まれます。
• クライアントによってリクエストされた操作とTobj_ServantBase::deactivate_object()操作はどちらも呼び出されません。
• オブジェクトにalwaysトランザクション・ポリシーがあり、オブジェクトが呼び出されたときにOracle Tuxedoシステムがトランザクションを自動的に開始した場合。この場合、トランザクションはOracle Tuxedoシステムによって自動的にロールバックされます。クライアント・アプリケーションはトランザクションを認識しないため、Oracle Tuxedoシステムは、クライアントがトランザクションを開始した場合に生成されるCORBA:: TRANSACTION_ROLLEDBACK例外ではなく、CORBA::OBJ_ADAPTER CORBAシステム例外を生成します。
• 例外がファイルTobjS_c.hで定義されている場合。この場合、例外はCORBA::BAD_OPERATION例外に変換され、クライアント・アプリケーションに戻されます。また、次のメッセージがユーザー・ログに送信されます。例外がTobjS::IllegalOperationの場合は、次の補足メッセージが書き込まれ、アプリケーションのコーディング・エラーの可能性が開発者に警告されます。この状況は、transactionアクティブ化ポリシーを持つオブジェクトの内部でTP::deactivateEnable()操作が呼び出された場合に発生することがあります。(アプリケーションで制御される非アクティブ化は、トランザクション・バウンド・オブジェクトに対してサポートされません。)
• Oracle Tuxedoシステムがクライアント呼出しに続いて内部システム例外を生成した場合。この場合は、CORBA::INTERNAL例外がクライアント・アプリケーションに返されます。これは通常、オブジェクトがアクティブなプロセスでの重大なシステムの問題を示しています。CORBA標準で定義されているように、クライアントに返信された応答には、操作実装からの結果値、または操作実装でスローされた例外が含まれている場合がありますが、その両方が含まれることはありません。最初の場合(応答ステータス値がNO_EXCEPTIONの場合)では、応答に操作の戻り値とinoutまたはout引数値が含まれます。それ以外(応答ステータス値がUSER_EXCEPTIONまたはSYSTEM_EXCEPTION)の場合は、すべての応答に例外のエンコーディングが含まれます。
• 発生した例外がTobjS::DectivateObjectFailedの場合は、メッセージがユーザー・ログに送信されます。例外のコンストラクタで理由の文字列が提供されている場合は、理由文字列もメッセージの一部として書き込まれます。これらのメッセージは、表2-5に示す、オプションの理由文字列を持つ例外で指定します。
表2-5 例外 サーバー・オブジェクトの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()操作を呼び出して、トランザクションがロールバックされるようにします。これにより、クライアント・アプリケーションが次のいずれかの例外を受け取ります。
• クライアント・アプリケーションがトランザクションを開始した場合、クライアント・アプリケーションはCORBA::TRANSACTION_ROLLEDBACK例外を受け取ります。
• Oracle Tuxedoシステムがトランザクションを開始した場合、クライアント・アプリケーションはCORBA::OBJ_ADAPTER例外を受け取ります。トランザクションが使用されていない場合は、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()操作の実装で、クライアント・リクエストの到着時に次の処理を実行するコードを記述します。
b. サーバントが存在しない場合は、サーバントを作成し、それに対してTobj_ServantBase::activate_object()操作を呼び出します。
c. サーバントが存在する場合は、それに対してTobj_ServantBase::activate_object()操作を呼び出し、クライアント・リクエストに含まれているオブジェクトIDを割り当てます。Oracle Tuxedo CORBAアプリケーションでオブジェクトを実装するには、継承とデレゲーションの2つの主要な方法があります。オブジェクトがPOAスケルトン・クラスを継承しており、したがってCORBAオブジェクトである場合、そのオブジェクトは継承によって実装されているとみなされます。一方、POAスケルトン・クラスからの継承が難しいか実際的ではないCORBAアプリケーションでは、C++オブジェクトを使用する場合もあります。たとえば、POAスケルトン・クラスを継承するために大幅な書換えが必要なC++オブジェクトがある場合です。この非CORBAオブジェクトをCORBAアプリケーションに格納するには、オブジェクトのtieクラスを作成します。このtieクラスはPOAスケルトン・クラスから継承し、tieクラスにはこれらの操作の実装用のレガシー・クラスに委任する1つ以上の操作が含まれます。レガシー・クラスは、デレゲーションによってCORBAアプリケーションで実装されます。デレゲーション・ベースのインタフェース実装を作成するには、IDLコンパイラの-Tコマンド行オプションを使用して、OMG IDLファイルで定義されたインタフェースごとにtieクラス・テンプレートを生成します。CORBAアプリケーションでのtieクラスの使用は、サーバー・オブジェクトでのServer::create_servant()操作の実装方法にも影響します。次の各項では、Oracle Tuxedo製品でのtieクラスの使用方法を詳細に説明し、これらのクラスをインスタンス化するためのServer::create_servant()操作の実装方法も説明します。表2-1に、レガシー・オブジェクトのラッパーとして機能するインタフェースAccountの継承特性を示します。レガシー・オブジェクトには、操作op1の実装が含まれます。tieクラスはop1をレガシー・クラスに委任します。図2-1 インタフェースAccountの継承特性tieクラスは、次の場合には推奨されません。IDLコンパイラは、スケルトンの名前に文字列_tieを追加したC++テンプレート・クラスを生成します。IDLコンパイラは、このテンプレート・クラスをスケルトン・ヘッダー・ファイルに追加します。IDLコンパイラは、tieクラスの実装ファイルを生成しません。このファイルは次のステップで説明するように手動で作成する必要があります。
4. サーバー・オブジェクトのServer::create_servant()操作で、レガシー・オブジェクトをインスタンス化するコードを記述します。
注意: UNIX用のCompaq C++ Tru64コンパイラでtieクラスをコンパイルする場合は、buildobjserverコマンドで使用されるCFLAGSまたはCPPFLAGS環境変数の定義に-noimplicit_includeオプションを含める必要があります。このオプションは、多重定義シンボル・エラーを回避するために必要なサーバー・スケルトン・ヘッダー・ファイル(_s.h)がインクルードされるすべての場所にC++コンパイラがサーバー・スケルトン定義ファイル(_s.cpp)を自動的にインクルードすることを防ぎます。Tru64 C++でのtieクラスなどのクラス・テンプレートとの使用の詳細は、Compaqのマニュアルを参照してください。