bea ホーム | 製品 | dev2dev | support | askBEA
BEA Logo Tuxedo
 ドキュメントのダウンロード   サイトマップ   用語集 
検索
0

Tuxedo CORBA クライアント・アプリケーションの開発方法

 Previous Next Contents Index View as PDF  

動的起動インターフェイスの使い方

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

このトピックの情報は、CORBA C++ および CORBA Java クライアント・アプリケーションに適用されます。DII は、ActiveX クライアント・アプリケーションではサポートされません。

呼び出し方式と DII の概要については、「静的起動と動的起動」を参照してください。

このトピックで説明する CORBA メンバ関数の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

 


DII の使用

CORBA クライアント・アプリケーションから要求を送信する際、静的起動と動的起動を使い分けるのには、それ相応の理由があります。しかし、同じ CORBA アプリケーションで両方の呼び出し方式を使用する必要がある場合もあります。呼び出し方式を選択するには、DII の利点と欠点を理解しておく必要があります。

静的起動と動的起動の大きな違いの 1 つは、どちらも同期 oneway 通信をサポートしているのに対し、動的起動だけが遅延同期通信をサポートしているという点です。

同期通信では、CORBA クライアント・アプリケーションは要求を送信し、応答を取得するまで待機します。応答待ちの間、CORBA クライアント・アプリケーションはほかの作業を行うことができません。遅延同期通信では、CORBA クライアント・アプリケーションは要求を送信し、ほかの作業を自由に行うことができます。CORBA クライアント・アプリケーションは、要求が完了したかどうかを定期的にチェックし、完了した場合は、その要求の結果を利用します。

さらに、DII を使用すると、CORBA クライアント・アプリケーションは、自身が記述された時点で未知であった CORBA オブジェクト型のメソッドを呼び出すことができます。これは、静的起動とは対照的です。静的起動では、CORBA クライアント・アプリケーションには呼び出す CORBA オブジェクトの各型に対するクライアント・スタブが含まれている必要があります。ただし、DII では、コードでクライアント・スタブの作業を実行する必要があるため、プログラミングが難しくなります。

CORBA クライアント・アプリケーションは、DII を使用してより高いパフォーマンスを取得できます。たとえば、CORBA クライアント・アプリケーションは複数の遅延同期要求を同時に送信し、それらの完了を処理できます。要求が異なるサーバ・アプリケーションに送信された場合、この処理を並列に行うことができます。同期クライアント・スタブを使用している場合は、こうした処理を行うことができません。

注記 クライアント・スタブは、最適化機能を備えています。このため、クライアント・スタブは、単一の要求を送信し、即座にブロックしてその要求の応答を取得するときに、DII で達成される応答時間より短い応答を達成できます。

DII は、単なる CORBA クライアント・アプリケーションへのインターフェイスです。CORBA サーバ・アプリケーションからは、静的起動と動的起動はまったく同じに見えます。

 


DII の概念

多くの場合、DII はあるタスクを達成するための複数の方法を提供します。それには、プログラミングの簡素化と性能のトレード・オフが必要となります。この節では、DII の使い方を理解するのに必要な高度な概念について説明します。このトピックの後半には、コード例などの詳細を示します。

この節で説明する概念は次のとおりです。

リクエスト・オブジェクト

リクエスト・オブジェクトは、ある CORBA オブジェクトの 1 つのメソッドの 1 つの呼び出しを表します。同じメソッドに対して 2 つの呼び出しを行う場合、2 つのリクエスト・オブジェクトを作成する必要があります。

メソッドを呼び出すには、そのメソッドが含まれている CORBA オブジェクトへのオブジェクト・リファレンスが必要です。オブジェクト・リファレンスを使用して、リクエスト・オブジェクトを作成し、そのリクエスト・オブジェクトに引数を指定し、要求を送信し、応答を待機して、要求の結果を取得します。

リクエスト・オブジェクトは、次の方法で作成できます。

CORBA メンバ関数の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

要求送信オプション

リクエスト・オブジェクトを作成し、引数、結果の型、および例外の型を追加したら、その要求を CORBA オブジェクトに送信します。要求は、以下の方法で送信できます。

注記 CORBA::Request::send_deferred メンバ関数を使用する場合、対象オブジェクトが呼び出しを発行する CORBA クライアント・アプリケーションと同じアドレス空間に存在するときには、リクエスト・オブジェクトの呼び出しは同期的に動作します。この動作の結果、CosTransaction::Current::suspend オペレーションを呼び出しても、CORBA::BAD_IN_ORDER 例外は発生しません。トランザクションが完了したからです。

