レッスン 4: Hello World サーバの開発


このレッスンでは、CORBA 一時サーバ作成の基本を学びます。このレッスンの手順は次のとおりです。

  1. 基本設定
  2. ORB オブジェクトの作成
  3. サーバントオブジェクトの管理
  4. COS ネーミングの利用
  5. 呼び出し待ち
  6. Hello World サーバのコンパイルと実行

完成した HelloServer.java ファイルを見るには、HelloServer.java をクリックしてください。

基本設定

CORBA サーバプログラムの構造は、ほとんどの Java アプリケーションと同じです。つまり、必要なライブラリパッケージをインポートし、サーバクラスを宣言し、main() メソッドを定義し、例外の処理を行います。

必要なパッケージのインポート

テキストエディタを起動して、HelloServer.java という名前のファイルを保存します。

クライアントクラスに必要なパッケージをインポートします。

// The package containing our stubs.
import HelloApp.*;

// HelloServer will use the naming service.
import org.omg.CosNaming.*;

// The package containing special exceptions thrown by the name service.
import org.omg.CosNaming.NamingContextPackage.*;

// All CORBA applications need these classes.
import org.omg.CORBA.*;

サーバクラスの宣言

次のように、サーバクラスを宣言します。

public class HelloServer 
{
  // Add the main() method here in the next step.
}

main() メソッドの定義

次のように、標準の main() メソッドを宣言します。

  public static void main(String args[])
  {
    // Add the try-catch block here in the next step.
  }

CORBA システム例外の処理

どの CORBA プログラムでも、実行時に CORBA システム例外が発生する可能性があるので、main() メソッドの機能は、すべて try-catch ブロック内に記述します。CORBA プログラムは、呼び出しに伴うプロセス (整列化、非整列化、アップコール) で問題が発生すると、システム例外を発生させます。このレッスンの例外ハンドラは簡単なもので、どんな問題が起こったかが分かるように、例外の名前とそのスタックトレースを標準出力に出力します。

main() の中に、以下の try-catch ブロックを記述します。

    try{
    
      // Add the rest of the HelloServer code here.
    
    } catch(Exception e) {
        System.err.println("ERROR: " + e);
        e.printStackTrace(System.out);
    }

ファイルを保存します。

ORB オブジェクトの作成

クライアントと同様に、CORBA サーバにもローカルの ORB オブジェクトが必要です。各サーバは ORB のインスタンスを生成し、ORB が呼び出しを受けたときにサーバを検索できるように、ORB の サーバントオブジェクトを登録します。

HelloServer.java が閉じている場合は、ここで開きます。

try-catch ブロックの中で、ORB 変数を宣言して初期化します。

      ORB orb = ORB.init(args, null);

ORB の init() メソッドの呼び出しは、サーバのコマンド行引数に渡されるので、実行時に特定のプロパティを設定できます。

ここで必ずファイルを保存してください。

サーバントオブジェクトの管理

サーバとは、1 つ以上のサーバントオブジェクトのインスタンスを生成するプロセスです。サーバントは、idltojava が生成したインタフェースを実装し、そのインタフェース上で実際のオペレーションを行います。このレッスンの HelloServer には 1 つの HelloServant が必要です。

サーバントオブジェクトのインスタンスの生成

HelloServer.java が閉じている場合は、ここで開きます。

try-catch ブロックの中で、init() の直後にサーバントオブジェクトのインスタンスを生成します。

      HelloServant helloRef = new HelloServant();

このサーバントクラスはまだ定義されていません。後のステップで定義します。

ORB が呼び出しを受けたときにそれを認識し、正しいサーバントに引き渡せるように、サーバントを ORB に結合します。

      orb.connect(helloRef);

サーバントクラスの定義

HelloServer.java の最後に、HelloServer クラスの外側にサーバントオブジェクトのためのクラスを定義します。

  1. サーバントクラスを宣言します。
    class HelloServant extends _HelloImplBase
    {
      // Add the sayHello() method here in the next step.
    }
    

    このサーバントは _HelloImplBase のサブクラスなので、コンパイラが _HelloImplBase のために生成した共通の CORBA 機能を継承します。

  2. sayHello() メソッドが必要なので、ここで宣言します。
      public String sayHello()
      {
        // Add the method implementation here in the next step.
      }
    
  3. sayHello() の実装コードを記述します。
    return "\nHello world!!\n";
    
  4. HelloServer.java を保存します。

COS ネーミングの利用

HelloServer はネームサービスを利用して、クライアント側からサーバントオブジェクトのオペレーションを利用可能にします。サーバが自らを登録し、Hello インタフェースでの呼び出しが確実にサーバのサーバントオブジェクトに渡されるために、サーバはネームサービスへのオブジェクト参照を必要とします。

初期ネーミングコンテキストの取得

try-catch ブロックの中で、サーバントのインスタンス生成の次に、orb.resolve_initial_references() を呼び出してネームサーバへのオブジェクト参照を取得します。

      org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

