クライアントの開発


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

ORB と呼び出し

クライアントが 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 に対して生成されたパッケージには、クライアントプログラマにとって有用な以下の項目が含まれています。

次にクライアント側から見た簡単な例を示します。

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 つの呼び出しを受け取った場合のプロセスは、次のようになります。

  1. ORB はオブジェクト参照を検査し、オブジェクトのサーバントを識別します。
  2. それから ORB は適切なスケルトンを呼び出します。このスケルトンは ORB にパラメータの非整列化の手順についての情報を提供します。
  3. ORB は、クライアントが要求したオペレーションのサーバント実装を呼び出します。
  4. サーバントメソッドは、スケルトンに結果を返します。
  5. スケルトンは、サーバ ORB に対して整列化を取り決めます
  6. サーバ ORB は、結果をクライアント ORB に返します。
  7. クライアント ORB は、結果をスタブに返します。
  8. スタブは、結果をクライアントに返します。

つまり、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);
        ...
      }
    }
 


クライアント | サーバ | 例外 | 初期化 | ネームサービス

ホーム

概念

プログラミング

リファレンス

チュートリアル


Copyright © 1996, 1997 Sun Microsystems, Inc., 2550 Garcia Ave., Mtn. View, CA. 94043-1100 USA., All rights reserved.