CORBA メンバ関数の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

要求結果受信オプション

呼び出しメソッドを使用して要求を送信した場合、結果を取得する方法は 1 つしかありません。その方法とは、リクエスト・オブジェクトの CORBA::Request::env メンバ関数を使用して例外をチェックし、例外が存在しない場合は CORBA::Request::result メンバ関数を使用してリクエスト・オブジェクトから NVList を抽出することです。

遅延同期メソッドを使用して要求を送信した場合、次のいずれかのメンバ関数を使用して結果を取得できます。

CORBA::Request::send_oneway メンバ関数を使用する場合、結果は存在しません。

CORBA メンバ関数の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

 


DII の開発プロセスの概要

クライアント・アプリケーションで DII を使用するための手順は次のとおりです。

手順

説明

1

CORBA インターフェイスをインターフェイス・リポジトリにロードします。

2

呼び出すメソッドが含まれる CORBA オブジェクトへのオブジェクト・リファレンスを取得します。

3

CORBA オブジェクト用のリクエスト・オブジェクトを作成します。

4

DII 要求を送信し、結果を取得します。

5

要求を削除します。

6

DII でインターフェイス・リポジトリを使用します。


 

以降の節では、これらのステップについて詳しく説明し、C++ のコード例を示します。

 


ステップ 1: CORBA インターフェイスのインターフェイス・リポジトリへのロード

DII を使用する CORBA クライアント・アプリケーションを作成する前に、CORBA オブジェクトのインターフェイスをインターフェイス・リポジトリにロードしておく必要があります。CORBA オブジェクトのインターフェイスがインターフェイス・リポジトリにロードされていない場合、BEA Application Builder にはそれらが表示されません。目的の CORBA インターフェイスが [Services] ウィンドウに表示されない場合、 idl2ir コマンドを使用して、CORBA オブジェクトを定義する OMG IDL をインターフェイス・リポジトリにロードします。idl2ir コマンドの構文は次のとおりです。

idl2ir [-f repositoryfile.idl] file.idl

オプション

説明

-f repositoryfile

CORBA インターフェイスの OMG IDL ファイルを指定されたインターフェイス・リポジトリにロードします。CORBA クライアント・アプリケーションがアクセスする BEA Tuxedo ドメインのインターフェイス・リポジトリの名前を指定します。

file.idl

CORBA インターフェイスの定義が記述されている OMG IDL ファイルを指定します。


 

idl2ir コマンドの詳細については、『BEA Tuxedo コマンド・リファレンス』を参照してください。

 


ステップ 2: CORBA オブジェクトのオブジェクト・リファレンスの取得

Bootstrap オブジェクトを使用して、FactoryFinder オブジェクトを取得します。次に、FactoryFinder オブジェクトを使用して、DLL 要求からアクセスする CORBA オブジェクトのファクトリを取得します。Boostrap オブジェクトと FactoryFinder オブジェクトを使用してファクトリを取得する例については、「ステップ 4: CORBA クライアント・アプリケーションの記述」を参照してください。

 


ステップ 3: リクエスト・オブジェクトの作成

CORBA クライアント・アプリケーションが CORBA オブジェクトのメソッドを呼び出す場合、そのメソッド呼び出しのための要求を作成します。この要求はバッファに書き込まれ、CORBA サーバ・アプリケーションに送信されます。CORBA クライアント・アプリケーションがクライアント・スタブを使用する場合、この処理は透過的に発生します。DII を使用する クライアント・アプリケーションは、リクエスト・オブジェクトを作成し、その要求を送信する必要があります。

CORBA::Object::_request メンバ関数の使い方

次の C++ の コード例に、CORBA::Object::_request メンバ関数の使い方を示します。

Boolean          aResult;
CORBA::ULong long1 = 42;
CORBA::Any in_arg1;
CORBA::Any &in_arg1_ref = in_arg1;

in_arg1 <<= long1;
// 短縮形式を使用して要求を作成
Request_ptr reqp = anObj->_request(“anOp”);
// 引数操作ヘルパ関数を使用
reqp->add_in_arg() <<= in_arg1_ref;
// boolean 型の結果が必要
reqp->set_return_type(_tc_boolean);
// 結果用の場所を提供
CORBA::Any::from_boolean boolean_return_in(aResult);
reqp->return_value() <<= boolean_return_in;
// invoke を実行
reqp->invoke();
// エラーがないので、戻り値を取得
CORBA::Any::to_boolean boolean_return_out(aResult);
reqp->return_value() >>= boolean_return_out;

