ここでは、以下の項目について説明します。
クライアントが CORBA オブジェクトのオペレーションを呼び出すには、クライアントとサーバ (オブジェクトの実装) の両方が ORB (Object Request Broker) という CORBA ソフトウェアコンポーネントを使用する必要があります。ORB は、クライアントとサーバとで異なる位置、プラットフォーム、およびプログラム言語の違いを埋める役目を果たす共通の基準です。ORB は、ネットワーク経由で互いにコンタクトをとることが可能で、オブジェクトの参照 (CORBA オブジェクトハンドル) を作成および解釈することができます。また、パラメータを IIOP が使用する形式に整列化したり、IIOP が使用する形式から他の形式に整列化することもできます。ここでは説明を省略しますが、ORB は、クライアント/サーバ通信以外のサービスも提供します。
CORBA オブジェクトのオペレーションを呼び出すには、次の 2 通りの方法があります。
CORBA オブジェクトで静的な呼び出しを行う場合、Java クライアントには、オペレーションを実行するサーバントへのオブジェクト参照が必要になります。オブジェクト参照には、次の 2 つの重要な機能があります。
OMG IDL は、CORBA オブジェクトのインタフェースを定義する言語です。idltojava コンパイラは、OMG IDL モジュールごとに Java パッケージを生成します。OMG IDL モジュールで定義された各インタフェース Foo
に対して生成されたパッケージには、クライアントプログラマにとって有用な以下の項目が含まれています。
Foo
。開発者の見地からは、CORBA の Foo
オブジェクトのオブジェクト参照は、このインタフェースを実装しています。
FooHelper
クラス。このクラスは、補助メソッド、特に Java のキャストに対応する CORBA の narrow()
を定義します。
次にクライアント側から見た簡単な例を示します。
OMG IDL |
生成された Java |
---|---|
module Example { interface Counter { boolean increment (in long arg); }; }; |
package Example; public interface Counter extends org.omg.CORBA.Object { public boolean increment (int arg); } public class CounterHelper { public static Counter narrow (org.omg.CORBA.Object obj); // ... } public final class CounterHolder { // ... } |
次に示す Java コードの一部は、この CORBA オブジェクトのインスタンスの宣言および呼び出しを行う上でのポイントを示しています。
import Example.* // get the interface and helper Counter anInstance = // acquire a reference boolean aResult; int anArg = 10; aResult = anInstance.increment(anArg);
「スタブ」は、クライアントを、目的の CORBA オブジェクト型に対応した ORB に適合させます。ORB は、引数を整列化することはできますが、特定のメソッドに渡すためにどの引数を整列化すべきかはわかりません。スタブは型指定であるため、メソッドごとに整列化の必要な引数を識別できます。クライアントがスタブメソッドを呼び出すと、スタブはクライアントの ORB に何を整列化するか指示し、それから ORB にオブジェクト参照によって識別した CORBA オブジェクトを呼び出すよう指示します。クライアントの ORB は、オブジェクト参照を使用して、どのリモート ORB が呼び出しを受け取るべきかを決定し、整列化したパラメータをネットワーク経由でその ORB に渡し、結果を待ちます (CORBA オブジェクトの呼び出しは、リモートプロシージャ呼び出しに類似している)。
「スケルトン」は、クライアントスタブのオブジェクトサーバアナログです。 スケルトンは、IDL コンパイラによっても生成されます。ORB がそのオブジェクトの 1 つの呼び出しを受け取った場合のプロセスは、次のようになります。
つまり、IIOP ORB はネットワーク経由の CORBA オブジェクト呼び出しを標準化された方式で行います。ORB オペレーションはすべて、呼び出されるオブジェクト型、およびクライアントとサーバが記述された言語から独立しています。スタブおよびスケルトンは、クライアントとサーバを特定の CORBA オブジェクト型の ORB と一致させる役割を果たします。
CORBA の動的な呼び出しは、request というオブジェクトを使用し、呼び出しに関係のあるすべてのもの、つまりオブジェクト参照、オペレーションの名前とそのパラメータ、および結果用のスペースを確保します。クライアントは、オペレーションを記述する request オブジェクトを構築し、その invoke
メソッドを呼び出します。このメソッドはスタブと同様の方法で要求をディスパッチします。invoke メソッドが返されると、その結果は request オブジェクトで利用できるようになります。
動的な呼び出しの鍵となるのは、自己記述型データを保持する要求機能です。この機能により、request オブジェクトは、パラメータに関係なく、任意のオペレーションの任意の呼び出しを代理実行できます。自己記述型データの各要素は、OMG IDL では Any
という特別な型を持っています。Any
は、タイプコード (その値は OMG IDL により定義されている) と値で構成され、タイプコードには値の型を指定します。
次の例は、動的な呼び出しを行う上でのポイントを示しています。呼び出される CORBA オブジェクトには、次の OMG IDL インタフェースが定義されています。
import org.omg.CosNaming.*; import org.omg.CORBA.*; public class CounterClient { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // resolve the Object Reference in Naming NameComponent nc = new NameComponent("Counter", ""); NameComponent path[] = {nc}; Counter counterRef = CounterHelper.narrow(ncRef.resolve(path)); System.out.println("Object Ref: " + orb.object_to_string(counterRef)); // Create a DII request and set the arguments and result org.omg.CORBA.Request r = counterRef._request("increment"); r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long)); org.omg.CORBA.Any inc = r.add_in_arg(); inc.insert_long(1); // increment by 1 for (int i = 0; i < 10; i++) { // call the Hello server object and print results r.invoke(); java.lang.Exception ex = r.env().exception(); if (ex instanceof org.omg.CORBA.UnknownUserException) { org.omg.CORBA.UnknownUserException userEx = (org.omg.CORBA.UnknownUserException) ex; } // extract the result int result; result = r.return_value().extract_long(); System.out.println("Counter: " + result); } } catch (Exception e) { System.out.println("CounterClient : Exception: " + e) ; e.printStackTrace(System.out); } } }
Web ブラウザの中には、内部に ORB を直接構築しているものがあります。このようなブラウザでは、ORB が完全に標準に準拠していない場合、問題が発生することがあります。この場合、Java IDL ORB を初期化する特別の手順を実行する必要があります。たとえば、Netscape Communicator 4.01 にインストールされている ORB には特定のクラスが欠けているため、このブラウザで表示するアプレットには、次に示すようなコードを init() メソッド内に記述する必要があります。
import java.util.Properties; import org.omg.CORBA.*; public class MyApplet extends java.applet.Applet { public void init() { // Instantiate the Sun ORB, passing in this applet // so that the ORB can retrieve the applet properties. Properties props = new Properties(); props.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); ORB orb = ORB.init(this, props); ... } }
クライアント | サーバ | 例外 | 初期化 | ネームサービス
ホーム |
概念 |
プログラミング |
リファレンス |
チュートリアル |