9.4.2 TPBrokerV5を除くORBクライアントアプリケーションの作成手順
TPBrokerV5を除くORBクライアント(CORBA2.1準拠のCORBAクライアントまたはTMS-4V/SP Object Access,TPBrokerV3)からEJBアプリケーション(Cosminexus)のEJBをCORBA通信によって呼び出す方式を次の図に示します。
この方式ではIDLとして次のデータ型/データ定義だけ使用できます。
long,unsigned long,string,sequence<octet>,struct
(1) インタフェース設計手順
アプリケーションサーバ側の通信インタフェースはEJBのリモートインタフェースとして,ORBクライアント側の通信インタフェースはCORBAのIDLとしてそれぞれ記述する必要があります。
リモートインタフェースおよびIDLの設計手順の概略は次のようになります。
-
インタフェースのベースとなるIDL定義を作成
-
IDLに合わせてEJBのリモートインタフェースを作成
-
ctmjava2idlコマンドの出力によって,IDLの構造体メンバの並びを補正
-
string,sequence<octet>,structのIDL定義を変更
各手順の詳細について説明します。
(a) インタフェースのベースとなるIDL定義の作成
インタフェースのベースとなるIDL定義は,次の注意事項を考慮して作成してください。
-
out/inout引数は使用できません(戻りデータとしてはリターン値を使用します。戻りデータが複数ある場合はstructにまとめてください)。
-
ユーザ例外は使用しないでください。
-
structのメンバはlong,unsigned long,string,sequence<octet>だけを使用してください。
-
#pragmaは使用しないでください。
(b) リモートインタフェースの作成
ベースとなるIDL定義の作成後,それを基にEJBのリモートインタフェースを作成します。
このとき,対応するメンバ名は,IDLとリモートインタフェースで同じにしてください。
また,IDLのmoduleは,Javaのパッケージに対応します。
サポートするデータ型のマッピングを次の表に示します。
データ型 |
IDL |
リモートインタフェース |
---|---|---|
整数 |
long |
int |
unsigned long※1 |
||
文字列 |
string※3 |
byte[]※2 |
バイナリ |
sequence<octet>※3 |
byte[] |
構造体 |
struct |
class(Serializableを実装) |
IDLの記述例
struct AAA { long longData; string<4> strData; unsigned long ulongData; sequence<octet> octseqData; };
リモートインタフェースの記述例
public class AAA implements java.io.Serializable { public int longData; public byte[] strData; public int ulongData; public byte[] octSeqData; };
(c) ctmjava2idlコマンドの出力によって,IDLの構造体メンバの並びを補正
EJBに対するCORBA通信では,IDLのstruct内のメンバの並びをJavaのSerializableの仕様に沿った形で並べ替える必要があります。ここで,IDL上での適正なstructメンバの並びを確認するために,ctmjava2idlコマンドを使用します。
ctmjava2idlコマンドは,EJBのリモートインタフェースをIDL定義へ変換するコマンドです。
- <例:表9-9の例で示した構造体AAAを使用した場合の手順>
-
-
AAAに対応するJavaソースプログラム(AAA.java)をコンパイルする。
% javac AAA.java
-
生成されたクラスファイル(AAA.class)をctmjava2idlコマンドに適用する。
% ctmjava2idl AAA.class
-
標準出力に出力されたIDL定義を基に,ベースとなるIDLを修正する。
ctmjava2idlコマンドによるIDLの構造体メンバの並びの変更例を,次の図に示します。
図9‒5 ctmjava2idlコマンドによるIDLの構造体メンバの並びの変更の例 - 参考
-
structメンバの並べ替えルール
リモートインタフェース上でのデータ型とメンバ名によって順番が決定されます。
-
intのメンバはbyte[]のメンバより先に並びます。
-
int型のメンバ同士では,メンバ名によって文字列順に並びます。
-
byte[]型のメンバ同士では,メンバ名によって文字列順に並びます。
-
int型のメンバ同士,および,byte[]のメンバ同士はctmjava2idlコマンドで出力したIDL定義のstructに定義されている順番に並べます。
-
-
(d) string,sequence<octet>,structのIDL定義を変更
ORBクライアントからのEJB呼び出しではstring,sequence<octet>,structのデータを特定の形式の構造体に変更して扱う必要があります(long/unsigned longはそのまま)。
- ORBクライアント側送信データの形式
-
ORBクライアント側からEJBに対し送信するデータに対しては,次のような形式に変更します。
(例:「図9-6 EJB向けのIDLへの変換例」のinvokeメソッドのin引数StringValue,OctSeqValue,AAARequest)
struct 任意の構造体名 { long VALUE_TAG; string REPOSITORY_ID; データ本体; }
ただしstruct内のstring,sequence<octet>メンバに対しては,上記構造体を使用する代わりに,次の構造体を各データの直前に配置するようにしてください。
(例:「図9-6 EJB向けのIDLへの変換例」のAAARequestのメンバtag1およびtag2)
struct ValueTag { long VALUE_TAG; string REPOSITORY_ID; }
ORBクライアント側のプログラム実装では,VALUE_TAG/REPOSITORY_IDに値を設定する必要があります。
- ORBクライアント側受信データの形式
-
戻り値としてのstructそのものに対しては,送信データと同様の形式に変更します。
(例:「図9-6 EJB向けのIDLへの変換例」のAAAReply)
struct 任意の構造体名 { long VALUE_TAG; string REPOSITORY_ID; データ本体; }
struct内のメンバの内,最初に出現したstring,sequence<octet>に対して次の構造体をデータの直前に配置してください。
(例:「図9-6 EJB向けのIDLへの変換例」のAAAReplyのメンバtag1)
struct ValueTag { long VALUE_TAG; string REPOSITORY_ID; }
二つ目以降に出現したstring,sequence<octet>メンバに対しては,次の構造体を各データの直前に配置してください。
(例:「図9-6 EJB向けのIDLへの変換例」のAAAReplyのメンバtag2 。手前にsequence<octet>のメンバがあるため,ValueTagでなくReplyTagになる。)
struct ReplyTag { long VALUE_TAG; long INDIRECTION_TAG; long INDIRECTION; }
受信データとしては,VALUE_TAG/REPOSITORY_ID/ INDIRECTION_TAG/INDIRECTIONの値は無視してください。
- IDLの変更例
-
IDLの変更例を次の図に示します(対応するリモートインタフェースも示します)。
図9‒6 EJB向けのIDLへの変換例
(2) 通信処理に関するプログラム実装
プログラム実装として追加すべき処理について説明します。
(a) ORBクライアント送信データでのVALUE_TAG,REPOSITORY_ID設定
string/sequence<octet>/structに関しては,ORBクライアント側からEJBに対し送信する場合には,送信前にデータ本体以外に,VALUE_TAG,REPOSITORY_IDにも値を設定してください。
- VALUE_TAG
-
常に固定値(0x7fffff02)を設定してください。
- REPOSITORY_ID
-
- string/sequence<octet>の場合
-
固定値(“RMI:[B:0000000000000000”)を設定してください。
- structの場合
-
リポジトリIDはstructの名称・構造により異なってくるため,ctmjava2idlコマンドの出力結果からリポジトリIDを取得してください。ctmjava2idlコマンド出力結果の「#pragma ID クラス名」の行,“RMI:〜”部分がリポジトリIDです。次の図の場合,"RMI:AAA:D7A0D1FA6D5A19A3:86B2BC1FA4F5362A"がAAAのリポジトリIDになります。
図9‒7 リポジトリIDの例
また,COBOLのマップファイルでREPOSITORY_ID部の長さを指定する場合,次の値を指定してください。
- string/sequence<octet>の場合
-
23文字以上
(固定値(“RMI:[B:0000000000000000”)の文字数以上)
- structの場合
-
ctmjava2idlコマンドの出力結果から取得したリポジトリIDの文字数以上
ORBクライアント側受信データに関しては,データ本体以外の情報(VALUE_TAGなど)は無視してください。
「図9-6 EJB向けのIDLへの変換例」のXXX::invoke()に対応したVALUE_TAG,REPOSITORY_IDの設定例を次に示します。
(b) IDLのstringに対するEJB上での取り扱い
EJB側では文字列をbyte[]として送受信するため,必要に応じてJavaのStringとの相互変換をしてください。
受信したbyte[]をそのままJavaのStringに変換した場合,終端に’¥0’が付加された状態になるため,文字列長を取得すると,文字数が1文字分多い値が得られます。必要であれば終端の’¥0’を削除してください。
byte[]に文字列を設定する場合は,文字列の終端としてプログラムで明示的に’¥0’を付加してください。’¥0’で終了していないデータをIDLのstringとして返した場合,受信側でエラーになるおそれがあります。
IDLでstringの最大長を指定している場合,終端文字’¥0’はその最大長に含まれないため,byte[]のサイズとしては最大長+1を確保してください。
(c) EJBでのNULL
Javaからの戻り値のclass/byte[]に,nullオブジェクトを使用しないでください。
(3) 文字列化オブジェクトリファレンスの生成
ORBクライアントからORBゲートウェイに接続するIOR文字列ファイルの取得手順について説明します。
-
ctmstartgwコマンドに-CTMIDLConnectオプションを指定してORBゲートウェイを開始します。
-
ORBクライアントから呼び出すJ2EEアプリケーションをデプロイしてから開始します。
-
ctmgetiorコマンドを実行し,IOR文字列ファイルを取得します。
なお,IOR文字列が記述されたファイルの再生成については,次の点に注意してください。
- EJBのリモートインタフェースとCORBAネーミングサービスの登録名称,サーバのIPアドレス,または,ORBゲートウェイの受信ポート番号を変更しない場合
-
再生成する必要はありません。
ctmstartgwコマンドに「-CTMIDLConnect 0」を指定してORBゲートウェイを開始すると,ctmgetiorコマンドによってIOR文字列は取得できませんが,アプリケーションやORBゲートウェイの開始時間を短縮できます。
- EJBのリモートインタフェース,CORBAネーミングサービスの登録名称,サーバのIPアドレス,または,ORBゲートウェイの受信ポート番号を変更する場合
-
文字列化オブジェクトリファレンスの生成手順1からやり直す必要があります。