CORBA::Object::create_request メンバ関数の使い方

CORBA::Object::create_request メンバ関数を使用してリクエスト・オブジェクトを作成する場合、空の NVList を作成し、その NVList に引数を 1 つずつ追加します。次に、リクエスト・オブジェクトを作成し、完成した NVList を引数としてそのリクエストに受け渡します。

リクエスト・オブジェクトの引数の設定

リクエスト・オブジェクトの引数は、名前付き/値オブジェクトを格納する NVList オブジェクトで表されます。このリスト内のオブジェクトの追加、削除、問い合わせを行うためのメソッドが用意されています。CORBA::NVList の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

CORBA::NamedValue メンバ関数による入力引数と出力引数の設定

CORBA::NamedValue メンバ関数は、要求の入力引数と出力引数を表すために使用する名前付き/値オブジェクトを指定します。名前付き/値オブジェクトは、リクエスト・オブジェクトの引数として使用されます。また、CORBA::NamedValue のペアは、CORBA クライアント・アプリケーションに返される要求の結果を表すためにも使用されます。名前付き/値オブジェクトの名前プロパティは文字列で、値プロパティは CORBA Any によって表されます。

CORBA::NamedValue メンバ関数の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

CORBA::Object::create_request メンバ関数の使用例

次の C++ のコード例に、CORBA::Object::create_request メンバ関数の使い方を示します。

CORBA::Request_ptr         reqp;
CORBA::Context_ptr ctx;
CORBA::NamedValue_ptr boolean_resultp = 0;
Boolean boolean_result;
CORBA::Any boolean_result_any(CORBA::_tc_boolean, & boolean_result);
CORBA::NVList_ptr arg_list = 0;
CORBA::Any arg;
// デフォルト・コンテキストを取得
orbp->get_default_context(ctx);
// 結果の名前付き値ペアを作成
(void) orbp->create_named_value(boolean_resultp);
CORBA::Any *tmpany = boolean_resultp->value();
*tmpany = boolean_result_any;

arg.replace(CORBA::_tc_long, &long_arg, CORBA_FALSE)
// NVList を作成
orbp->create_list(1, arg_list);

// IN 引数をリストに追加
arg_list->add_value(“arg1”, arg, CORBA::ARG_IN);

// 長い形式を使用して要求を作成
anObj->_create_request (ctx,
“anOp”,
arg_list,
boolean_resultp,
reqp,
CORBA::VALIDATE_REQUEST );
// invoke を実行
reqp->invoke();

CORBA::NamedValue_ptr result_namedvalue;
Boolean aResult;
CORBA::Any *result_any;
// 結果を取得
result_namedvalue = reqp->result();
result_any = result_namedvalue->value();
// any から Boolean を抽出
*result_any >>= aResult;

 


ステップ 4: DII 要求の送信と結果の取得

要求は、使用する通信の方式に応じて複数の方法で呼び出すことができます。この節では、CORBA メンバ関数を使用して要求の送信と結果の取得を行う方法について説明します。

同期要求

同期通信を行う場合、CORBA::Request::invoke メンバ関数は要求を送信し、その応答が CORBA クライアント・アプリケーションに返されるまで待機します。CORBA::Request::result メンバ関数は、戻り値を表す名前付き/値オブジェクトへのリファレンスを返すために使用します。結果を取得したら、要求に格納されている NVList から値を読み出します。

遅延同期要求

要求の送信用として、非ブロッキング・メンバ関数の CORBA::Request::send_deferred も用意されています。このメンバ関数を使用すると、CORBA クライアント・アプリケーションは要求を送信し、CORBA::Request::poll_response メンバ関数を使用して応答が利用可能であるかどうかを調べることができます。CORBA::Request::get_response メンバ関数は、応答が利用可能になるまでブロックします。

次のコード例に、CORBA::Request::send_deferredCORBA::Request::poll_response、および CORBA::Request::get_response メンバ関数の使い方を示します。

request->send_deferred ();

if (poll)
{
for ( int k = 0 ; k < 10 ; k++ )
{
CORBA::Boolean done = request->poll_response();
if ( done )
break;
     }
}
request->get_response();

oneway の要求

oneway の要求を送信するには、CORBA::Request::send_oneway メンバ関数を使用します。oneway の要求では、CORBA サーバ・アプリケーションから応答が返されません。CORBA::Request::send_oneway メンバ関数の詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』を参照してください。