文字列 NameService は、すべての CORBA ORB に対して定義されています。この文字列を渡すと、ORB はネームサービスへのオブジェクト参照であるネーミングコンテキストオブジェクトを返します。

オブジェクト参照のナロー変換

CORBA のどのオブジェクト参照とも同様に、objRef は汎用の CORBA オブジェクトです。これを NamingContext オブジェクトとして使うには、適切な型にナロー変換する必要があります。前の文の直後に narrow() の呼び出しを追加します。

      NamingContext ncRef = NamingContextHelper.narrow(objRef);

これは、idltojava から生成されるヘルパークラスの使用方法です。このクラスの機能は HelloHelper の機能に類似しています。ここで ncRef オブジェクトは org.omg.CosNaming.NamingContext になったので、これを使ってネームサービスにアクセスし、サーバを登録することができます。次のステップで、その処理を行います。

ネームサーバへのサーバントの登録

  1. narrow() の呼び出しの直後に、新しい NameComponent メンバを作成します。
          NameComponent nc = new NameComponent("Hello", "");
    

    この文は、ncid フィールドに 「Hello」を設定し、kind フィールドに空白文字列を設定します。

    NamingContext.resolve には作業用に配列が必要です。 Hello オブジェクトへのパスには要素が 1 つしかないので、単一要素の配列を作成します。

          NameComponent path[] = {nc};
    
  2. path とサーバントオブジェクトをネームサービスに引き渡して、サーバントオブジェクトを 「Hello」id に結びつけます。
          ncRef.rebind(path, helloRef);
    

    これで、クライアントが初期ネーミングコンテキストで resolve("Hello") を呼び出すと、ネームサービスから Hello サーバントへのオブジェクト参照が返されます。

  3. HelloServer.java を保存します。

呼び出し待ち

サーバの準備ができました。あとは、クライアントがサービスを要求するのを待つだけです。呼び出しを待つには、try-catch ブロック内の最後部に次のコードを記述します。

      java.lang.Object sync = new java.lang.Object();
      synchronized(sync){
        sync.wait();
      }

この形式の Object.wait() では、ORB から呼び出されるまで HelloServer が有効であること (ただし静止していること) が必要です。呼び出しは main() の try-catch ブロックの中にあるので 、呼び出しが終了して sayHello() が復帰したのち、サーバは再び呼び出し待ちに戻ります。

HelloServer.java を保存します。

Hello World サーバのコンパイルと実行

HelloServer を実行するには、いくつかのサーバファイルを新規に作成する必要があります。これらのファイルは、[Path_to_JDK]/docs/guide/idl/tutorial/server にあります。必要に応じてコピーして、プロジェクトディレクトリを作成します。

Windows のユーザの方は、このマニュアルのパスのスラッシュ (/) をバックスラッシュ (\) に置き換えてください。

サーバの設定

  1. Server という名前のプロジェクトディレクトリを新規に作成します。

  2. HelloServer.javaHelloClient.class[Path_to_JDK]/docs/guide/idl/tutorial/server ディレクトリから Server ディレクトリにコピーします。

  3. [Path_to_JDK]/docs/guide/idl/tutorial/server/HelloApp ディレクトリとその内容全体を、Server ディレクトリにコピーします。

プロジェクトディレクトリは次のようになります。

Server
 |-HelloServer.java
 |-HelloClient.class
 |-HelloApp
    |-_HelloImplBase.class
    |-_HelloStub.class
    |-Hello.class
    |-HelloHelper.class
    |-HelloHolder.class

サーバのコンパイル

  1. 作成した Server ディレクトリに移動します。

  2. HelloServer.java に対して Java コンパイラを実行します。
    javac HelloServer.java
    
  3. ファイルにエラーがあれば、修正してコンパイルし直します。正確に入力するのが難しい場合は、[Path_to_JDK]/docs/guide/idl/tutorial/server ディレクトリからファイルをコピーして使ってもかまいません。

  4. Server ディレクトリに、HelloServer.classHelloServant.class ができるはずです。

Hello World サーバの実行

このレッスンで作ったサーバプログラムが確実に実行されるよう、前のレッスンでサーバを実行したままになっていないか確認し、必要なら停止します。

  1. Java IDL ネームサーバを起動します。
    tnameserv -ORBInitialPort 1050 &
  2. Hello サーバを起動します。
    java HelloServer -ORBInitialPort 1050 &
  3. 別のウィンドウで Hello クライアントアプリケーションを実行します。
    java HelloClient -ORBInitialPort 1050

    コマンド行に、次の文字列が表示されます。

    Hello world!!

次のレッスンに進む前に、必ず両方のサーバプロセスを停止させてください。

詳細情報

例外:システム例外
CORBA のシステム例外の動作と、Java IDL のシステム例外のマイナーコードの詳細な説明
サーバの開発
CORBA サーバのプログラミングに関する問題
ネームサービス
COS ネームサービスの詳細な説明


前のレッスン | 次のレッスン | チュートリアルのホーム | HelloServer.java
ホーム


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