WebOTX Manual V11.1 (第6版) 目次を表示 |
図1.2.1.1-1
図1.2.1.1-2
ファクトリあり
|
ファクトリなし
|
|
---|---|---|
サーバオブジェクトの遅延生成
|
可能
|
不可能
|
ステートフルオブジェクト
|
利用可能
|
利用不可能
|
クライアント管理ライブラリ
|
利用可能
|
利用不可能
|
既存クライアントAPの利用
|
ファクトリのコーディングが必要
|
変更不要
|
通信量
|
サーバオブジェクトの生成/消滅のオペレーションコールが余計にある
|
通常のCORBAアプリケーションと同じ
|
interface foo // ステートフルオブジェクト { void op(in string a, out in string a); }; interface barFactory { foo creObj(); ^^^ ^^^^^^^^ | +------------------------ オペレーション名は任意です +----------------------------------- ステートフルオブジェクトのインタフェース void relObj(in foo obj); ^^^^ ^^^^^^ ^^^^^^^^^^ | | +----------------------- 上記メソッドの返却値を設定。 | | これ以外の値は渡してはいけない | +------------------------------ オペレーション名は任意です +----------------------------------- 返却値はvoid固定です };
説明
|
C++言語
|
Java言語
|
|
---|---|---|---|
DLL読み込み時/解放時
|
サーバアプリケーションDLL(コンポーネント)を読み込んだ時と解放時に特定の関数呼び出します。
|
○
|
×
|
プロセス起動時/終了時
|
プロセス初期化中および終了処理中に、特定のクラスファイル(InitTerm.class)のメソッドを呼び出します。
|
×
|
○
|
サーバオブジェクト生成時/解放時
|
サーバオブジェクト生成後と解放前に特定のインタフェースを実装している時に呼び出します。
|
×
|
○
|
常駐オブジェクト生成時/解放時
|
常駐オブジェクトを生成後と解放前に特定の関数を定義している時(あるいは特定のインタフェースを実装している時)に呼び出します。
|
○
|
○
|
オペレーション毎の常駐オブジェクトの呼び出し
|
各オペレーションが呼び出されたときや、正常終了、異常終了、サーバアプリケーション例外、クライアントとのセション切断時に特定の関数を定義している時(あるいは特定のインタフェースを実装している時)に呼び出します。
|
○
|
○
|
アプリケーション例外時
|
サーバアプリケーション処理中に例外したとき、WO_BASEインタフェースからの派生の時に限りOnTPSAbort()を呼び出します。
|
○
|
○
|
クライアントとのセション切断時
|
サーバアプリケーション処理中に例外したとき、WO_BASEインタフェースからの派生の時に限りOnTPSDisconnect()を呼び出します(ステートフルの時のみ)。
|
○
|
○
|
単一オペレーション完結型
|
サーバはステートレスが利用できるので、クライアント台数に依存せず最小限度のメモリ消費で実行可能になる。欠点としては、各オペレーションの引数が多くなる傾向が強く、コーディングが煩雑になることがある。
このとき、ステートレスを利用した時はクライアント切断イベントに対する処理は必要ありません。
|
---|---|
複数オペレーション完結型
|
サーバはステートフルのみ利用可能。同時接続クライアント数に応じてサーバオブジェクトも生成されるのでメモリ消費量が多くなることある。単一オペレーションとは異なり、前の状態をオブジェクト変数に保持できるので各オペレーションの引数は最小限度で済むのでコーディングは「単一オペレーション完結型」より簡素になることが多いです。
このとき、ステートフルを利用するのでクライアント切断イベントに対する処理が必要になります。
|
上記の複合型
|
上記二つの注意点を良く読んでください。
|
アプリケーション形態
|
リッチクライアント(Rich Client)
|
シンクライアント(Thin Client)
|
---|---|---|
・Visual C++クライアント
高速。Windowsのみ。VC++ランタイムの設定が必要。
・Javaアプリケーション
Windows、Unixで実行可能。Java実行環境(JDKなど)とランタイムが必要。
|
・JSP/Java Servlet
基本的にOSは選ばないが、WebサーバはJSP/Java
Servletに対応している必要があります。クライアントはHTMLを表示するので、クライアントのGUIはHTMLで表現できる範囲内となります。
・Java Applet
一般的なWebサーバなら利用可能。GUIはリッチクライアント並みに凝ったものが作成可能。ただし、クライアントのWebブラウザの種類とバージョンを統一しないと画面が乱れることがあります。
|
|
利用端末数
|
サーバのライセンス数に関わってくるので適切な台数を見積もる必要があります。
|
言語の選択
|
C++言語またはJava言語
|
|
---|---|---|
同時利用端末数の見積もり
|
初期設定は100端末です。無闇に多く取ると無駄にメモリを消費します。利用規模に合わせて最適値を設定してください。
|
|
スレッド
|
アパートメントモデル
|
フリースレッドモデル
|
・ スレッド毎にオブジェクトを生成する。
・ スレッド数が多くなるとそれだけたくさんのオブジェクトを生成する。
・ スレッドをまたがっての呼び出しが無いので、グローバル変数のスレッド間排他制御が必要。
|
・ 1からスレッド数まで任意の数までのオブジェクトを生成する。
・ スレッド数が多くなってもオブジェクトの生成は指定した数以上は生成しない。
・ ステートレスの場合、スレッドをまたがっての呼び出しがあるので、グローバル変数はもちろん、オブジェクト変数をアクセスする時もスレッド間排他制御が必要。ステートフルの場合は、グローバル変数の排他制御が必要。
|
メリット
|
デメリット
|
|
---|---|---|
テスト用の実行環境
|
ほぼ実業務と同じ評価ができる
|
実行環境にWebOTXシステムを二つ以上起動しなければならない
|
利用アプリケーション
|
ポート番号の指定方法
|
初期値
|
備考
|
---|---|---|---|
IIOPリスナ
|
運用管理ツールで設定
|
5151
|
-
|
OLFTPリスナ
|
運用管理ツールで設定
|
5251
|
-
|
クライアント管理ライブラリ
|
運用管理ツールで設定
|
5220
|
-
|
>PATH=${PATH}:/opt/WebOTX/ObjectBroker/bin >PATH=${PATH}:/opt/WebOTX/dev/bin >PATH=${PATH}:/opt/WebOTX/bin >export PATH : : >LD_LIBRARY_PATH=/opt/WebOTX/ObjectBroker/lib:/opt/WebOTX/dev/lib >export LD_LIBRARY_PATH : : >CLASSPATH=/opt/WebOTX/modules/jsocks.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/modules/wo-orb110.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/modules/omgorb110.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/dev/javalib/svsimj.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/dev/javalib/WOTXBS90.jar >export CLASSPATH :
1: module sample 2: { 3: interface LoopBackSample : WO_Base // (サンプルではWO_Baseからの派生はありません) 4: { 5: long LoopBack(in string inputChar, out string outputChar); 6: long LowerCase(in string inputChar, out string outputChar); 7: long UpperCase(in string inputChar, out string outputChar); 8: }; 9: };一行目のmoduleはモジュールを宣言するときに記述します。interfaceを指定する場合、module定義の指定は必須です。三行目のinterfaceはインタフェースを宣言するときに記述します。続けてインタフェース名を記述します。これがJavaのクラス名になります。その後ろの : WO_BaseはWO_Baseインタフェースからの派生を意味しています。WO_BaseはWebOTX専用のインタフェースで、このインタフェースから派生することにより、アプリケーション例外時の呼出し(OnTPSAbort())やクライアント切断時の呼出し(OnTPSDisconnect())が行われます。これらの機能が不要なときは記述しなくても結構です。 WO_Baseの定義はWebOTXをインストールしたディレクトリ配下にwobase.idlとして定義しています。 五行目以降はオペレーションの宣言です。オペレーションの書式はJavaのインスタンスメソッドと同じように記述します。 Javaのインスタンスメソッドの定義と異なるのは、各引数に入出力属性を付けることです。上記例ではin属性とout属性(出力属性)を使用していますが、このほかにも、inout属性(入出力属性)があります。 このようにして出来上がったIDLファイルをIDLコンパイラに入力してスタブファイル、スケルトンファイルを作成します。詳しいIDLの構文やJava言語マッピングについてはObject Broker のマニュアルを参照してください。 なお、IDLファイルのファイル名の拡張子は必ず .idl としてください。この例題では、loopback.idlとして説明します。 IDLファイルを作成しましたら、次にIDLコンパイラを実行してスタブファイルとスケルトンファイル、Holderクラスファイル、Helperクラスファイルを生成します。 スタブファイルとは、クライアントアプリケーションがサーバオブジェクトをアクセスするためのアクセスクラスを定義しているファイルのことです。スケルトンファイルとは、ORBからサーバアプリケーションを呼び出すためのベースとなるクラスを定義したファイルのことです。 Holderファイルはoutおよびinoutパラメータモードをサポートするためのクラスを定義しています。 HelperクラスはAny型への挿入と取り出し、ストリームからの読み込みと書き出しに使われます。 WebOTXでは、上記ファイルのほかに以下の機能を定義したファイルが必要になります。
i2j -i -lstub <IDLファイル名> (woi2jとは異なり、"loopback.idl"のように.idlも必要です) ^^ ^^^^^^ | +-----ローカルスタブを使用。 +-----------ifファイルの生成を行います。WebOTXに登録するために必須のオプションです。※UNIX系OSの場合、以下の様にi2j.shを使用してください。
/opt/WebOTX/ObjectBroker/bin/i2j.sh -i -lstub <IDLファイル名>また、WO_Baseを派生している場合は以下のオプションを指定してください。この場合、事前にwobase.idlをカレントディレクトリにコピーしておく必要があります。wobase.idlは、WebOTX Developer (for CORBA Application)をインストールしたディレクトリ配下のidlfilesディレクトリにあります。
i2j -i -lstub -rpjp.co.nec.WebOTX -Rwobase.idl <IDLファイル名> (.idlも必要) ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ | +-----wobase.idl を参照します。 | WO_Baseを使用するために必須のオプションです。 +----------IDL定義が jp.co.nec.WebOTXパッケージに置かれているものとして生成します。 WO_Baseを使用するために必須のオプションです。※UNIX系OSの場合、以下の様にi2j.shを使用してください。
/opt/WebOTX/ObjectBroker/bin/i2j.sh -i -lstub -rpjp.co.nec.WebOTX -Rwobase.idl <IDLファイル名>コマンドを実行すると以下のファイルを生成します。
1: module sample 2: { 3: interface LoopBackSample : WO_Base 4: // (サンプルではWO_Baseからの派生はありません) 5: { 6: long LoopBack(in string inputChar, out string outputChar); 7: long LowerCase(in string inputChar, out string outputChar); 8: long UpperCase(in string inputChar, out string outputChar); 9: }; 10: 11: interface WO_Factory_LoopBackSample : WO_BaseFactory 12: // (サンプルではWO_BaseFactoryからの派生はありません) 13: { 14: LoopBackSample CreateServerObject(); 15: void ReleaseServerObject(in LoopBackSample obj); 16: }; 17: };一行目のmoduleはモジュールを宣言するときに記述します。interfaceを指定する場合、module定義の指定は必須です。三行目のinterfaceはインタフェースを宣言するときに記述します。続けてインタフェース名を記述します。これがJavaのクラス名になります。その後ろの : WO_BaseはWO_Baseインタフェースからの派生を意味しています。WO_BaseはWebOTX専用のインタフェースで、このインタフェースから派生することにより、アプリケーション例外時の呼出し(OnTPSAbort())やクライアント切断時の呼出し(OnTPSDisconnect())が行われます。これらの機能が不要なときは記述しなくても結構です。 WO_Baseの定義はWebOTXをインストールしたディレクトリ配下にwobase.idlとして定義しています。 六行目から八行目はオペレーションの宣言です。オペレーションの書式はJavaのインスタンスメソッドと同じように記述します。 Javaのインスタンスメソッドの定義と異なるのは、各引数に入出力属性を付けることです。上記例ではin属性とout属性(出力属性)を使用していますが、このほかにも、inout属性(入出力属性)があります。 十一行目以降はファクトリのインターフェースの宣言です。書式は通常のインターフェースと同様です。インターフェース名は任意の名前で定義できます。オブジェクトを生成するためのオペレーション(この例ではCreateServerObject())とオブジェクトを解放するためのオペレーション(この例ではReleaseServerObject())を宣言してください。また、クライアント管理ライブラリを使用する場合はWO_BaseFactoryインターフェースの派生にしてください。WO_BaseFactoryはWO_Baseと同様にwobase.idlに定義されています。 このようにして出来上がったIDLファイルをIDLコンパイラに入力してスタブファイル、スケルトンファイルを作成します。詳しいIDLの構文やJava言語マッピングについてはObject Broker のマニュアルを参照してください。 なお、IDLファイルのファイル名の拡張子は必ず .idl としてください。この例題では、loopback.idlとして説明します。 IDLファイルを作成しましたら、次にIDLコンパイラを実行してスタブファイルとスケルトンファイル、Holderクラスファイル、Helperクラスファイルを生成します。 スタブファイルとは、クライアントアプリケーションがサーバオブジェクトをアクセスするためのアクセスクラスを定義しているファイルのことです。スケルトンファイルとは、ORBからサーバアプリケーションを呼び出すためのベースとなるクラスを定義したファイルのことです。 Holderファイルはoutおよびinoutパラメータモードをサポートするためのクラスを定義しています。 HelperクラスはAny型への挿入と取り出し、ストリームからの読み込みと書き出しに使われます。 WebOTXでは、上記ファイルのほかに以下の機能を定義したファイルが必要になります。
i2j -i -lstub <IDLファイル名> (woi2jとは異なり、"loopback.idl"のように.idlも必要です) ^^ ^^^^^^ | +-----ローカルスタブを使用。 +----------ifファイルの生成を行います。WebOTXに登録するために必須のオプションです。※UNIX系OSの場合、以下の様にi2j.shを使用してください。
/opt/WebOTX/ObjectBroker/bin/i2j.sh -i -lstub <IDLファイル名>また、WO_Base,WO_BaseFactoryを派生している場合は以下のオプションを指定してください。この場合、事前にwobase.idlをカレントディレクトリにコピーしておく必要があります。wobase.idlは、WebOTX Developer (for CORBA Application)をインストールしたディレクトリ配下のidlfilesディレクトリにあります。
i2j -i -lstub -rpjp.co.nec.WebOTX -Rwobase.idl <IDLファイル名> (.idlも必要) ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ | +-----wobase.idl を参照します。 | WO_Baseを使用するために必須のオプションです。 +----------IDL定義が jp.co.nec.WebOTXパッケージに置かれているものとして コードを生成します。WO_Baseを使用するために必須のオプションです。※UNIX系OSの場合、以下の様にi2j.shを使用してください。
/opt/WebOTX/ObjectBroker/bin/i2j.sh -i -lstub -rpjp.co.nec.WebOTX -Rwobase.idl <IDLファイル名>コマンドを実行すると以下のファイルを生成します。
// // 実装クラス(LoopBackSampleObj.java) // package sample; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; public class LoopBackSampleObj extends LoopBackSamplePOA { public LoopBackSampleObj() { } public int LoopBack(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar; return outputChar.value.length(); } public int LowerCase(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar.toLowerCase(); return outputChar.value.length(); } public int UpperCase(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar.toUpperCase(); return outputChar.value.length(); } // WO_Base interface public void OnTPSAbort(int status) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_ERR, "*** OnTPSAbort() called. ***"); WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_ERR, " status="+status); } public void OnTPSDisconnect() { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_INFO, "*** OnTPSDisconnect() called. ***"); } public void OnTPSMessageNotified(java.lang.String mes) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_INFO, "*** OnTPSMessageNotified("+mes+") called. ***"); } }各オペレーションの定義は自分で記述することも出来ますが、IDLコンパイラが生成したLoopBackSampleOperation.javaの定義からコピーするのが簡単です。 OnTPSAbort()とOnTPSDisconnect()およびOnTPSMessageNotified()の定義はWO_Baseから派生したときのみ必要です。これは、サーバアプリケーションが例外したとき(OnTPSAbort)や端末が不意に切断したとき(OnTPSMessageNotified)、運用管理コマンドからのメッセージ送信(OnTPSMessageNotified)時にそれぞれWebOTXから呼ばれる関数です。 また、import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapperはサーバAPIを使うときに必要になります。サーバAPIの詳細な使い方や、このほかのAPIついては、 [リファレンス > API > WebOTXが提供するAPI > CORBA > WebOTX CORBA アプリケーション(Java) > サーバAPI ] を参照してください。 次に実装情報定義クラスとコンポーネント初期化クラスの作成方法について説明します。 実装情報定義クラスとコンポーネント初期化クラスを作成するには、woixjコマンドを使用するか、後述の記述例を参照し作成してください。 woixjコマンドのインタフェースは以下のようになります。
woixj <ifファイル名> [-options] (拡張子ifは不要) 使用例: woixj loopbackオプションの指定方法については、 [コマンドリファレンス] を参照してください。 次に、実装情報定義クラスの記述例を示します。
// // 実装情報定義クラス(LoopBackSampleObjInfo.java) // import jp.co.nec.WebOTX.WOServantCallback; public class LoopBackSampleObjInfo implements WOServantCallback { public String _name() { return "sample_LoopBackSampleJava"; } public String _id() { return "IDL:sample/LoopBackSample:1.0"; } public org.omg.PortableServer.Servant _newInstance() { return new sample.LoopBackSampleObj(); } }実装情報定義クラスは、実装クラスをインスタンス化する時に使用されるクラスで、実装クラスごとに必要になります。 実装情報定義クラスを実装するためには、インターフェースWOServantCallbackをimplementsする必要があります。 _name() では、WebOTXが実装を識別するために使用する実装識別名を返却してください。この値は、コンポーネントファイル内で一意にする必要があります。 _id() では、対応する実装クラスのリポジトリIDを返却してください。 _newInstance() では、対応する実装クラスをインスタンス化して返却してください。 次に、コンポーネント初期化クラスの記述例を示します。
// // コンポーネント初期化クラス(LoopBackInit.java) // import jp.co.nec.WebOTX.WOComponent; import jp.co.nec.WebOTX.WOUserComponent; public class LoopBackInit implements WOUserComponent { public void init() { WOComponent.add(new LoopBackSampleObjInfo()); } }コンポーネント初期化クラスは、コンポーネントファイルが読み込まれるときに使用されるクラスで、コンポーネントファイルにつき1つ必要になります。 コンポーネント初期化クラスを実装するためには、インターフェースWOUserComponentをimplementsする必要があります。 init() では、WOComponent.add()を呼び出してコンポーネントファイル内に定義されている実装情報を登録する処理を記述してください。コンポーネントファイル内の全ての実装クラスについて実装情報を登録する必要があります。 作成したLoopBackSampleObj.java, LoopBackSampleObjInfo.java, LoopBackInit.javaとIDLコンパイラが作成したサーバアプリケーションに必要なファイルをすべてコンパイルします。 まず、コンパイル後に出来るクラスファイルを格納するディレクトリを作成します。ここではclassesディレクトリとしています。
>mkdir classes次にJavaのソースファイルをコンパイルしてclassファイルを作成します。 JDKの場合、以下のように入力します。
Windows >javac -d classes *.java sample\*.java Unix >javac -d classes *.java sample/*.javaこの例では、classesディレクトリ配下にclassファイルを作成するようにしています。 無事にコンパイルができたら、JDKのjarコマンドを使って一つにまとめます。カレントディレクトリを先ほど指定したclassesディレクトリとした場合は、
>cd classes >jar cvf LoopBackSample.jar *.class sampleとタイプします。これで、LoopBackSample.jarというファイルができます。これがWebOTXのコンポーネントになります。 この例では、サーバの実装とインタフェース部分を一つにまとめていますが、1インタフェースで複数の実装を作成する場合は「インタフェースコンポーネントファイル」、「サーバコンポーネントファイル」と別々に作成することをお勧めします。
// // 実装クラス(LoopBackSampleObj.java) // package sample; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; public class LoopBackSampleObj extends LoopBackSamplePOA { public LoopBackSampleObj() { } public int LoopBack(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar; return outputChar.value.length(); } public int LowerCase(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar.toLowerCase(); return outputChar.value.length(); } public int UpperCase(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar.toUpperCase(); return outputChar.value.length(); } // WO_Base interface public void OnTPSAbort(int status) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_ERR, "*** OnTPSAbort() called. ***"); WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_ERR, " status="+status); } public void OnTPSDisconnect() { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_INFO, "*** OnTPSDisconnect() called. ***"); } public void OnTPSMessageNotified(java.lang.String mes) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_INFO, "*** OnTPSMessageNotified("+mes+") called. ***"); } }各オペレーションの定義は自分で記述することも出来ますが、IDLコンパイラが生成したLoopBackSampleOperation.javaの定義からコピーするのが簡単です。 OnTPSAbort()とOnTPSDisconnect()およびOnTPSMessageNotified()の定義はWO_Baseから派生したときのみ必要です。これは、サーバアプリケーションが例外したとき(OnTPSAbort)や端末が不意に切断したとき(OnTPSMessageNotified)、運用管理コマンドからのメッセージ送信(OnTPSMessageNotified)時にそれぞれWebOTXから呼ばれる関数です。 また、import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapperはサーバAPIを使うときに必要になります。サーバAPIの詳細な使い方や、このほかのAPIついては [リファレンス > API > WebOTXが提供するAPI > CORBA > WebOTX CORBA アプリケーション(Java) > サーバAPI ] を参照してください。 次に実装情報定義クラスとコンポーネント初期化クラスの作成方法について説明します。 実装情報定義クラスとコンポーネント初期化クラスを作成するには、woixjコマンドを使用するか、後述の記述例を参照し作成してください。 woixjコマンドのインタフェースは以下のようになります。
woixj <ifファイル名> [-options] (拡張子ifは不要) 使用例: woixj loopbackオプションの指定方法については、[コマンドリファレンス]を参照してください。 次に、ファクトリの実装クラスの記述例を示します。
// // ファクトリ実装クラス(WO_Factory_LoopBackSampleObj.java) // package sample; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; import jp.co.nec.WebOTX.WOServantCallback; import jp.co.nec.WebOTX.WOServantManager; import org.omg.CORBA.IntHolder; import org.omg.CORBA.StringHolder; public class WO_Factory_LoopBackSampleObj extends WO_Factory_LoopBackSamplePOA { public WO_Factory_LoopBackSampleObj() { } public LoopBackSample CreateServerObject() { WOServantCallback servInfo = new LoopBackSampleObjInfo(); org.omg.CORBA.Object obj = WOServantManager.CreateServant(servInfo); return LoopBackSampleHelper.narrow(obj); } public void ReleaseServerObject(LoopBackSample obj) { WOServantCallback servInfo = new LoopBackSampleObjInfo(); WOServantManager.ReleaseServant(servInfo, obj); } public void GetID(IntHolder port, StringHolder host, StringHolder termid) { WoServerWrapper.TPSGetIDs(port, host, termid); } }オブジェクト生成オペレーション(この例ではCreateServerObject())では、WOServantManager.CreateServant()を呼び出してオブジェクトを生成し返却してください。 オブジェクト解放オペレーション(この例ではReleaseServerObject())では、WOServantManager.ReleaseServant()を呼び出してオブジェクトを解放してください。 GetID()の定義はWO_BaseFactoryから派生したときのみ必要です。これは、クライアント管理ライブラリを使用する場合に内部的に呼び出される関数です。 WoServerWrapper.TPSGetIDs()を呼び出す処理を記述してください。 次に、実装情報定義クラスの記述例を示します。
// // 実装情報定義クラス(LoopBackSampleObjInfo.java) // import jp.co.nec.WebOTX.WOServantCallback; public class LoopBackSampleObjInfo implements WOServantCallback { public String _name() { return "sample_LoopBackSampleJava"; } public String _id() { return "IDL:sample/LoopBackSample:1.0"; } public org.omg.PortableServer.Servant _newInstance() { return new sample.LoopBackSampleObj(); } }
// // 実装情報定義クラス(WO_Factory_LoopBackSampleObjInfo.java) // import jp.co.nec.WebOTX.WOServantCallback; public class WO_Factory_LoopBackSampleObjInfo implements WOServantCallback { public String _name() { return "sample_WO_Factory_LoopBackSampleJava"; } public String _id() { return "IDL:sample/WO_Factory_LoopBackSample:1.0"; } public org.omg.PortableServer.Servant _newInstance() { return new WO_Factory_LoopBackSampleObj(); } }実装情報定義クラスは、実装クラスをインスタンス化する時に使用されるクラスで、実装クラスごとに必要になります。 実装情報定義クラスを実装するためには、インターフェースWOServantCallbackをimplementsする必要があります。 _name() では、WebOTXが実装を識別するために使用する実装識別名を返却してください。この値は、コンポーネントファイル内で一意にする必要があります。 _id() では、対応する実装クラスのリポジトリIDを返却してください。 _newInstance() では、対応する実装クラスをインスタンス化して返却してください。 次に、コンポーネント初期化クラスの記述例を示します。
// // コンポーネント初期化クラス(LoopBackInit.java) // import jp.co.nec.WebOTX.WOComponent; import jp.co.nec.WebOTX.WOUserComponent; public class LoopBackInit implements WOUserComponent { public void init() { WOComponent.add(new LoopBackSampleObjInfo()); WOComponent.add(new WO_Factory_LoopBackSampleObjInfo()); } }コンポーネント初期化クラスは、コンポーネントファイルが読み込まれるときに使用されるクラスで、コンポーネントファイルにつき1つ必要になります。 コンポーネント初期化クラスを実装するためには、インターフェースWOUserComponentをimplementsする必要があります。 init() では、WOComponent.add()を呼び出してコンポーネントファイル内に定義されている実装情報を登録する処理を記述してください。コンポーネントファイル内の全ての実装クラスについて実装情報を登録する必要があります。 作成したLoopBackSampleObj.java, WO_Factory_LoopBackSampleObj.java, LoopBackSampleObjInfo.java, WO_Factory_LoopBackSampleObjInfo.java, LoopBackInit.javaとIDLコンパイラが作成したサーバアプリケーションに必要なファイルをすべてコンパイルします。 まず、コンパイル後に出来るクラスファイルを格納するディレクトリを作成します。ここではclassesディレクトリとしています。
>mkdir classes次にJavaのソースファイルをコンパイルしてclassファイルを作成します。 JDKの場合、以下のように入力します。
Windows >javac -d classes *.java sample\*.java Unix >javac -d classes *.java sample/*.javaこの例では、classesディレクトリ配下にclassファイルを作成するようにしています。 無事にコンパイルができたら、JDKのjarコマンドを使って一つにまとめます。カレントディレクトリを先ほど指定したclassesディレクトリとした場合は、
>cd classes >jar cvf LoopBackSample.jar *.class sampleとタイプします。これで、LoopBackSample.jarというファイルができます。これがWebOTXのコンポーネントになります。 この例では、サーバの実装とインタフェース部分を一つにまとめていますが、1インタフェースで複数の実装を作成する場合は「インタフェースコンポーネントファイル」、「サーバコンポーネントファイル」と別々に作成することをお勧めします。
---- IDLファイル ---- IDLファイル ---- IDLファイル ---- module AAAA { module BBBB { module CCCC { interface DDDD { void op1(); }; }; }; }; ---- 実装部分(DDDDObj.java) ---- 実装部分(DDDDObj.java) ---- package AAAA.BBBB.CCCC; import AAAA.BBBB.CCCC.DDDDPOA; public class DDDDObj extends DDDDPOA { public DDDDObj() { } public void op1() { } }(b). sequence型とstruct型を利用している場合
---- IDLファイル ---- IDLファイル ---- IDLファイル ---- interface AAA { struct BBB { long ID; string NAME; short AGE; }; typedef sequence < BBB > SEQ001; void GET_DATA (in SEQ001 inARG, out SEQ001 outARG, inout SEQ001 inoutARG); }; ---- 実装部分(AAAObj.java) ---- 実装部分(AAAObj.java) ---- import AAA; import AAAHelper; import AAAHolder; import AAAOperations; import AAAPOA; public class AAAObj extends AAAPOA { public AAAObj() { } public void GET_DATA(AAAPackage.BBB[] inARG, AAAPackage.SEQ001Holder outARG, AAAPackage.SEQ001Holder inoutARG) { int i=0; // inARGは値が設定されています。参照のみ可能です int inARGlen = inARG.length; for(i=0; i < inARGlen; i++) { int id = inARG[i].ID; } // outARGはBBB::SEQ001をnewしてAAAPackage.SEQ001Holder.valueに // 設定しなければなりません int outARGlen = 100; outARG.value = new AAAPackage.BBB[outARGlen]; for(i=0; i < outARGlen; i++) { outARG.value[i] = new AAAPackage.BBB(); outARG.value[i].ID = 10; } // inoutARGは値が設定されています。また書き換えもできます int inoutARGlen = inoutARG.value.length; for(i=0; i < inoutARGlen; i++) { inoutARG.value[i].ID = inoutARG.value[i].ID * 2; } } }
R5形式 >i2j -tie -i -lstun loopback.idl >woixj loopback -tie※UNIX系OSの場合、以下の様にi2j.shを使用してください。
> /opt/WebOTX/ObjectBroker/bin/i2j.sh -tie -i -lstun loopback.idl >woixj loopback -tieこれでTIEアプローチが使用できるファイルが生成されます。以下にTIEアプローチ時のコーディング例を示します。
package sample; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; public class LoopBackSampleObj implements LoopBackSampleOperations { ///////////////////////////////^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ここが違います。 public LoopBackSampleObj() { } public int LoopBack(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar; return outputChar.value.length(); } public int LowerCase(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar.toLowerCase(); return outputChar.value.length(); } public int UpperCase(java.lang.String inputChar, org.omg.CORBA.StringHolder outputChar) { outputChar.value = inputChar.toUpperCase(); return outputChar.value.length(); } // WO_Base interface public void OnTPSAbort(int status) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_ERR, "*** OnTPSAbort() called. ***"); WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_ERR, " status="+status); } public void OnTPSDisconnect() { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_INFO, "*** OnTPSDisconnect() called. ***"); } public void OnTPSMessageNotified(java.lang.String mes) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_INFO, "*** OnTPSMessageNotified("+mes+") called. ***"); } }
>/opt/WebOTX/bin/makecpk loopback.spk module=loopback.jar if=loopback.if
>/opt/WebOTX/bin/makecpk loopback.cpk module=loopback.jar if=loopback.if \ initfunc=LoopBackInit useshareif=true
>/opt/WebOTX/bin/makecpk loopback.cpk module= LoopBackSample.jar if=loopback.if \ initfunc=loopbackInit useshareif=false
import jp.co.nec.WebOTX.WO_PUOObjectListener; import jp.co.nec.WebOTX.WO_PUOOperationListener; public class preObjhoo1 implements WO_PUOObjectListener, WO_PUOOperationListener { String m_ID; public preObjhoo1() { } public void OnTPSPUOCreateObject() { // 生成時に特別な処理を行うときに記述 } public void OnTPSPUOReleaseObject() { // 解放時に特別な処理を行うときに記述 } public void OnTPSPUOOperationStart(String intf, String opname) { // オペレーション開始時に特別な処理を行うときに記述 } public void OnTPSPUOOperationNormal(String intf, String opname) { // オペレーション正常終了時に特別な処理を行うときに記述 } public void OnTPSPUOOperationAbnormal(String intf, String opname, int status) { // オペレーション異常終了時に特別な処理を行うときに記述 } public void OnTPSPUOOperationAbort(String intf, String opname, int status) { // オペレーションアボート時に特別な処理を行うときに記述 } // 常駐オブジェクトとしてのオペレーション public int set(String ID) { m_ID = id; return m_ID.length(); } }
public interface jp.co.nec.WebOTX.WO_PUOObjectListener { public void OnTPSPUOCreateObject(); public void OnTPSPUOReleaseObject(); }
public interface jp.co.nec.WebOTX.WO_PUOOperationListener { public void OnTPSPUOOperationStart(String intf, String opname); public void OnTPSPUOOperationNormal(String intf, String opname); public void OnTPSPUOOperationAbnormal(String intf, String opname, int status); public void OnTPSPUOOperationAbort(String intf, String opname, int status); }
preObjhoo2.java import jp.co.nec.WebOTX.WO_PUOObjectListenerForPlural; import jp.co.nec.WebOTX.WO_PUOOperationListenerForPlural; public class preObjhoo2 implements WO_PUOObjectListenerForPlural, WO_PUOOperationListenerForPlural { String m_ID; public preObjhoo2() { } public void OnTPSPUOCreateObject(String ident) { // 生成時に特別な処理を行うときに記述 } public void OnTPSPUOReleaseObject(String ident) { // 解放時に特別な処理を行うときに記述 } public void OnTPSPUOOperationStart(String ident, String intf, String opname) { // オペレーション開始時に特別な処理を行うときに記述 } public void OnTPSPUOOperationNormal(String ident, String intf, String opname) { // オペレーション正常終了時に特別な処理を行うときに記述 } public void OnTPSPUOOperationAbnormal(String ident, String intf, String opname, int status) { // オペレーション異常終了時に特別な処理を行うときに記述 } public void OnTPSPUOOperationAbort(String ident, String intf, String opname, int status) { // オペレーションアボート時に特別な処理を行うときに記述 } // 常駐オブジェクトとしてのオペレーション public int set(String ID) { m_ID = id; return m_ID.length(); } }
preObjhoo3.java import jp.co.nec.WebOTX.WO_PUOObjectListener; import jp.co.nec.WebOTX.WO_PUOOperationListener; public class preObjhoo3 implements WWO_PUOObjectListenerForPlural, WO_PUOOperationListenerForPlural { int m_len; public preObjhoo3() { } public void OnTPSPUOCreateObject(String ident) { // 生成時に特別な処理を行うときに記述 } public void OnTPSPUOReleaseObject() { // 解放時に特別な処理を行うときに記述 } public void OnTPSPUOOperationStart(String ident, String intf, String opname) { // オペレーション開始時に特別な処理を行うときに記述 } public void OnTPSPUOOperationNormal(String ident, String intf, String opname) { // オペレーション正常終了時に特別な処理を行うときに記述 } public void OnTPSPUOOperationAbnormal(String ident, String intf, String opname, int status) { // オペレーション異常終了時に特別な処理を行うときに記述 } public void OnTPSPUOOperationAbort(String ident, String intf, String opname, int status) { // オペレーションアボート時に特別な処理を行うときに記述 } // 常駐オブジェクトとしてのオペレーション public void set(int len) { m_len = len; } }
public interface jp.co.nec.WebOTX.WO_PUOObjectListenerForPlural { public void OnTPSPUOCreateObject(String ident); public void OnTPSPUOReleaseObject(String ident); }
public interface jp.co.nec.WebOTX.WO_PUOOperationListenerForPlural { public void OnTPSPUOOperationStart(String ident, String intf, String opname); public void OnTPSPUOOperationNormal(String ident, String intf, String opname); public void OnTPSPUOOperationAbnormal(String ident, String intf, String opname, int status); public void OnTPSPUOOperationAbort(String ident, String intf, String opname, int status); }
import foo.*; import preObjhoo1; import preObjhoo2; import preObjhoo3; import jp.co.nec.WebOTX.orbsvwpr.*; public class fooObj extends fooPOA { public fooObj() { } public int op1(java.lang.String ID) { preObjhoo1 preobj1; preObjhoo2 preobj2; preObjhoo3 preobj3; // 単一常駐オブジェクトの取得 preObjhoo1 = (preObjhoo1)WoServerWrapper.TPSGetPrecreatedUsersObject(); // メソッドの呼び出し(本来ならnullチェックが必要) if (preObjhoo1 != null) { preObjhoo1.set(ID); } else { // エラー処理 } // 複数常駐オブジェクトの取得 try{ // hoo2とhoo3は運用管理ツールで指定。 // 大文字小文字を区別するので注意が必要 preObjhoo2 = (preObjhoo2) WoServerWrapper.TPSGetPrecreatedUsersObjectForPlural("hoo2"); preObjhoo3 = (preObjhoo3) WoServerWrapper.TPSGetPrecreatedUsersObjectForPlural("hoo3"); }catch(Exception e){ e.printStackTrace(); return -1; } // メソッドの呼び出し(例外処理しているので nullチェックは不要) return preObjhoo3.set(preObjhoo2.set(ID)); } }
: import jp.co.nec.WebOTX.WOPropertyGroupManager; import jp.co.nec.WebOTX.WOPropertyGroup; import jp.co.nec.WebOTX.WOProperty; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; import propPOA; public class foo extends propPOA { WOPropertyGroupManager pgm = new WOPropertyGroupManager(); public int Lock() { WOPropertyGroup[] pg = new WOPropertyGroup[1]; // オブジェクトを得るため int area = WOPropertyGroupManager.WOSP_AREATYPE_HOST; // ホスト内共通 java.lang.String pgname = "SamplePGName"; // PropertyGroup名 // プロパティグループの生成 ong nRet = pgm.TPSCreatePropertyGroup(pgname, area, pg); if (nRet < 0) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " Lock(): TPSCreatePropertyGroup() ==> " + nRet); return (int)nRet; } else { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " Lock(): TPSCreatePropertyGroup() ==> " + nRet); } // ロック(5秒間の待ち合わせあり)を行う int waitmode = WOPropertyGroup.WO_PG_WAIT; // 待ち合わせあり int waittime = 5000; // 5秒間待ち合わせ(単位ms) nRet = pg[0].Lock(waitmode, waittime); if (nRet < 0) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " Lock(): Lock() ==> " + nRet); return (int)nRet; } else { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " Lock(): Lock() ==> " + nRet); } // プロパティの生成 WOProperty pro[] = new WOProperty[1]; nRet = pg[0].CreateProperty(pname, pro); if (nRet < 0) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " SetValue(): CreateProperty() ==> " + nRet); return (int)nRet; } else { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " SetValue(): CreateProperty() ==> " + nRet); } // 値の取得 int[] getvalue = new int[1]; nRet = pro[0].Get(getvalue); WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " GetValue(): Get() value ==> " +getvalue[0]); WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " GetValue(): Get() nRet ==> " + nRet); // プロパティグループのアンロック nRet = pg[0].Unlock(); if (nRet != 0) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " Unlock(): Unlock() ==> " + nRet); return (int)nRet; } else { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " Unlock(): Unlock() ==> " + nRet); } return (int)nRet; } }
コーディング例: package jp.co.nec.WebOTX.Objectcreator; import org.omg.CORBA.ORB; import jp.co.nec.WebOTX.WO_InitTerm; import jp.co.nec.WebOTX.WebOTX_Information; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; public class InitTerm implements WO_InitTerm { public void initialize(ORB orb, WebOTX_Information info) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, "===***=== initialize"); // 初期化処理 } public void terminate(ORB orb, WebOTX_Information info) { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, "===***=== terminate"); // 終了処理 } }既定値以外のValueファクトリを使用する場合にも、初期化関数でvalueファクトリを登録してください。
(例) ((org.omg.CORBA_2_3.ORB)orb).register_value_factory(NamesHelper.id(), new NamesValueFactory_impl());
jp.co.nec.WebOTX.WO_ObjectListenerインタフェース public interface jp.co.nec.WebOTX.WO_ObjectListener { public void OnTPSCreateObject(); public void OnTPSReleaseObject(); }OnTPSCreateObject()はサーバオブジェクト生成後に、 OnTPSReleaseObject()はサーバオブジェクト消滅前にそれぞれコールバックします。
package jp.co.nec.WebOTX.apg; interface APGStarting { public static int WOAPGINT_SUCCESS = 0; public static int WOAPGINT_FAILURE = -1; public int initialize(); };
オペレーション操作関連 | |
---|---|
TPSSetTxStatus() | × オペレーション呼び出し中のみ意味があるため |
TPSRegisterDB() | × オペレーション呼び出し中のみ意味があるため |
TPSAbort() | × オペレーション呼び出し中のみ意味があるため |
TPSRestart() | × オペレーション呼び出し中のみ意味があるため |
トレース関連 | |
TPSUserTrace() | △ トレースレベル1または2のときのみ出力可能 |
TPSGetUserTraceLevel | ○ |
TPSEventJournal() | ○ |
情報取得 | |
TPSGetLid() | × オペレーション呼び出し中のみ意味があるため |
TPSGetArgument() | ○ |
TPSGetServerInformation() | △ 一部情報が欠落する(後述) |
常駐オブジェクト関連 | |
TPSGetPrecreatedUsersObject() | × オペレーション呼び出し中のみ意味があるため |
TPSGetPrecreatedUsersObjectForPlural()× | オペレーション呼び出し中のみ意味があるため |
SPA関連 | |
TPSGetSpa() | × オペレーション呼び出し中のみ意味があるため |
TPSSetSpa() | × オペレーション呼び出し中のみ意味があるため |
TPSSetSpaFlag() | × オペレーション呼び出し中のみ意味があるため |
共有プロパティ関連 | |
TPSCreatePropertyGroup() | ○ |
TPSGetPropertyGroup() | ○ |
TPSDeletePropertyGroup() | ○ |
CreateProperty() | ○ |
GetProperty() | ○ |
DeleteProperty() | ○ |
Lock() | ○ |
Unlock() | ○ |
Set() | ○ |
Get() | ○ |
WebOTXの情報 | |
アプリケーショングループ名 | ○ |
プロセスグループ名 | × プロセスグループ単位の指定パラメータのため |
ステートフルかステートレスか | × プロセスグループ単位の指定パラメータのため |
スレッドモデル | × プロセスグループ単位の指定パラメータのため |
IIOPリスナポート番号 | ○ |
クライアント管理ライブラリポート | ○ |
常駐オブジェクトクラス名 | × プロセスグループ単位の指定パラメータのため |
OTS連携を行うか | × プロセスグループ単位の指定パラメータのため |
システムID | ○ |
接続サーバ名 | ○ |
名前サーバ名 | ○ |
名前サーバに登録するリファレンスの数 | ○ |
ファクトリを使うかどうか | × プロセスグループ単位の指定パラメータのため |
import jp.co.nec.WebOTX.WebOTX_DB; import jp.co.nec.WebOTX.orbsvwpr.WoServerWrapper; public class MyDB implements WebOTX_DB { public MyDB () { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " **** called MyDB."); // データベース初期化処理 } public void rollback() { WoServerWrapper.TPSUserTrace(WoServerWrapper.LOG_DEBUG, " **** called MyDB.rollback()"); // データベースロールバック処理 (異常終了時に呼ばれる) } }
>PATH=${PATH}:/opt/WebOTX/ObjectBroker/bin >PATH=${PATH}:/opt/WebOTX/dev/bin >PATH=${PATH}:/opt/WebOTX/bin >export PATH >LD_LIBRARY_PATH=/opt/WebOTX/ObjectBroker/lib:/opt/WebOTX/dev/lib >export LD_LIBRARY_PATH >CLASSPATH=/opt/WebOTX/modules/jsocks.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/modules/wo-orb110.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/modules/omgorb110.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/dev/javalib/WOTXTRM.jar >CLASSPATH=${CLASSPATH}:/opt/WebOTX/dev/javalib/WOTXBS90.jar >export CLASSPATH
// // クライアント(LoopBackSampleClient.java) // import org.omg.CosNaming.*; import sample.*; public class LoopBackSampleClient { private org.omg.CORBA.ORB orb = null; private LoopBackSample serverobj = null; public static void main(String args[]) { LoopBackSampleClient ap = new LoopBackSampleClient(); if (ap.init(args) == false) { System.exit(1); } String org = "AbCdEfGhIj"; String strRet; // call loopback strRet = ap.call_LoopBack(org); if (strRet != null && strRet.equals(org)) { System.out.println("LoopBack OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("LoopBack NG!"); if (strRet != null) { System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println(" res=null"); } System.exit(1); } // call lowercase strRet = ap.call_LowerCase(org); if (strRet != null) { System.out.println("LowerCase OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("LowerCase NG!"); System.out.println(" org=" + org); System.out.println(" res=null"); System.exit(1); } // call uppercase strRet = ap.call_UpperCase(org); if (strRet != null) { System.out.println("UpperCase OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("UpperCase NG!"); System.out.println(" org=" + org); System.out.println(" res=null"); System.exit(1); } ap.destroy(); } public boolean init(String args[]) { try { orb = org.omg.CORBA.ORB.init(args, null); // get naming service object reference org.omg.CORBA.Object nsobj = null; NamingContext ns = null; nsobj = orb.resolve_initial_references("NameService"); ns = NamingContextHelper.narrow(nsobj); // make name path of server object reference NameComponent ncseq[] = { new NameComponent("NEC", ""), new NameComponent("WebOTX", ""), new NameComponent("WO_Default", ""), new NameComponent("sample", ""), new NameComponent("LoopBackSample", ""), new NameComponent("1", "") }; serverobj = LoopBackSampleHelper.narrow(ns.resolve(ncseq)); if (serverobj == null) { System.out.println("Server object is null."); } return true; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return false; } } public void destroy() { if (serverobj != null) { serverobj = null; } if (orb != null) { try { // コネクション切断 (Object BrokerローカルAPI) jp.co.nec.orb.ConnectionManager.close_all_client_connections(); boolean wait_for_completion = true; orb.shutdown(wait_for_completion); } catch(Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } } public String call_LoopBack(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.LoopBack(in,outputChar); returnoutputChar.value; }catch(Exception e){ System.out.println("ERROR:" + e); e.printStackTrace(System.out); return null; } } public String call_LowerCase(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.LowerCase(in, outputChar); return outputChar.value; }catch(Exception e){ System.out.println("ERROR:" + e); e.printStackTrace(System.out); return null; } } public String call_UpperCase(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.UpperCase(in, outputChar); return outputChar.value; }catch(Exception e){ System.out.println("ERROR:" + e); e.printStackTrace(System.out); return null; } } }ファイルの作成が終わりましたら、コンパイルします。 まず、コンパイル後に出来るクラスファイルを格納するディレクトリを作成します。ここではclassesディレクトリとしています。
>mkdir classes次にJavaのソースファイルをコンパイルしてclassファイルを作成します。 JDKの場合、以下のように入力します。
Windows >javac -d classes *.java sample\*.java Unix >javac -d classes *.java sample/*.java無事にコンパイルが終わりましたらJARファイルにまとめます。
>cd classes >jar cvf LoopBackSampleClient.jar *.class sample
// // クライアント(LoopBackSampleClient.java) // import org.omg.CosNaming.*; import sample.*; public class LoopBackSampleClient { private org.omg.CORBA.ORB orb = null; private WO_Factory_LoopBackSample factoryobj = null; private LoopBackSample serverobj = null; public static void main(String args[]) { LoopBackSampleClient ap = new LoopBackSampleClient(); if (ap.init(args) == false) { System.exit(1); } String org = "AbCdEfGhIj"; String strRet; // call loopback strRet = ap.call_LoopBack(org); if (strRet != null && strRet.equals(org)) { System.out.println("LoopBack OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("LoopBack NG!"); if (strRet != null) { System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println(" res=null"); } System.exit(1); } // call lowercase strRet = ap.call_LowerCase(org); if (strRet != null) { System.out.println("LowerCase OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("LowerCase NG!"); System.out.println(" org=" + org); System.out.println(" res=null"); System.exit(1); } // call uppercase strRet = ap.call_UpperCase(org); if (strRet != null) { System.out.println("UpperCase OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("UpperCase NG!"); System.out.println(" org=" + org); System.out.println(" res=null"); System.exit(1); } ap.destroy(); } public boolean init(String args[]) { try { orb = org.omg.CORBA.ORB.init(args, null); // get naming service object reference org.omg.CORBA.Object nsobj = null; NamingContext ns = null; nsobj = orb.resolve_initial_references("NameService"); ns = NamingContextHelper.narrow(nsobj); // make name path of server object reference NameComponent ncseq[] = { new NameComponent("NEC", ""), new NameComponent("WebOTX", ""), new NameComponent("WO_Default", ""), new NameComponent("sample", ""), new NameComponent("WO_Factory_LoopBackSample", ""), new NameComponent("1", "") }; factoryobj = WO_Factory_LoopBackSampleHelper.narrow(ns.resolve(ncseq)); if (factoryobj == null) { System.out.println("Factory object is null."); } serverobj = factoryobj.CreateServerObject(); if (serverobj == null) { System.out.println("Server object is null."); } return true; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return false; } } public void destroy() { if (factoryobj != null && serverobj != null) { factoryobj.ReleaseServerObject(serverobj); serverobj = null; factoryobj = null; } if (orb != null) { try { // コネクション切断 (Object BrokerローカルAPI) jp.co.nec.orb.ConnectionManager.close_all_client_connections(); boolean wait_for_completion = true; orb.shutdown(wait_for_completion); } catch(Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } } public String call_LoopBack(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.LoopBack(in,outputChar); return outputChar.value; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return null; } } public String call_LowerCase(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.LowerCase(in,outputChar); return outputChar.value; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return null; } } public String call_UpperCase(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.UpperCase(in,outputChar); return outputChar.value; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return null; } } }ファイルの作成が終わりましたら、コンパイルします。 まず、コンパイル後に出来るクラスファイルを格納するディレクトリを作成します。ここではclassesディレクトリとしています。
> mkdir classes次にJavaのソースファイルをコンパイルしてclassファイルを作成します。 JDKの場合、以下のように入力します。
Windows > javac -d classes *.java sample\*.java Unix > javac -d classes *.java sample/*.java無事にコンパイルが終わりましたらJARファイルにまとめます。
> cd classes > jar cvf LoopBackSampleClient.jar *.class
// // クライアント(LoopBackSampleClient.java) // import org.omg.CosNaming.*; import sample.*; import jp.co.nec.WebOTX.TerminalManager; public class LoopBackSampleClient { private org.omg.CORBA.ORB orb = null; private WO_Factory_LoopBackSample factoryobj = null; private LoopBackSample serverobj = null; private TerminalManager tm = new TerminalManager(); public static void main(String args[]) { LoopBackSampleClient ap = new LoopBackSampleClient(); if (ap.init(args) == false) { System.exit(1); } String org = "AbCdEfGhIj"; String strRet; // call loopback strRet = ap.call_LoopBack(org); if (strRet != null && strRet.equals(org)) { System.out.println("LoopBack OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("LoopBack NG!"); if (strRet != null) { System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println(" res=null"); } System.exit(1); } // call lowercase strRet = ap.call_LowerCase(org); if (strRet != null) { System.out.println("LowerCase OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("LowerCase NG!"); System.out.println(" org=" + org); System.out.println(" res=null"); System.exit(1); } // call uppercase strRet = ap.call_UpperCase(org); if (strRet != null) { System.out.println("UpperCase OK!"); System.out.println(" org=" + org); System.out.println(" res=" + strRet); } else { System.out.println("UpperCase NG!"); System.out.println(" org=" + org); System.out.println(" res=null"); System.exit(1); } ap.destroy(); } public boolean init(String args[]) { try { orb = org.omg.CORBA.ORB.init(args, null); // get naming service object reference org.omg.CORBA.Object nsobj = null; NamingContext ns = null; nsobj = orb.resolve_initial_references("NameService"); ns = NamingContextHelper.narrow(nsobj); // make name path of server object reference NameComponent ncseq[] = { new NameComponent("NEC", ""), new NameComponent("WebOTX", ""), new NameComponent("WO_Default", ""), new NameComponent("sample", ""), new NameComponent("WO_Factory_LoopBackSample", ""), new NameComponent("1", "") }; factoryobj = WO_Factory_LoopBackSampleHelper.narrow(ns.resolve(ncseq)); if (factoryobj == null) { System.out.println("Factory object is null."); } serverobj = factoryobj.CreateServerObject(); if (serverobj == null) { System.out.println("Server object is null."); } tm.SetFactoryObject(orb, factoryobj); tm.SetMessageType(TerminalManager.TM_MESSAGE_SYSTEMOUT); return true; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return false; } } public void destroy() { if (factoryobj != null && serverobj != null) { factoryobj.ReleaseServerObject(serverobj); serverobj = null; factoryobj = null; } tm.Term(); tm = null; if (orb != null) { try { // コネクション切断 (Object BrokerローカルAPI) jp.co.nec.orb.ConnectionManager.close_all_client_connections(); boolean wait_for_completion = true; orb.shutdown(wait_for_completion); } catch(Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } } public String call_LoopBack(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.LoopBack(in,outputChar); return outputChar.value; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return null; } } public String call_LowerCase(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.LowerCase(in,outputChar); return outputChar.value; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return null; } } public String call_UpperCase(String in) { try{ org.omg.CORBA.StringHolder outputChar = new org.omg.CORBA.StringHolder(); serverobj.UpperCase(in,outputChar); return outputChar.value; } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); return null; } } }修正個所には下線をつけています。これで、無通信監視機能、非同期メッセージ表示機能が使えます。なお、クライアント管理ライブラリの有効期間はTerm()メソッドを呼び出すまでです。 非同期メッセージ表示機能にはダイアログボックスを表示するほかに、メッセージを送信する拡張機能があります。これを使うことより、非同期メッセージを受信した後の動作を独自に実装することが出来ます。クライアント管理ライブラリに関するAPIについては [リファレンス > API > WebOTXが提供するAPI > CORBA > WebOTX CORBA アプリケーション(Java) > クライアント管理ライブラリAPI ] を参照してください。
: export PATH=$PATH:/opt/WebOTX/ObjectBroker/bin:/opt/WebOTX/dev/bin : export LD_LIBRARY_PATH=/opt/WebOTX/ObjectBroker/namespace/lib: \ /opt/WebOTX/dev/lib :
1: module sample 2: { 3: interface LoopBackSample : WO_Base 4: // (サンプルではWO_Baseからの派生はありません) 5: { 6: long LoopBack(in string inputChar, out string outputChar); 7: long LowerCase(in string inputChar, out string outputChar); 8: long UpperCase(in string inputChar, out string outputChar); 9: }; 10: };一行目のmoduleはモジュールを宣言するときに記述します。interfaceを指定する場合、module定義の指定は必須です。三行目のinterfaceはインタフェースを宣言するときに記述します。続けてインタフェース名を記述します。これがC++のクラス名になります。その後ろの : WO_BaseはWO_Baseインタフェースからの派生を意味しています。WO_BaseはWebOTX専用のインタフェースで、このインタフェースから派生することにより、アプリケーション例外時の呼出し(OnTPSAbort())やクライアント切断時の呼出し(OnTPSDisconnect())が行われます。これらの機能が不要なときは記述しなくても結構です。また、WO_Baseの定義はWebOTXをインストールしたディレクトリ配下にwobase.idlとして定義しています。 六行目以降はオペレーションの宣言です。オペレーションの書式はC++の関数宣言のように記述します。 C++の関数宣言と異なるのは、各引数に入出力属性を付けることです。上記例ではin属性、out属性を指定しています。このほかにもinout属性(入出力属性)があります。また、オペレーション名は256バイト以内で記述してください。 このようにして出来上がったIDLファイルをIDLコンパイラに入力してスタブファイル、スケルトンファイルを作成します。 なお、IDLファイルのファイル名の拡張子は必ず .idl としてください。この例題では、loopback.idlとして説明します。 IDLファイルを作成しましたら、次にIDLコンパイラを実行します。 IDLコンパイラを実行するとスタブファイルとスケルトンファイルを生成します。スタブファイルとは、クライアントアプリケーションがサーバオブジェクトをアクセスするためのアクセスクラス群を定義しているファイルのことです。スケルトンファイルとは、ORBからサーバアプリケーションを呼び出すためのベースとなるクラス群を定義したファイルのことです。 WebOTXでは、スタブファイルおよびスケルトンファイルのほかに以下のコードが必要になります。
i2cc -i -Xdii -lstub <IDLファイル名> ^^ ^^^^^ ^^^^^^ (woigenxx とは異なり、"loopback.idl"のように.idlも必要です) | | +-----ローカルスタブを使用。。 | +-----------フックが使用可能になります。 | +----------------ifファイルの生成を行います。 WebOTXに登録するために必須のオプションです。同一インタフェースに複数の実装を持たせる場合は、インタフェース部分を分離して共有ライブラリを作成する必要があります。この場合は-Eオプションを指定してください。同一インタフェースに複数の実装を持たせない場合は、-Eオプションは指定しないでください。
i2cc -i -Xdii -lstub -E <IDLファイル名> ^^ ^^^^^ ^^^^^^ ^^ (woigenxx とは異なり、"loopback.idl"のように.idlも必要です) | | | +--スタブとスケルトンを__declspec(dllexport)可能にします。 | | +-------ローカルスタブを使用。 | | | +-------------フックが使用可能になります。 | +------------------ifファイルの生成を行います。 WebOTXに登録するために必須のオプションです。また、WO_Baseを派生している場合は-Rオプションを以下のように指定してください。この場合、事前にwobase.idlをカレントディレクトリにコピーしておく必要があります。 wobase.idlは、WebOTX Developer (for CORBA Application)をインストールしたディレクトリ配下のidlfilesディレクトリにあります。
i2cc -i -Xdii -lstub -Rwobase.idl <IDLファイル名> (woigenxx とは異なり、 ^^ ^^^^^ ^^^^^^ ^^^^^^^^^^^^ "loopback.idl"のように.idlも必要です) | | | +--wobase.idl を参照します。 | | | WO_Baseを使用するために必須のオプションです。 | | +----------ローカルスタブを使用。 | | | +------------フックが使用可能になります。 | +-----------------ifファイルの生成を行います。 WebOTXに登録するために必須のオプションです。このコマンドを実行すると以下のファイルが生成されます。
1: module sample 2: { 3: interface LoopBackSample : WO_Base 4: //(サンプルではWO_Baseからの派生はありません) 5: { 6: long LoopBack(in string inputChar, out string outputChar); 7: long LowerCase(in string inputChar, out string outputChar); 8: long UpperCase(in string inputChar, out string outputChar); 9: }; 10 11: interface WO_Factory_LoopBackSample : WO_BaseFactory 12: // (サンプルではWO_BaseFactoryからの派生はありません) 13: { 14: LoopBackSample CreateServerObject(); 15: void ReleaseServerObject(in LoopBackSample obj); 16: }; 17: };一行目のmoduleはモジュールを宣言するときに記述します。interfaceを指定する場合、module定義の指定は必須です。三行目のinterfaceはインタフェースを宣言するときに記述します。続けてインタフェース名を記述します。これがC++のクラス名になります。その後ろの : WO_BaseはWO_Baseインタフェースからの派生を意味しています。WO_BaseはWebOTX専用のインタフェースで、このインタフェースから派生することにより、アプリケーション例外時の呼出し(OnTPSAbort())やクライアント切断時の呼出し(OnTPSDisconnect())が行われます。これらの機能が不要なときは記述しなくても結構です。また、WO_Baseの定義はWebOTXをインストールしたディレクトリ配下にwobase.idlとして定義しています。 六行目から八行目はオペレーションの宣言です。オペレーションの書式はC++の関数宣言のように記述します。 C++の関数宣言と異なるのは、各引数に入出力属性を付けることです。上記例ではin属性、out属性を指定しています。このほかにもinout属性(入出力属性)があります。また、オペレーション名は256バイト以内で記述してください。 十一行目以降はファクトリのインターフェースの宣言です。書式は通常のインターフェースと同様です。インターフェース名は任意の名前で定義できます。オブジェクトを生成するためのオペレーション(この例ではCreateServerObject())とオブジェクトを解放するためのオペレーション(この例ではReleaseServerObject())を宣言してください。また、クライアント管理ライブラリを使用する場合はWO_BaseFactoryインターフェースの派生にしてください。WO_BaseFactoryはWO_Baseと同様にwobase.idlに定義されています。 このようにして出来上がったIDLファイルをIDLコンパイラに入力してスタブファイル、スケルトンファイルを作成します。 なお、IDLファイルのファイル名の拡張子は必ず .idl としてください。この例題では、loopback.idlとして説明します。 IDLファイルを作成しましたら、次にIDLコンパイラを実行します。 IDLコンパイラを実行するとスタブファイルとスケルトンファイルを生成します。スタブファイルとは、クライアントアプリケーションがサーバオブジェクトをアクセスするためのアクセスクラス群を定義しているファイルのことです。スケルトンファイルとは、ORBからサーバアプリケーションを呼び出すためのベースとなるクラス群を定義したファイルのことです。 WebOTXでは、スタブファイルおよびスケルトンファイルのほかに以下のコードが必要になります。
i2cc -i -Xdii -lstub <IDLファイル名> ^^ ^^^^^ ^^^^^^ (woigenxx とは異なり、"loopback.idl"のように.idlも必要です) | | +-----ローカルスタブを使用。 | | | +-----------フックが使用可能になります。 | +----------------ifファイルの生成を行います。 WebOTXに登録するために必須のオプションです。同一インタフェースに複数の実装を持たせる場合は、インタフェース部分を分離して共有ライブラリを作成する必要があります。この場合は-Eオプションを指定してください。同一インタフェースに複数の実装を持たせない場合は、-Eオプションは指定しないでください。
i2cc -i -Xdii -lstub -E <IDLファイル名> ^^ ^^^^^ ^^^^^^ ^^ (woigenxx とは異なり、"loopback.idl"のように.idlも必要です) | | | +--スタブとスケルトンを__declspec(dllexport)可能にします。 | | +-------ローカルスタブを使用。 | | | +-------------フックが使用可能になります。 | +------------------ifファイルの生成を行います。 WebOTXに登録するために必須のオプションです。また、WO_Base,WO_BaseFactoryを派生している場合は-Rオプションを以下のように指定してください。この場合、事前にwobase.idlをカレントディレクトリにコピーしておく必要があります。 wobase.idlは、WebOTX Developer (for CORBA Application)をインストールしたディレクトリ配下のidlfilesディレクトリにあります。
i2cc -i -Xdii -lstub -Rwobase.idl <IDLファイル名> (woigenxx とは異なり、 ^^ ^^^^^ ^^^^^^ ^^^^^^^^^^^^ "loopback.idl"のように.idlも必要です) | | | +---wobase.idl を参照します。 | | WO_Baseを使用するために必須のオプションです。 | | +-----------ローカルスタブを使用。 | | | +-----------------フックが使用可能になります。 | +----------------------ifファイルの生成を行います。 WebOTXに登録するために必須のオプションです。このコマンドを実行すると以下のファイルが生成されます。
R5形式
R5形式におけるUNIXのMakefileについて
IDLコンパイラが生成したファイルを使用して、サーバアプリケーションの共有ライブラリを作成します。 必要なファイルは、以下のほかに利用者が作成した実装コードとヘッダファイル(サンプルではloopback_i.hとloopback_i.C)です。
コンパイル時のオプション
リンク時のオプション
-DOB_<IDLファイル名の大文字>CMN_EXPORT -DOB_<IDLファイル名の大文字>IMP_EXPORT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +-------スケルトンをdllexportする +-------------------------スタブをdllexportする
#----------------------------------------------------------------------- # for Linux #----------------------------------------------------------------------- CC = /usr/bin/g++ I2CC = /opt/WebOTX/ObjectBroker/bin/i2cc IDLFLAGS= -i -Xdii -lstub -Rwobase.idl BASENAME= loopback LIBS = OBJS = ${BASENAME}cmn.o \ ${BASENAME}imp.o \ ${BASENAME}_i.o INC = -I/opt/WebOTX/dev/include \ -I/opt/WebOTX/ObjectBroker/namespace/include LDFLAGS = -shared C++FLAGS= -D_REENTRANT -D_GNU_SOURCE -fPIC TARGET = ${BASENAME}.so all : ${OBJS} ${TARGET} ${TARGET} : ${OBJS} ${CC} -o $@ ${C++FLAGS} ${LDFLAGS} ${OBJS} ${LIBS} ${BASENAME}cmn.o : ${BASENAME}cmn.C ${BASENAME}.h ${BASENAME}imp.o : ${BASENAME}imp.C ${BASENAME}.h ${BASENAME}_i.o : ${BASENAME}_i.C ${BASENAME}_i.h .C.o : ${CC} ${INC} ${C++FLAGS} -c $*.C idl: ${I2CC} ${IDLFLAGS} ${BASENAME}.idl clean: /bin/rm -rf *.o ${TARGET}
/D "OB_<IDLファイル名の大文字>CMN_EXPORT" /D "OB_<IDLファイル名の大文字>IMP_EXPORT" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +----------------スケルトンをdllexportする +-------------------------------------スタブをdllexportする
#----------------------------------------------------------------------- # for Windows(Intel 64) #----------------------------------------------------------------------- !include OUTDIR=.\Release INTDIR=.\Release # Begin Custom Macros OutDir=.\Release # End Custom Macros OTXDIR=C:\Program Files\NEC\WebOTX OSPIDIR=$(OTXDIR)\ObjectBroker ALL : "$(OUTDIR)\$(BASENAME).dll" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /EHsc /O2 \ /I "$(OSPIDIR)\namespace\include" \ /I "$(OTXDIR)\dev\include" \ /D "WIN32" /D "WIN64" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" \ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << LINK=link.exe LINK_FLAGS=nosp9011.lib nOrbW971.lib nWOBS97.lib \ /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(BASENAME).pdb" \ /machine:AMD64 /out:"$(OUTDIR)\$(BASENAME).dll" \ /implib:"$(OUTDIR)\$(BASENAME).lib" \ /libpath:"$(OSPIDIR)\namespace\lib" \ /libpath:"$(OTXDIR)\dev\lib" LINK_OBJS= \ "$(INTDIR)\$(BASENAME)_i.obj" \ "$(INTDIR)\$(BASENAME)cmn.obj" \ "$(INTDIR)\$(BASENAME)imp.obj" "$(OUTDIR)\$(BASENAME).dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK_OBJS) $(LINK) @<< $(LINK_FLAGS) $(LINK_OBJS) << SOURCE=.\$(BASENAME)_i.cpp "$(INTDIR)\$(BASENAME)_i.obj" : $(SOURCE) "$(INTDIR)" SOURCE=.\$(BASENAME)cmn.cpp "$(INTDIR)\$(BASENAME)cmn.obj" : $(SOURCE) "$(INTDIR)" SOURCE=.\$(BASENAME)imp.cpp "$(INTDIR)\$(BASENAME)imp.obj" : $(SOURCE) "$(INTDIR)"
woixcpp <ifファイル名> [-options] (拡張子ifは不要) 使用例: woixcpp loopbackオプションの指定方法については、[コマンドリファレンス]を参照してください。 このサンプルアプリケーションの場合は、loopback_i.hファイルと、loopback_i.C(Windowsの場合は.cpp)の二つのファイルを作成します。以下に、loopback_i.hの記述例を示します。
// loopback_i.h // // loopback_i.h // #ifndef LOOPBACK_I_H #define LOOPBACK_I_H #include "loopback.h" namespace sample { // 実装クラスの定義 class LoopBackSample_i : public virtual POA_sample::LoopBackSample { public: // constructor LoopBackSample_i(); // destructor virtual ~LoopBackSample_i(); public: CORBA::Long LoopBack( const char* inputChar, char*& outputChar, CORBA::Environment& _env = Ob_default_environment()); CORBA::Long LowerCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env = Ob_default_environment()); CORBA::Long UpperCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env = Ob_default_environment()); void OnTPSAbort( CORBA::Long status, CORBA::Environment& _env = Ob_default_environment()); void OnTPSDisconnect( CORBA::Environment& _env = Ob_default_environment()); void OnTPSMessageNotified( const char* mes, CORBA::Environment& _env = Ob_default_environment()); }; }; ////////////////////////////////////////////////////// // 実装情報の定義 class loopbackCallback_i : public virtual WebOTX::WOServantCallback { public: loopbackCallback_i() {} const char* _name(); const char* _id(); PortableServer::Servant _newInstance(); void _deleteInstance(PortableServer::Servant servant); }; #endif実装クラス定義は自分で記述することも出来ますが、IDLコンパイラが生成したloopback.hのPOA_sample::LoopBackSampleクラスの定義からコピーするのが簡単です。ただし、OnTPSAbort()とOnTPSDisconnect()の宣言はloopback.hにはありませんので、上記のようにタイプしてください。 次に、実装部分のコーディングです。
//loopback_i.C #include "orb.h" #include "wotxexps.h" #include "loopback.h" #include "loopback_i.h" #include <string.h> #include <ctype.h> // constructor sample::LoopBackSample_i::LoopBackSample_i() { } // destructor sample::LoopBackSample_i::~LoopBackSample_i() { } CORBA::Long sample::LoopBackSample_i::LoopBack( const char* inputChar, char*& outputChar, CORBA::Environment& _env) { outputChar = CORBA::string_dup(inputChar); return strlen(outputChar); } CORBA::Long sample::LoopBackSample_i::LowerCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env) { int len = strlen(inputChar); char* tmpstring = new char[len+1]; for (int i = 0; i < len && inputChar[i] != '\n'; i++) tmpstring[i] = tolower((char)inputChar[i]); tmpstring[len] = '\0'; outputChar = CORBA::string_dup((const char*)tmpstring); delete[] tmpstring; return len; } CORBA::Long sample::LoopBackSample_i::UpperCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env) { int len = strlen(inputChar); char* tmpstring = new char[len+1]; for (int i = 0; i < len && inputChar[i] != '\n'; i++) tmpstring[i] = toupper((char)inputChar[i]); tmpstring[len] = '\0'; outputChar = CORBA::string_dup((const char*)tmpstring); delete[] tmpstring; return len; } void sample::LoopBackSample_i::OnTPSAbort( CORBA::Long status, CORBA::Environment& _env) { char buf[256]; sprintf(buf, "Called OnTPSAbort."); TPSUserTrace(LOG_ERR, buf); // Abort時の処理を記述 } void sample::LoopBackSample_i::OnTPSDisconnect( CORBA::Environment& _env) { char buf[256]; sprintf(buf, "Called OnTPSDisconnect"); TPSUserTrace(LOG_ERR, buf); // クライアント切断時の処理を記述 } void sample::LoopBackSample_i::OnTPSMessageNotified( const char* mes, CORBA::Environment& _env) { // フェールオーバ時の処理を記述 } ////////////////////////////////////////////////////// // コンポーネント初期化関数 #ifdef _WINDOWS #define LOOPBACKEXPORT __declspec(dllexport) #else #define LOOPBACKEXPORT #endif extern "C" LOOPBACKEXPORT void loopbackinit(); // ^^^^^^^^^^^^これがコンポーネント初期化関数になります extern "C" LOOPBACKEXPORT void loopbackinit() { // 実装情報を登録します WebOTX::WOComponent::add(new loopbackCallback_i); } ////////////////////////////////////////////////////// // 実装情報の設定部分 const char* loopbackCallback_i::_name() { return (const char*)"loopback"; } const char* loopbackCallback_i::_id() { return (const char*)"IDL:sample/LoopBackSample:1.0"; } PortableServer::Servant loopbackCallback_i::_newInstance() { sample::LoopBackSample_i* iobj = new sample::LoopBackSample_i; return iobj; } void loopbackCallback_i::_deleteInstance(PortableServer::Servant servant) { delete servant; }コーディングそのものは通常のC++のコーディングと何ら変わりません。 WebOTXにはサーバアプリケーションの開発に役立つサーバAPIを用意しています(上記例ではTPSUserTrace()を使用しています)。サーバAPIの使い方については[リファレンス > API > WebOTXが提供するAPI > CORBA > WebOTX CORBA アプリケーション(C++) > サーバAPI ]を参照してください。 これで、サーバアプリケーションは完成しました。これをコンパイルしてライブラリを作成してください。
コンパイル中... U:\TestAPcl\loopbackcmn.cpp(980) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
woixcpp <ifファイル名> [-options] (拡張子ifは不要) 使用例: woixcpp loopbackオプションの指定方法については、[コマンドリファレンス]を参照してください。 このサンプルアプリケーションの場合は、loopback_i.hファイルと、loopback_i.C(Windowsの場合は.cpp)の二つのファイルを作成します。以下に、loopback_i.hの記述例を示します。
// loopback_i.h // #ifndef LOOPBACK_I_H #define LOOPBACK_I_H #include "loopback.h" namespace sample { // 実装クラスの定義 class LoopBackSample_i : public virtual POA_sample::LoopBackSample { public: // constructor LoopBackSample_i(); // destructor virtual ~LoopBackSample_i(); public: CORBA::Long LoopBack( const char* inputChar, char*& outputChar, CORBA::Environment& _env = Ob_default_environment()); CORBA::Long LowerCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env = Ob_default_environment()); CORBA::Long UpperCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env = Ob_default_environment()); void OnTPSAbort( CORBA::Long status, CORBA::Environment& _env = Ob_default_environment()); void OnTPSDisconnect( CORBA::Environment& _env = Ob_default_environment()); void OnTPSMessageNotified( const char* mes, CORBA::Environment& _env = Ob_default_environment()); }; class WO_Factory_LoopBackSample_i : public virtual POA_sample ::WO_Factory_LoopBackSample { public: // constructor WO_Factory_LoopBackSample_i(); // destructor virtual ~WO_Factory_LoopBackSample_i(); public: LoopBackSample_ptr CreateServerObject( CORBA::Environment& _env = Ob_default_environment()); void ReleaseServerObject( LoopBackSample_ptr obj, CORBA::Environment& _env = Ob_default_environment()); }; }; ////////////////////////////////////////////////////// // 実装情報の定義 class loopbackCallback_i : public virtual WebOTX::WOServantCallback { public: loopbackCallback_i() {} const char* _name(); const char* _id(); PortableServer::Servant _newInstance(); void _deleteInstance(PortableServer::Servant servant); }; class WO_Factory_loopbackCallback_i : public virtual WebOTX::WOServantCallback { public: WO_Factory_loopbackCallback_i() {} const char* _name(); const char* _id(); PortableServer::Servant _newInstance(); void _deleteInstance(PortableServer::Servant servant); }; #endif実装クラスの定義は自分で記述することも出来ますが、IDLコンパイラが生成したloopback.hの POA_sample::LoopBackSampleクラスの定義からコピーするのが簡単です。ただし、OnTPSAbort()とOnTPSDisconnect()の宣言はloopback.hにはありませんので、上記のようにタイプしてください。 次に、実装部分のコーディングです。
//loopback_i.C //loopback_i.C #include "orb.h" #include "wotxexps.h" #include "loopback.h" #include "loopback_i.h" #include <string.h> #include <ctype.h> // constructor sample::LoopBackSample_i::LoopBackSample_i() { } // destructor sample::LoopBackSample_i::~LoopBackSample_i() { } CORBA::Long sample::LoopBackSample_i::LoopBack( const char* inputChar, char*& outputChar, CORBA::Environment& _env) { outputChar = CORBA::string_dup(inputChar); return strlen(outputChar); } CORBA::Long sample::LoopBackSample_i::LowerCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env) { int len = strlen(inputChar); char* tmpstring = new char[len+1]; for (int i = 0; i < len && inputChar[i] != '\n'; i++) tmpstring[i] = tolower((char)inputChar[i]); tmpstring[len] = '\0'; outputChar = CORBA::string_dup((const char*)tmpstring); delete[] tmpstring; return len; } CORBA::Long sample::LoopBackSample_i::UpperCase( const char* inputChar, char*& outputChar, CORBA::Environment& _env) { int len = strlen(inputChar); char* tmpstring = new char[len+1]; for (int i = 0; i < len && inputChar[i] != '\n'; i++) tmpstring[i] = toupper((char)inputChar[i]); tmpstring[len] = '\0'; outputChar = CORBA::string_dup((const char*)tmpstring); delete[] tmpstring; return len; } void sample::LoopBackSample_i::OnTPSAbort( CORBA::Long status, CORBA::Environment& _env) { char buf[256]; sprintf(buf, "Called OnTPSAbort."); TPSUserTrace(LOG_ERR, buf); // Abort時の処理を記述 } void sample::LoopBackSample_i::OnTPSDisconnect( CORBA::Environment& _env) { char buf[256]; sprintf(buf, "Called OnTPSDisconnect"); TPSUserTrace(LOG_ERR, buf); // クライアント切断時の処理を記述 } void sample::LoopBackSample_i::OnTPSMessageNotified( const char* mes, CORBA::Environment& _env) { // フェールオーバ時の処理を記述 } ////////////////////////////////////////////////////// // constructor sample::WO_Factory_LoopBackSample_i::WO_Factory_LoopBackSample_i() { } // destructor sample::WO_Factory_LoopBackSample_i::~WO_Factory_LoopBackSample_i() { } sample::LoopBackSample_ptr sample::WO_Factory_LoopBackSample_i::CreateServerObject( CORBA::Environment& _env) { WebOTX::WOServantCallback* servInfo = new loopbackCallback_i(); CORBA::Object_ptr obj = WebOTX::WOServantManager::CreateServant(servInfo); delete servInfo; return LoopBackSample::_narrow(obj); } void sample::WO_Factory_LoopBackSample_i::ReleaseServerObject( sample::LoopBackSample_ptr obj, CORBA::Environment& _env) { WebOTX::WOServantCallback* servInfo = new WO_Factory_loopbackCallback_i(); WebOTX::WOServantManager::ReleaseServant(servInfo, obj); delete servInfo; } ////////////////////////////////////////////////////// // コンポーネント初期化関数 #ifdef _WINDOWS #define LOOPBACKEXPORT __declspec(dllexport) #else #define LOOPBACKEXPORT #endif extern "C" LOOPBACKEXPORT void loopbackinit(); // ^^^^^^^^^^^^これがコンポーネント初期化関数になります extern "C" LOOPBACKEXPORT void loopbackinit() { // 実装情報を登録します WebOTX::WOComponent::add(new loopbackCallback_i); WebOTX::WOComponent::add(new WO_Factory_loopbackCallback_i); } ////////////////////////////////////////////////////// // 実装情報の設定部分 const char* loopbackCallback_i::_name() { return (const char*)"loopback"; } const char* loopbackCallback_i::_id() { return (const char*)"IDL:sample/LoopBackSample:1.0"; } PortableServer::Servant loopbackCallback_i::_newInstance() { sample::LoopBackSample_i* iobj = new sample::LoopBackSample_i; return iobj; } void loopbackCallback_i::_deleteInstance(PortableServer::Servant servant) { delete servant; } ////////////////////////////////////////////////////// const char* WO_Factory_loopbackCallback_i::_name() { return (const char*)"WO_Factory_loopback"; } const char* WO_Factory_loopbackCallback_i::_id() { return (const char*)"IDL:sample/WO_Factory_LoopBackSample:1.0"; } PortableServer::Servant WO_Factory_loopbackCallback_i::_newInstance() { sample::WO_Factory_LoopBackSample_i* iobj = new sample::WO_Factory_LoopBackSample_i; return iobj; } void WO_Factory_loopbackCallback_i::_deleteInstance(PortableServer::Servant servant) { delete servant; }コーディングそのものは通常のC++のコーディングと何ら変わりません。 WebOTXにはサーバアプリケーションの開発に役立つサーバAPIを用意しています(上記例ではTPSUserTrace()を使用しています)。サーバAPIの使い方については [リファレンス > API > WebOTXが提供するAPI > CORBA > WebOTX CORBA アプリケーション(C++) > サーバAPI ] を参照してください。 これで、サーバアプリケーションは完成しました。これをコンパイルしてライブラリを作成してください。
コンパイル中... U:\TestAPcl\loopbackcmn.cpp(980) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
IDL: test1.idl module AAAA { module BBBB { module CCCC { interface DDDD { void op1(); }; }; }; }; C++: test1_i.h namespace AAAA { namespace BBBB { namespace CCCC { class DDDD_i : public virtual POA_AAAA::BBBB::CCCC::DDDD { public: DDDD_i(); virtual ~DDDD_i(); void op1(CORBA::Environment& _env = Ob_default_environment()); }; }; }; }; C++: test1_i.C(test1_i.cpp) AAAA::BBBB::CCCC::DDDD_i::DDDD_i() { : } AAAA::BBBB::CCCC::DDDD_i::~DDDD_i() { : } void AAAA::BBBB::CCCC::DDDD_i::op1(CORBA::Environment& _env) { : }(b). sequence型とstruct型を利用している場合
IDL: test2.idl interface AAA { struct BBB { long ID; string NAME; short AGE; }; typedef sequence < BBB > SEQ001; void GET_DATA (in SEQ001 inARG, out SEQ001 outARG, inout SEQ001 inoutARG); }; C++: test2_i.h class AAA_i : public virtual POA_AAA { public: AAA_i(); virtual ~AAA_i(); void GET_DATA(const AAA::SEQ001& inARG, AAA::SEQ001*& outARG, AAA::SEQ001& inoutARG, CORBA::Environment& _env = Ob_default_environment() ); }; C++: test2_i.C(test2_i.cpp) AAA_i::AAA_i() { : } AAA_i::~AAA_i() { : } void AAA_i::GET_DATA( const AAA::SEQ001& inARG, AAA::SEQ001*& outARG, AAA::SEQ001& inoutARG, CORBA::Environment& _env ) { // inARGは値が設定されています。参照のみ可能です CORBA::ULong inARGlen = inARG.length(); CORBA::ULong i; for(i=0; i < inARGlen; i++) { CORBA::ULong id = inARG[i].ID; : } // outARGはAAA::SEQ001をnewして値を設定しなければなりません CORBA::ULong outARGlen = 5000; outARG = new AAA::SEQ001; outARG->length(outARGlen); for(i=0; i < outARGlen; i++) { (*outARG)[i].ID = 10; : } // inoutARGは値が設定されている。また書き換えもできます CORBA::ULong inoutARGlen = inoutARG.length(); for(i=0; i < outARGlen; i++) { inoutARG[i].ID = 10; : } : }
/opt/WebOTX/bin/makecpk loopback.spk module=loopback.so if=loopback.if
/opt/WebOTX/bin/makecpk loopback.cpk module=loopback.so if=loopback.if \ initfunc=loopbackinit useshareif=true
/opt/WebOTX/bin/makecpk loopback.cpk module=loopback.so if=loopback.if \ initfunc=loopbackinit useshareif=false
/opt/WebOTX/bin/makecpk loopback.cpk module=loopback.so \ if=loopback.if useshareif=false
単一常駐オブジェクト生成用関数 | extern "C"DLLEXPORT void* OnTPSPrecreatedUsersObject () |
単一常駐オブジェクト解放用関数 | extern "C"DLLEXPORT void OnTPSReleasePrecreatedUsersObject (void * preobj) |
単一常駐オブジェクトコーディング例
preobj1.def(Windowsのみ必要) ------------------------------- EXPORTS OnTPSPrecreatedUsersObject OnTPSReleasePrecreatedUsersObject OnTPSOperationStart OnTPSOperationNormal OnTPSOperationAbnormal OnTPSOperationAbort preobj1.h ------------------------------- #ifndef PREOBJ1_H_ #define PREOBJ1_H_ #if defined(WIN32) #if defined(PREOBJ1_EXPORTS) #ifndef PREOBJ1_EXPORTDEF #define PREOBJ1_EXPORTDEF __declspec(dllexport) #endif #else // !defined(PREOBJ1_EXPORTS) #define PREOBJ1_EXPORTDEF __declspec(dllimport) #endif #endif #else // !WIN32 #define PREOBJ1_EXPORTDEF #endif #endif class PREOBJ1_EXPORTDEF preobj1 { int m_db; public: preobj1(); ~preobj1(); void set(int db); int get(); }; #endif preobj1.C(Windowsの場合は.cpp) ------------------------------- #include #include "preobj1.h" #include "wotxexps.h" extern "C" PREOBJ1_EXPORTDEF void* OnTPSPrecreatedUsersObject(); extern "C" PREOBJ1_EXPORTDEF void OnTPSReleasePrecreatedUsersObject(void* ptr); extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationStart(void* ptr, const char* repositoryID, const char* opname); extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationNormal(void* ptr, const char* repositoryID, const char* opname); extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationAbnormal(void* ptr, const char* repositoryID, const char* opname, int status); extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationAbort(void* ptr, const char* repositoryID, const char* opname, int status); //==========================================================// PREOBJ1_EXPORTDEF preobj1::preobj1() { // 単一常駐オブジェクトのコンストラクタ m_db = 0; } PREOBJ1_EXPORTDEF preobj1::~preobj1() { // 単一常駐オブジェクトのデストラクタ } PREOBJ1_EXPORTDEF void preobj1::set(int db) { // 単一常駐オブジェクトのメソッド m_db = db; } PREOBJ1_EXPORTDEF int preobj1::get() { // 単一常駐オブジェクトのメソッド return m_db; //==========================================================// extern "C" PREOBJ1_EXPORTDEF void* OnTPSPrecreatedUsersObject() { // 単一常駐オブジェクトオブジェクトの生成 return (void*)new preobj1; } extern "C" PREOBJ1_EXPORTDEF void OnTPSReleasePrecreatedUsersObject(void* ptr) { // 単一常駐オブジェクトオブジェクトの解放 delete (preobj1*)ptr; } extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationStart(void* ptr, const char* repositoryID, const char* opname) { // オペレーション開始時に特別な処理を行う時に記述 } extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationNormal(void* ptr, const char* repositoryID, const char* opname) { // オペレーション正常終了時に特別な処理を行う時に記述 } extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationAbnormal(void* ptr, const char* repositoryID, const char* opname, int status) { // オペレーション異常終了時に特別な処理を行う時に記述 } extern "C" PREOBJ1_EXPORTDEF void OnTPSOperationAbort(void* ptr, const char* repositoryID, const char* opname, int status) { // オペレーションアボート時に特別な処理を行う時に記述 } //==========================================================//
オペレーションの開始 | extern "C"DLLEXPORT void OnTPSOperationStart ( void * preobj, const char* intf, const char* op ) |
オペレーションの正常終了 | extern "C"DLLEXPORT void OnTPSOperationNormal ( void * preobj, const char* intf, const char* op ) |
オペレーションの異常終了(TPSSetTxStatus()で0以外を設定したとき) | extern "C"DLLEXPORT void OnTPSOperationAbnormal ( void *preobj, const char* intf, const char* op, int status ) |
アボート(AbortExit()が呼ばれたときに、サーバオブジェクトのOnTPSAbort()より前に呼び出す) | extern "C"DLLEXPORT void OnTPSOperationAbort ( void *preobj, const char* intf, const char* op, int status ) |
複数常駐オブジェクトの生成用関数定義 | extern "C" DLLEXPORT void* OnTPSPrecreatedUsersObjectForPlural( const char* ident ); |
複数常駐オブジェクトの解放用関数定義 | extern "C" DLLEXPORT void OnTPSReleasePrecreatedUsersObjectForPlural( void* preobj, const char* ident ) |
mpreobj2.def(Windowsのみ必要) ------------------------------- EXPORTS OnTPSPrecreatedUsersObjectForPlural OnTPSReleasePrecreatedUsersObjectForPlural OnTPSOperationStartForPlural OnTPSOperationNormalForPlural OnTPSOperationAbnormalForPlural OnTPSOperationAbortForPlural mpreobj2.h ------------------------------- #ifndef MPREOBJ2_H_ #define MPREOBJ2_H_ #if defined(WIN32) #if defined(MPREOBJ2_EXPORTS) #ifndef MPREOBJ2_EXPORTDEF #define MPREOBJ2_EXPORTDEF __declspec(dllexport) #endif #else // !defined(PREOBJ1_EXPORTS) #define MPREOBJ2_EXPORTDEF __declspec(dllimport) #endif #endif #else // !WIN32 #define MPREOBJ2_EXPORTDEF #endif #endif class MPREOBJ2_EXPORTDEF mpreobj2 { int m_db; public: mpreobj2(); ~mpreobj2(); void set(int db); int get(); }; #endif mpreobj2.C(Windowsの場合は.cpp) ------------------------------- #include #include "mpreobj2.h" #include "wotxexps.h" extern "C" MPREOBJ2_EXPORTDEF void* OnTPSPrecreatedUsersObjectForPlural( const char* ID ); extern "C" MPREOBJ2_EXPORTDEF void OnTPSReleasePrecreatedUsersObjectForPlural( void* ptr, const char* ID ); extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationStartForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname ); extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationNormalForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname ); extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationAbnormalForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname, int status ); extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationAbortForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname, int status ); //==========================================================// MPREOBJ2_EXPORTDEF mpreobj2::mpreobj2() { // 複数常駐オブジェクトのコンストラクタ m_db = 0; } MPREOBJ2_EXPORTDEF mpreobj2::~mpreobj2() { // 複数常駐オブジェクトのデストラクタ } MPREOBJ2_EXPORTDEF void mpreobj2::set(int db) { // 複数常駐オブジェクトのメソッド m_db = db; } MPREOBJ2_EXPORTDEF int mpreobj2::get() { // 複数常駐オブジェクトのメソッド return m_db; } //==========================================================// extern "C" MPREOBJ2_EXPORTDEF void* OnTPSPrecreatedUsersObjectForPlural( const char* ID ) { // 複数常駐オブジェクトオブジェクトの生成 return (void*)new mpreobj2; } extern "C" MPREOBJ2_EXPORTDEF void OnTPSReleasePrecreatedUsersObjectForPlural( void* ptr, const char* ID ) { // 複数常駐オブジェクトオブジェクトの解放 delete (mpreobj2*)ptr; } extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationStartForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname ) { // オペレーション開始時に特別な処理を行う時に記述 } extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationNormalForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname ) { // オペレーション正常終了時に特別な処理を行う時に記述 } extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationAbnormalForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname, int status ) { // オペレーション異常終了時に特別な処理を行う時に記述 } extern "C" MPREOBJ2_EXPORTDEF void OnTPSOperationAbortForPlural( void* ptr, const char* ID, const char* repositoryID, const char* opname, int status ) { // オペレーションアボート時に特別な処理を行う時に記述 } //==========================================================//
オペレーションの開始 | extern "C"DLLEXPORT void OnTPSOperationStartForPlural ( void * preobj, const char* ident, const char* intf, const char* op) |
オペレーションの正常終了 | extern "C"DLLEXPORT void OnTPSOperationNormalForPlural ( void * preobj, const char* ident, const char* intf, const char* op) |
オペレーションの異常終了(TPSSetTxStatus()で0以外を設定したとき) | extern "C"DLLEXPORT void OnTPSOperationAbnormalForPlural ( void *preobj, const char* ident, const char* intf, const char* op, int status) |
アボート(AbortExit()が呼ばれたときに、サーバオブジェクトのOnTPSAbort()より前に呼び出す) | extern "C"DLLEXPORT void OnTPSOperationAbortForPlural ( void *preobj, const char* ident, const char* intf, const char* op, int status) |
#include "orb.h" #include "wotxexps.h" #include "preobj1.h" #include "mpreobj2.h" CORBA_Long foo_i::op1(CORBA_Long id, CORBA::Environment& _env) { // 常駐オブジェクトの変数を設定 preobj1* pPreobj1 = NULL; mpreobj2* pMpreobj2 = NULL; // 単一常駐オブジェクトの取得と呼び出し TPSGetPrecreatedUsersObject((void**)&pPreobj1); if (pPreobj1 != NULL) { 正常時の処理 常駐オブジェクトのメソッドを呼び出す } else { 異常時の処理 ユーザ定義の例外やエラー返却値を設定 } // 複数常駐オブジェクトの取得と呼び出し int nRet = TPSGetPrecreatedUsersObjectForPlural( "mpreobj2", (void**)&pMpreobj2 ); if (nRet == ERROR_PREOBJ_NO) { 正常時の処理 常駐オブジェクトのメソッドを呼び出す } else { 異常時の処理 ユーザ定義の例外やエラー返却値を設定 } }
: : : void foo::hoo () { const char* pgname = "PropertyGroupFoo"; // プロパティグループ名 long area = WOSP_AREATYPE_HOST; // ホスト内共有 WOPropertyGroup* wopg = NULL; long result = TPSCreatePropertyGroup(pgname, area, &wopg); if (result == WOSP_RC_DONE) { // 新規作成なのでプロパティも新規作成する const char* propertyName = "fooProperty"; WOProperty* woproperty = NULL; result = wopg->CreateProperty(propertyName, &woproperty); if (result != WOSP_RC_DONE) { : } // プロパティグループのロック WO_PG_WAITFLAG inWaitflag; inWaitflag = WO_PG_WAIT; // ロック取得まで待ち合わせる long waitsec = 3 * 1000; // 待ちあわせ時間 result = wopg->Lock(inWaitflag, waitsec); if (result != WOSP_RC_DONE) { : } // 値を設定 int nValue = 100; if (result == WOSP_RC_DONE || result == WOSP_RC_ALREADY) { woproperty->Set(nValue); } else { // 異常系処理 : : } : : // プロパティグループのアンロック result = wopg->Unlock(); if (result != WOSP_RC_DONE) { : } } else { // 既に存在するので、プロパティを取得する const char* propertyName = "fooProperty"; WOProperty* woproperty = NULL; result = wopg->GetProperty(propertyName, &woproperty); if (result != WOSP_RC_DONE) { : } // プロパティグループのロック WO_PG_WAITFLAG inWaitflag; inWaitflag = WO_PG_WAIT; // ロック取得まで待ち合わせる long waitsec = 3 * 1000; // 待ちあわせ時間 result = wopg->Lock(inWaitflag, waitsec); if (result != WOSP_RC_DONE) { : } // 値の取得 int nValue; if (result == WOSP_RC_DONE || result == WOSP_RC_ALREADY) { woproperty->Get(nValue); } else { // 異常系処理 : : } : : // プロパティグループのアンロック result = wopg->Unlock(); if (result != WOSP_RC_DONE) { : } } } : :
module Pet { interface Dog : ::Animal { long bark(); }; interface Cat : ::Animal { long jump(); }; };
woigenxx -R com1.idl -R com2.idl extends
#include "Animal.h" #include "Animal_i.h" class Pet_dog_i : public virtual POA_Pet_dog , public virtual Animal_i{ : }
#include "Animal.h" class Pet_dog_i : public virtual POA_Pet_dog { <dd>: }
igenxx -i Animal.idl
extern "C" WO_USER_EXPORT int WebOTX_Init() { return 0; } extern "C" WO_USER_EXPORT void WebOTX_Term() { return ; }
オペレーション操作関連 | |
---|---|
TPSSetTxStatus() | × オペレーション呼び出し中のみ意味があるため |
TPSRegisterDB() | × オペレーション呼び出し中のみ意味があるため |
TPSAbort() | × オペレーション呼び出し中のみ意味があるため |
TPSRestart() | × オペレーション呼び出し中のみ意味があるため |
トレース関連 | |
TPSUserTrace() | △ トレースレベル1または2のときのみ出力可能 |
TPSGetUserTraceLevel() | ○ |
TPSEventJournal() | ○ |
情報取得 | |
TPSGetLid() | × オペレーション呼び出し中のみ意味があるため |
TPSGetTerminalIP() | × オペレーション呼び出し中のみ意味があるため |
TPSGetArgumentCount() | ○ |
TPSGetArgumentValue() | ○ |
TPSGetServerInformation() | △ 一部情報が欠落する(後述) |
CORBAオブジェクト関連 | |
TPSGetORB() | ○ |
TPSGetMyPOA() | ○ |
TPSGetInitialReference() | ○ |
常駐オブジェクト関連 | |
TPSGetPrecreatedUsersObject() | × オペレーション呼び出し中のみ意味があるため |
TPSGetPrecreatedUsersObjectForPlural() | × オペレーション呼び出し中のみ意味があるため |
SPA関連 | |
TPSGetSpa() | × オペレーション呼び出し中のみ意味があるため |
TPSSetSpaFlag() | × オペレーション呼び出し中のみ意味があるため |
共有プロパティ関連 | |
TPSCreatePropertyGroup() | ○ |
TPSGetPropertyGroup() | ○ |
VDサーバ関連(OLF/TP-UT) | |
TPSVDSend() | ○ |
WebOTXの情報: | |
アプリケーショングループ名 | ○ |
プロセスグループ名 | × プロセスグループ単位の指定パラメータのため |
ステートフルかステートレスか | × プロセスグループ単位の指定パラメータのため |
スレッドモデル | × プロセスグループ単位の指定パラメータのため |
IIOPリスナポート番号 | ○ |
クライアント管理ライブラリポート | ○ |
常駐オブジェクトクラス名 | × プロセスグループ単位の指定パラメータのため |
OTS連携を行うか | × プロセスグループ単位の指定パラメータのため |
システムID | ○ |
接続サーバ名 | ○ |
名前サーバ名 | ○ |
名前サーバに登録するリファレンスの数 | ○ |
ファクトリを使うかどうか | × プロセスグループ単位の指定パラメータのため |
Oracle連携するかどうか | × プロセスグループ単位の指定パラメータのため |
SQL/Netを使用するか | × プロセスグループ単位の指定パラメータのため |
Oracle連携用のSID名 | × プロセスグループ単位の指定パラメータのため |
Oracle連携用のユーザ名とパスワード | × プロセスグループ単位の指定パラメータのため |
// MyDB.hファイル #include "orb.h" #include "wotxexps.h" #ifndef MYDB_H #define MYDB_H class MyDB : public WebOTX_DB { public: MyDB(); ~MyDB(); 独自の機能 void commit(); // 独自の機能 void rollback(); // 純仮想関数に対する定義 }; #endif // MyDB.C(WindowsではMyDB.CPP)ファイル #include "orb.h" #include "wotxexps.h" #include "MyDB.h" MyDB::MyDB() { // DBへの接続処理(独自処理) } MyDB::~MyDB() { // DBとの切断処理(独自処理) } void MyDB::insert(char* data1, char* data2) { // テーブルにデータを追加(独自処理) } void MyDB::commit() { // コミット処理(独自処理) } void MyDB::rollback() { // ロールバック処理(例外時に呼ばれる) }以上のクラス定義を行い、サーバオブジェクト内にてMyDB db = new MyDB;を行ってTPSRegisterDB(db)を実行してください。
: export PATH=$PATH:/opt/WebOTX/ObjectBroker/bin:/opt/WebOTX/dev/bin : export LD_LIBRARY_PATH=/opt/WebOTX/ObjectBroker/namespace/lib: \ /opt/WebOTX/dev/lib :
#----------------------------------------------------------------------- # for Linux #----------------------------------------------------------------------- CC = /usr/bin/g++ WOIGENXX = /opt/WebOTX/dev/bin/woigenxx BASENAME = loopback LIBS = -lpthread -ldl \ -L/opt/WebOTX/ObjectBroker/namespace/lib -lnsospi \ -L/opt/WebOTX/dev/lib -lnWOBSE91 OBJS = ${BASENAME}cmn.o \ ${BASENAME}cl.o INC = -I/opt/WebOTX/dev/include \ -I/opt/WebOTX/ObjectBroker/namespace/include LDFLAGS = C++FLAGS = -D_REENTRANT -D_GNU_SOURCE -fPIC TARGET = ${BASENAME}cl all : ${OBJS} ${TARGET} ${TARGET} : ${OBJS} ${CC} -o $@ ${C++FLAGS} ${LDFLAGS} ${OBJS} ${LIBS} ${BASENAME}cmn.o : ${BASENAME}cmn.C ${BASENAME}.h .C.o : ${CC} ${INC} ${C++FLAGS} -c $*.C idl: ${WOIGENXX} ${BASENAME} clean: /bin/rm -rf *.o ${TARGET}
#----------------------------------------------------------------------- # for Windows(Intel 64) #----------------------------------------------------------------------- !include OUTDIR=.\Release INTDIR=.\Release # Begin Custom Macros OutDir=.\Release # End Custom Macros OTXDIR=C:\Program Files\NEC\WebOTX OSPIDIR=$(OTXDIR)\ObjectBroker ALL : "$(OUTDIR)\$(BASENAME)cl.exe" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ = /nologo /MD /W3 /GX /O2 \ /I "$(OSPIDIR)\namespace\include" \ /I "$(OTXDIR)\dev\include" \ /D "WIN32" /D "WIN64" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" \ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << LINK=link.exe LINK_FLAGS=nosp9011.lib nWOBS97.lib \ /nologo /incremental:no /pdb:"$(OUTDIR)\$(BASENAME)cl.pdb" \ /machine:AMD64 /out:"$(OUTDIR)\$(BASENAME)cl.exe" \ /libpath:"$(OSPIDIR)\namespace\lib" \ /libpath:"$(OTXDIR)\dev\lib" LINK_OBJS= \ "$(INTDIR)\$(BASENAME)cl.obj" \ "$(INTDIR)\$(BASENAME)cmn.obj" "$(OUTDIR)\$(BASENAME)cl.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << SOURCE=.\$(BASENAME)cl.cpp "$(INTDIR)\$(BASENAME)cl.obj" : $(SOURCE) "$(INTDIR)" SOURCE=.\$(BASENAME)cmn.cpp "$(INTDIR)\$(BASENAME)cmn.obj" : $(SOURCE) "$(INTDIR)"
#include <stdio.h> #include "orb.h" #include "loopback.h" int main (int argc, char **argv) { // ORBの初期化 try { CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, ""); // 名前サーバオブジェクトリファレンスの取得 CORBA::Object_var obj = orb->resolve_initial_references("NameService"); CosNaming::NamingContext_var nmctx = CosNaming::NamingContext::_narrow(obj); // サーバオブジェクトリファレンスの取得 CosNaming::Name objname; objname.length(6); // コンテキスト+1 objname[0].id = (const char*)"NEC"; objname[0].kind = (const char*)""; objname[1].id = (const char*)"WebOTX"; objname[1].kind = (const char*)""; objname[2].id = (const char*)"WO_Default"; objname[2].kind = (const char*)""; objname[3].id = (const char*)"sample"; objname[3].kind = (const char*)""; objname[4].id = (const char*)"LoopBackSample"; objname[4].kind = (const char*)""; objname[5].id = (const char*)"1"; // バージョン番号 objname[5].kind = (const char*)""; obj = nmctx->resolve(objname); sample::LoopBackSample_ptr svobj = sample::LoopBackSample::_narrow(obj); // オペレーション呼出し const char* instr = "AaBbCc"; char* outstr; int result = svobj->LoopBack (instr,outstr); printf("LoopBack %s -> %s\n",instr,outstr); CORBA::string_free(outstr); result = svobj->LowerCase (instr,outstr); printf("LowerCase %s -> %s\n",instr,outstr); CORBA::string_free(outstr); result = svobj->UpperCase (instr,outstr); printf("UpperCase %s -> %s\n",instr,outstr); CORBA::string_free(outstr); // サーバオブジェクトリファレンスの解放 CORBA::release(svobj); return 0; } catch (CORBA::SystemException& e) { printf("Occurred exception."); printf(" ID=%s minor=%d\n",e.__id(), e.minor()); return -1; } catch (CORBA::Exception& e) { printf("Occurred exception."); printf(" ID=%s \n", e.__id()); return -1; } }
#include <stdio.h> #include "orb.h" #include "loopback.h" int main (int argc, char **argv) { // ORBの初期化 try { CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, ""); // 名前サーバオブジェクトリファレンスの取得 CORBA::Object_var obj = orb->resolve_initial_references("NameService"); CosNaming::NamingContext_var nmctx = CosNaming::NamingContext::_narrow(obj); // ファクトリオブジェクトリファレンスの取得 CosNaming::Name objname; objname.length(6); // コンテキスト+1 objname[0].id = (const char*)"NEC"; objname[0].kind = (const char*)""; objname[1].id = (const char*)"WebOTX"; objname[1].kind = (const char*)""; objname[2].id = (const char*)"WO_Default"; objname[2].kind = (const char*)""; objname[3].id = (const char*)"sample"; objname[3].kind = (const char*)""; objname[4].id = (const char*)"WO_Factory_LoopBackSample"; objname[4].kind = (const char*)""; objname[5].id = (const char*)"1"; // バージョン番号 objname[5].kind = (const char*)""; obj = nmctx->resolve(objname); sample::WO_Factory_LoopBackSample_ptr fobj = sample::WO_Factory_LoopBackSample::_narrow(obj); // サーバオブジェクトリファレンスの取得 sample::LoopBackSample_ptr svobj = fobj->CreateServerObject(); // オペレーション呼出し const char* instr = "AaBbCc"; char* outstr; int result = svobj->LoopBack (instr,outstr); printf("LoopBack %s -> %s\n",instr,outstr); CORBA::string_free(outstr); result = svobj->LowerCase (instr,outstr); printf("LowerCase %s -> %s\n",instr,outstr); CORBA::string_free(outstr); result = svobj->UpperCase (instr,outstr); printf("UpperCase %s -> %s\n",instr,outstr); CORBA::string_free(outstr); // サーバオブジェクトリファレンスの解放 fobj->ReleaseServerObject(svobj); CORBA::release(svobj); // ファクトリオブジェクトリファレンスの解放 CORBA::release(fobj); return 0; } catch (CORBA::SystemException& e) { printf("Occurred exception."); printf(" ID=%s minor=%d\n",e.__id(), e.minor()); return -1; } catch (CORBA::Exception& e) { printf("Occurred exception."); printf(" ID=%s \n", e.__id()); return -1; } }
#include <stdio.h> #include "orb.h" #include "loopback.h" #include "WOTrmMan.h" int main (int argc, char **argv) { try { // ORBの初期化 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, ""); // 名前サーバオブジェクトリファレンスの取得 CORBA::Object_var obj = orb->resolve_initial_references("NameService"); CosNaming::NamingContext_var nmctx = CosNaming::NamingContext::_narrow(obj); // ファクトリオブジェクトリファレンスの取得 CosNaming::Name objname; objname.length(6); objname[0].id = (const char*)"NEC"; objname[0].kind = (const char*)""; objname[1].id = (const char*)"WebOTX"; objname[1].kind = (const char*)""; objname[2].id = (const char*)"WO_Default"; objname[2].kind = (const char*)""; objname[3].id = (const char*)"sample"; objname[3].kind = (const char*)""; objname[4].id = (const char*)"WO_Factory_LoopBackSample"; objname[4].kind = (const char*)""; objname[5].id = (const char*)"1"; // バージョン番号 objname[5].kind = (const char*)""; obj = nmctx->resolve(objname); sample::WO_Factory_LoopBackSample_ptr fobj = sample::WO_Factory_LoopBackSample::_narrow(obj); // クライアント管理ライブラリへの登録 WO_TerminalManager woterm; woterm.SetFactoryObject(fobj); // サーバオブジェクトリファレンスの取得 sample::LoopBackSample_ptr svobj = fobj->CreateServerObject(); // オペレーション呼出し const char* instr = "AaBbCc"; char* outstr; int result = svobj->LoopBack (instr,outstr); printf("Loopback %s -> %s\n",instr,outstr); CORBA::string_free(outstr); result = svobj-> LowerCase (instr,outstr); printf("LowerCase %s -> %s\n",instr,outstr); CORBA::string_free(outstr); result = svobj-> UpperCase (instr,outstr); printf("UpperCase %s -> %s\n",instr,outstr); CORBA::string_free(outstr); // サーバオブジェクトリファレンスの解放 fobj->ReleaseServerObject(svobj); CORBA::release(svobj); // ファクトリオブジェクトリファレンスの解放 CORBA::release(fobj); return 0; } catch (CORBA::SystemException& e) { printf("Occurred exception."); printf(" ID=%s minor=%d\n",e.__id(), e.minor()); return -1; } catch (CORBA::Exception& e) { printf("Occurred exception."); printf(" ID=%s \n", e.__id()); return -1; } }修正個所には下線をつけています。これで、無通信監視機能、非同期メッセージ表示機能が使えます。 なお、クライアント管理ライブラリの有効範囲はWO_TerminalManagerオブジェクトが有効な間だけです。 非同期メッセージ表示機能にはダイアログボックスを表示するほかに、メッセージを送信する拡張機能があります。これを使うことより、非同期メッセージを受信した後の動作を独自に実装することが出来ます。クライアント管理ライブラリに関するAPIについては [ リファレンス > API > WebOTXが提供するAPI > CORBA > WebOTX CORBA アプリケーション(C++) > クライアント管理ライブラリAPI ] を参照してください。
+----------------------------------------+ |C++スタブ/スケルトンコードのオブジェクト| IDLコンパイラが自動生成部分 +----------------------------------------+ |COBOLを呼び出すC++のコードのオブジェクト| サーバント部分 +==============extern "C"================+ | COBOLコードのオブジェクト | COBOL部分 +----------------------------------------+
IDLコンパイラが自動生成部分
|
WebOTXおよびObject
BrokerのIDLコンパイラがIDLファイルを入力することで生成されるものです。
|
---|---|
サーバント部分
|
ユーザが任意の処理を記述する部分です。
C++言語のみのサーバコンポーネントはここにビジネスロジックを記述しますが、
COBOL言語使用時は主にCOBOLコードを呼び出し値を返却するロジックを記述します。
|
COBOL部分
|
ビジネスロジックを記述します。 COBOLサーバコンポーネントを作成する場合は、
COBOLのソースファイルからネイティブオブジェクト(.o)ファイルを生成してリンクします。
|
形式
|
woi2j IDLファイル名(拡張子.idlは削除) [-tie] [-R
IDLファイル名]* [-wofactoryless [-wobase]]
|
---|---|
機能
|
WebOTXのJava用IDLコンパイルの実行
|
オプション
|
|
注意事項
|
形式
|
woixj ifファイル名(拡張子ifは不要) [-init
コンポーネント初期化クラス名] [-I
<インタフェース名>,<実装クラス名>]* [-f設定ファイル名] [-tie]
[-out出力先ディレクトリパス] [-prop プロパティファイル名]
|
---|---|
機能
|
コンポーネント初期化クラス、実装情報定義クラスを生成します
|
オプション
|
|
注意事項
|
形式
|
woigenxx IDLファイル名(拡張子.idlは削除) [-tie] [-R
IDLファイル名]* [-wofactoryless [-wobase]]
|
---|---|
機能
|
WebOTXのC++用IDLコンパイルの実行
|
オプション
|
|
注意事項
|
形式
|
woixcpp ifファイル名(拡張子ifは不要) [-init
コンポーネント初期化クラス名] [-I
<インタフェース名>,<実装クラス名>]* [-f設定ファイル名]
[-out出力先ディレクトリパス] [-prop プロパティファイル名]
|
---|---|
機能
|
コンポーネント初期化クラス、実装情報定義クラスを生成します
|
オプション
|
|
注意事項
|
パッケージ名
|
クラス
|
メソッド
|
---|---|---|
org.omg.CORBA
|
ORB
|
poll_next_response()
|
get_next_response()
|
||
work_pending()
|
||
perform_work()
|
||
run()
|
||
jp.co.nec.orb
|
Config
|
setServerRecvTimeout()
|
getServerRecvTimeout()
|
||
setServerPort()
|
||
synchronizedPerObject()
|
||
asynchronizedPerObject()
|
||
setPerClientThreadPolicy()
|
||
setPooledThreadPolicy()
|
||
setNoDelay()
|
||
corbalocAskWithMT
|
||
setCorbalocServerPort
|
名前空間
|
クラス
|
メソッド
|
---|---|---|
CORBA
|
ORB
|
poll_next_response()
|
get_next_response()
|
||
work_pending()
|
||
perform_work()
|
||
run()
|
||
Environment
|
__connection ()
|
|
Ob_SvrCon
|
get_peer()
|
|
なし
|
Ob_SvrInitialArg
|
Ob_SvrInitialArg()
|
this_object()
|
パッケージ名
|
クラス
|
メソッド
|
---|---|---|
jp.co.nec.orb
|
HookObj
|
全て(サーバアプリケーション)
|
パッケージ名
|
クラス
|
メソッド
|
---|---|---|
なし
|
Ob_MesBufHook
|
全て(サーバアプリケーション)
|
CORBA
|
orb
|
__stop()
|
__is_active()
|
/ +---- リポジトリID;ファイル名 (例: IDL:LoopBackSample:1.0;loopback.jar) +---- リポジトリID;ファイル名 | : | : +---- リポジトリID;ファイル名よって、WebOTXが生成するPOAを使用したい場合は、上記命名規則に従って検索してください。
CORBA::PolicyList policies(5); policies.length(5); policies[0] = rootPOA->create_servant_retention_policy( PortableServer::NON_RETAIN); policies[1] = rootPOA->create_id_uniqueness_policy( PortableServer::MULTIPLE_ID); policies[2] = rootPOA->create_request_processing_policy( PortableServer::USE_SERVANT_MANAGER); policies[3] = rootPOA->create_lifespan_policy( PortableServer::PERSISTENT); policies[4] = rootPOA->create_id_assignment_policy( PortableServer::USER_ID);
Policy[] policies = new Policy[5]; policies[0] = rootPOA.create_servant_retention_policy( ServantRetentionPolicyValue.NON_RETAIN); policies[1] = rootPOA.create_id_uniqueness_policy( IdUniquenessPolicyValue.MULTIPLE_ID); policies[2] = rootPOA.create_request_processing_policy( RequestProcessingPolicyValue.USE_SERVANT_MANAGER); policies[3] = rootPOA.create_lifespan_policy( LifespanPolicyValue.PERSISTENT); policies[4] = rootPOA.create_id_assignment_policy( IdAssignmentPolicyValue.USER_ID);
CORBA::PolicyList policies(4); policies.length(4); policies[0] = rootPOA->create_servant_retention_policy( PortableServer::NON_RETAIN); policies[1] = rootPOA->create_request_processing_policy( PortableServer::USE_SERVANT_MANAGER); policies[2] = rootPOA->create_lifespan_policy( PortableServer::PERSISTENT); policies[3] = rootPOA->create_id_assignment_policy( PortableServer::USER_ID);
Policy policies[] = new Policy[4]; policies[0] = rootPOA.create_servant_retention_policy( ServantRetentionPolicyValue.NON_RETAIN); policies[1] = rootPOA.create_request_processing_policy( RequestProcessingPolicyValue.USE_SERVANT_MANAGER); policies[2] = rootPOA.create_lifespan_policy( LifespanPolicyValue.PERSISTENT); policies[3] = rootPOA.create_id_assignment_policy( IdAssignmentPolicyValue.USER_ID);