次のコード例に、CORBA::Request::send_oneway メンバ関数の使い方を示します。

request->send_oneway();

複数の要求

CORBA::Request::send_multiple_requests_deferred メンバ関数を使用してリクエスト・オブジェクトのシーケンスを送信する場合、CORBA::ORB::poll_responseCORBA::ORB::poll_next_response、CORBA::ORB::get_response、および CORBA::ORB::get_next_response メンバ関数を使用すると、CORBA サーバ・アプリケーションが各要求に対して送信する応答を取得できます。

CORBA::ORB::poll_response メンバ関数と CORBA::ORB::poll_next_response メンバ関数を使用すると、CORBA サーバ・アプリケーションから応答を取得したかどうかを調べることができます。これらのメンバ関数は、少なくとも 1 つの応答が利用可能な場合は 1 を返し、利用可能な応答が存在しない場合は 0 を返します。

CORBA::ORB::get_response メンバ関数と CORBA::ORB::get_next_response メンバ関数を使用すると、応答を取得できます。利用可能な応答が存在しない場合、これらのメンバ関数は応答を取得するまでブロックします。CORBA クライアント・アプリケーションがブロックしないようにする場合は、最初に CORBA::ORB::poll_next_response メンバ関数を使用して応答が利用可能かどうかを調べてから、CORBA::ORB::get_next_response メソッドを使用してその結果を取得します。

また、CORBA::Request::send_multiple_requests_oneway メンバ関数を使用すると、複数の oneway 要求を送信できます。

次のコード例に、CORBA::Request::send_multiple_requests_deferredCORBA::Request::poll_next_response、および CORBA::Request::get_next_response メンバ関数の使い方を示します。

CORBA::Context_ptr           ctx;
CORBA::Request_ptr requests[2];
CORBA::Request_ptr request;
CORBA::NVList_ptr arg_list1, arg_list2;
CORBA::ULong i, nreq;
CORBA::Long arg1 = 1;
Boolean aResult1 = CORBA_FALSE;
Boolean expected_aResult1 = CORBA_TRUE;
CORBA::Long arg2 = 3;
Boolean aResult2 = CORBA_FALSE;
Boolean expected_aResult2 = CORBA_TRUE

try
{
orbp->get_default_context(ctx);

populate_arg_list ( &arg_list1, &arg1, &aResult1 );

nreq = 0;

anObj->_create_request ( ctx,
“Multiply”,
arg_list1,
0,
requests[nreq++],
0);

populate_arg_list ( &arg_list2, &arg2, &aResult2 );

anObj->_create_request ( ctx,
“Multiply”,
arg_list2,
0,
requests[nreq++],
0 );

// 要求シーケンス変数を宣言...
CORBA::ORB::RequestSeq rseq ( nreq, nreq, requests, CORBA_FALSE );

orbp->send_multiple_requests_deferred ( rseq );
for ( i = 0 ; i < nreq ; i++ )
{
requests[i]->get_response();
}
// ここで結果をチェック
if ( aResult1 != expected_aResult1 )
{
cout << “aResult1=” << aResult1 << “ different than expected: “ <<
expected_aResult1;
}
if ( aResult2 != expected_aResult2 )
{
cout << “aResult2=” << aResult2 << “ different than expected: “ <<
expected_aResult2;
}
aResult1 = CORBA_FALSE;
aResult2 = CORBA_FALSE;
// 同じ引数リストを使用して、数値を再び乗算
// 今度は応答をポーリング

orbp->send_multiple_requests_deferred ( rseq );

// ここで応答をポーリング
for ( i = 0 ; i < nreq ; i++ )
{
// 最大 10 回ランダムにポーリング
for ( int j = 0 ; j < 10 ; j++ )
{
CORBA::Boolean done = requests[i]->poll_response();

if ( done ) break;
}
}
// ここで応答を実際に所得
for ( i = 0 ; i < nreq ; i++ )
{
requests[i]->get_response();
}
// ここで結果をチェック
if ( aResult1 != expected_aResult1 )
{
cout << “aResult1=” << aResult1 << “ different than expected: “ <<
expected_aResult1
}
if ( aResult2 != expected_aResult2 )
{
cout << “aResult2=” << aResult2 << “ different than expected: “ <<
expected_aResult2;
}
aResult1 = CORBA_FALSE;
aResult2 = CORBA_FALSE;
// 同じ引数リストを使用して、数値を再び乗算
// get_next_response を呼び出し、応答を待機
orbp->send_multiple_requests_deferred ( rseq );

// 応答を取得するまでポーリングし、get_next_response を使用して取得
for ( i = 0 ; i < nreq ; i++ )
{
CORBA::Boolean res = 0;

while ( ! res )
{
res = orbp->poll_next_response();
}
orbp->get_next_response(request);
CORBA::release(request);
}
// ここで結果をチェック
if ( aResult1 != expected_aResult1 )
{
cout << “aResult1=” << aResult1 << “ different than expected: “ <<
expected_aResult1;
}
if ( aResult2 != expected_aResult2 )
{
cout << “aResult2=” << aResult2 << “ different than expected: “ <<
expected_aResult2;
}
static void populate_arg_list (
CORBA::NVList_ptr ArgList,
CORBA::Long * Arg1,
CORBA::Long * Result )
{
CORBA::Any any_arg1;
CORBA::Any any_result;

(* ArgList) = 0;
orbp->create_list(3, *ArgList);

any_arg1 <<= *Arg1;
any_result.replace(CORBA::_tc_boolean, Result, CORBA_FALSE);
(*ArgList)->add_value(“arg1”, any_arg1, CORBA::ARG_IN);
(*ArgList)->add_value(“result”, any_result, CORBA::ARG_OUT);

return;
}

 


ステップ 5: 要求の削除

要求が正常に完了したことが通知されたら、既存の要求を削除するか、または次の呼び出しでその一部を再利用するかを決定する必要があります。

要求全体を削除するには、削除する要求に対して CORBA::Release(request) メンバ関数を使用します。このオペレーションにより、要求に関連するすべてのメモリが解放されます。遅延同期通信を使用して発行された要求を削除する場合、その要求が完了していないときはその要求がキャンセルされます。

 


ステップ 6: DII でのインターフェイス・リポジトリの使い方

CORBA クライアント・アプリケーションは、その作成時に未知であったオブジェクトの要求を作成、設定、および送信できます。そのために、CORBA クライアント・アプリケーションはインターフェイス・リポジトリを使用して、要求を作成および設定するために必要な情報を取得します。CORBA クライアント・アプリケーションは、そのインターフェイスのクライアント・スタブを持っていないので、DII を使用して要求を送信します。

このテクニックは未知の型の CORBA オブジェクトのオペレーションを呼び出すのに役立ちますが、インターフェイス・リポジトリとの対話によるオーバーヘッドのため、パフォーマンスが問題となります。このタイプの DII 要求は、オブジェクトを参照する CORBA クライアント・アプリケーションを作成する場合か、または管理ツールの CORBA クライアント・アプリケーションを作成する場合に使用を検討します。

DLL 要求でインターフェイス・リポジトリを使用するための手順は次のとおりです。

  1. CORBA.hORB_INCLUDE_REPOSITORY を、BEA Tuxedo システム内でのインターフェイス・リポジトリ・ファイルの格納場所に設定します。

  2. Bootstrap オブジェクトを使用して、インターフェイス・リポジトリ・オブジェクトを取得します。このオブジェクトには、特定の BEA Tuxedo ドメイン内のインターフェイス・リポジトリへのリファレンスが含まれています。インターフェイス・リポジトリへのリファレンスを取得したら、そのインターフェイス・リポジトリをルートから参照できます。

  3. CORBA::Object::_get_interface メンバ関数を使用して、目的の CORBA オブジェクトをインプリメントする CORBA サーバ・アプリケーションと通信します。

  4. CORBA::InterfaceDef_ptr を使用して、インターフェイス・リポジトリに格納されている CORBA インターフェイスの定義を取得します。

  5. FullInterfaceDescription オペレーションで、目的のオペレーション用の OperationDescription を検索します。

  6. OperationDescription からリポジトリ ID を取得します。

  7. OperationDescription で返されたリポジトリ ID を使用して CORBA::Repository::lookup_id を呼び出して、インターフェイス・リポジトリ内の OperationDef を検索します。この呼び出しにより、包含オブジェクトが返されます。

  8. 包含オブジェクトを OperationDef にナロー変換します。

  9. OperationDef 引数と CORBA::ORB::create_operation_list メンバ関数を使用して、オペレーションの引数リストを作成します。

  10. オペレーション・リスト内の引数値を設定します。

  11. ほかの要求と同じように、要求を送信して結果を取得します。このトピックで説明した任意のオプションを使用して、要求を送信して結果を取得できます。

 

Back to Top Previous Next
Contact e-docsContact BEAwebmasterprivacy