入門: RMI-IIOPの使用法
POAベースのサーバー側モデルの使用例


このチュートリアルでは、おなじみの「Hello World」プログラムの分散システム版を、JavaのRMI (Remote Method Invocation、リモート・メソッド呼び出し)をInternet Inter-ORB Protocol (IIOP)経由で使用して作成する手順を説明します。RMI-IIOPは、CORBA (Common Object Request Broker Architecture)機能を、ほかの多くのプログラミング言語およびプラットフォームに対するJava接続性に追加します。RMI-IIOPにより、Web対応の分散JavaリモートManagement Groupが可能になります。ランタイム・コンポーネントには、IIOP通信を使った分散コンピューティング用のJava ORBが含まれています。

RMI-IIOPは、IIOPをベースとなるトランスポートとして使用してRMIインタフェースをプログラミングしたいJavaプログラマ向けです。RMI-IIOPはさまざまな言語で実装されるCORBAオブジェクトとの相互運用性を提供しますが、リモート・インタフェースをあらかじめJava RMIインタフェースとして定義しておく必要があります。EJBのリモート・オブジェクト・モデルはRMIベースなので、Enterprise JavaBeans (EJB)を使うプログラマには特に有用です。

分散アプリケーションを作成するためのもう1つの選択肢として、Java IDLがあります。Java IDLは、CORBAインタフェース定義言語(IDL)で定義されたインタフェースに基づいてJavaプログラミング言語でプログラムを記述したいCORBAプログラマ向けです。これは「通常どおりの」CORBAプログラミングで、C++やCOBOLのようなほかの言語とまったく同じ方法でJavaをサポートしています。


チュートリアル: 「Hello World」アプリケーション

ここで例として紹介する分散型の「Hello World」プログラムでは、クライアント・アプリケーションからIIOP経由でサーバー(そのクライアント・アプリケーションのダウンロード元のホスト上で稼働している)に対してリモート・メソッド呼出しを行います。このクライアント・アプリケーションを実行すると、「Hello World!」が表示されます。

このチュートリアルの構成は、次のとおりです。

  1. ソース・ファイルを作成する手順
  2. クラス・ファイルをコンパイルする手順
  3. ネーム・サービス、サーバー、およびクライアントを起動する手順

ソース・ファイルの作成またはダウンロード

このセクションで行うタスクは3つあります。

  1. リモート・クラスの関数をJavaプログラミング言語で作成されたインタフェースとして定義する
  2. 実装クラスを作成する
  3. サーバー・クラスを作成する
  4. リモート・サービスを利用するクライアント・プログラムを作成する
このチュートリアルで作成するソース・ファイル(ここからダウンロードできる)は次のとおりです。

リモート・クラスの関数をJavaプログラミング言語で作成されたインタフェースとして定義する

Javaプログラミング言語では、リモート・オブジェクトは、Remoteインタフェースを実装するクラスのインスタンスです。作成するリモート・インタフェースでは、ほかのマシンから呼び出したい各メソッドを宣言します。リモート・インタフェースには、次の特性があります。

この例では、すべてのソース・ファイルを同じディレクトリ(たとえば、$HOME/mysrc/RMIHelloPOA)内に作成します。リモート・インタフェースHelloInterfaceのインタフェース定義は、次のとおりです。このインタフェースには、ただ1つのメソッドsayHelloが含まれています。

//HelloInterface.java
import java.rmi.Remote;

public interface HelloInterface extends java.rmi.Remote {
  public void sayHello() throws java.rmi.RemoteException;
}
リモート・メソッド呼出しでは、ローカル・メソッド呼出しとは異なる方法でエラーが発生することがあります。これは、ネットワーク通信上の問題や、サーバーの問題がエラーの原因になるからです。このため、リモート・メソッドは、通信上の障害を、java.rmi.RemoteExceptionをスローすることによって報告します。

実装クラスを作成する

リモート・オブジェクトの実装クラスHelloImpl.javaは、少なくとも次の条件を満たしていなければなりません。

HelloImpl.java: のソースは次のとおりです。そのあと、上記の各ステップについて説明します。
//HelloImpl.java
import javax.rmi.PortableRemoteObject;

public class HelloImpl extends PortableRemoteObject implements HelloInterface {
  public HelloImpl() throws java.rmi.RemoteException {
    super();     // invoke rmi linking and remote object initialization
  }

  public void sayHello() throws java.rmi.RemoteException {
    System.out.println( "It works!  Hello World!!" );
  }
}

リモート・インタフェースを実装する

Javaプログラミング言語では、あるインタフェースを実装することをクラスが宣言すると、そのクラスとコンパイラの間で契約が結ばれます。この契約によって、そのクラスは、そのインタフェース内で宣言された各メソッド・シグネチャに対して、メソッドの本体(つまり定義)を提供することを約束します。インタフェースのメソッドは、暗黙のうちにpublicおよびabstractとして宣言されているため、実装クラスでその契約が果たされない場合、そのクラスは定義に基づきabstractになります。そのクラスがabstractとして宣言されていない場合は、コンパイラによってその事実が指摘されます。

この例では、実装クラスはHelloImplです。このクラスは、どのリモート・インタフェースを実装するのかを宣言します。HelloImplクラスの宣言は、次のとおりです。

  public class HelloImpl extends PortableRemoteObject
    implements HelloInterface{
便宜上、実装クラスはリモート・クラスを拡張できます。この例では、リモート・クラスはjavax.rmi.PortableRemoteObjectです。PortableRemoteObjectを拡張していることにより、HelloImplクラスを、通信にIIOPベースのトランスポートを使うリモート・オブジェクトを作成するために利用できます。

リモート・オブジェクトのコンストラクタを定義する

リモート・クラスのコンストラクタは、リモート以外のクラスのコンストラクタと同じ機能を提供します。つまり、そのクラスの新しく作成されたインスタンスごとに変数を初期化して、コンストラクタを呼び出したプログラムにそのクラスのインスタンスを返します。

さらに、リモート・オブジェクトのインスタンスは「エクスポート」される必要があります。リモート・オブジェクトをエクスポートすると、そのオブジェクトは、匿名ポート上でリモート・オブジェクトへの着呼を監視することによって、着信したリモート・メソッド要求を受け入れることができるようになります。javax.rmi.PortableRemoteObjectを拡張すると、そのクラスは作成時に自動的にエクスポートされます。

オブジェクトのエクスポートは、java.rmi.RemoteExceptionをスローする可能性があるため、コンストラクタがほかに何も行わない場合でも、RemoteExceptionをスローするコンストラクタを定義する必要があります。コンストラクタを定義しなかった場合は、javacは、次のエラー・メッセージを生成します。

        HelloImpl.java:3: unreported exception java.rmi.RemoteException; must be
        caught or declared to be thrown. 
        
        public class HelloImpl extends PortableRemoteObject implements HelloInterface{
               ^ 
        1 error
復習: リモート・オブジェクトの実装クラスが行う必要のある事柄は、次のとおりです。 HelloImplクラスのコンストラクタは、次のとおりです。
  public HelloImpl() throws java.rmi.RemoteException { 
    super(); 
  }
次の点に注意してください。

java.rmi.RemoteExceptionは、実行時例外ではなく、チェック例外です。

スーパー・クラスの引数なしのコンストラクタsuper()への呼出しは、省略したとしてもデフォルトで発生しますが、この例では、クラスの前にスーパー・クラスが構築されることを明確にするために、この呼出しを省略せずに記述しました。

各リモート・メソッドに実装を提供する

リモート・オブジェクトの実装クラスは、リモート・インタフェースで指定された各リモート・メソッドを実装するコードを含みます。たとえば、sayHello()メソッドの実装例は、次のようになります。この例では、呼出し側に「It works! Hello World!」という文字列が返されます。
  public void sayHello() throws java.rmi.RemoteException {
    System.out.println( "It works!  Hello World!!" );
  }
リモート・メソッドに渡す引数、またはリモート・メソッドからの戻り値は、Javaプラットフォーム用のどのデータ型であってもかまいません。さらに、インタフェースjava.io.Serializableを実装したオブジェクトであれば、オブジェクト型であってもかまいません。java.langおよびjava.util内のコア・クラスの大部分は、Serializableインタフェースを実装しています。RMIでは:

サーバー・クラスを作成する

サーバー・クラスは、リモート・オブジェクト実装のインスタンスを生成し、そのインスタンスをネーム・サービスの名前にバインドするmainメソッドを持ちます。このmainメソッドを含むクラスは、実装クラスそのものである場合も、まったく別のクラスである場合もあります。

この例では、mainメソッドはHelloServer.javaの一部として含まれており、次の処理を実行します。

HelloServer.java: のソースは次のとおりです。そのあと、上記の各ステップについて説明します。
//HelloServer.java
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.rmi.PortableRemoteObject ;
//Please note that internal Oracle APIs
//may change in future releases.
import com.sun.corba.se.internal.POA.POAORB;
import org.omg.PortableServer.*;
import java.util.*;
import org.omg.CORBA.*;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.Util;

public class HelloServer {
  public HelloServer(String[] args) {
    try {
      Properties p = System.getProperties();
      // add runtime properties here
      //Please note that the name of the servertool 
      //class may change in future releases.
      p.put("org.omg.CORBA.ORBClass", 
          "com.sun.corba.se.internal.POA.POAORB");
      p.put("org.omg.CORBA.ORBSingletonClass", 
          "com.sun.corba.se.internal.corba.ORBSingleton");

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

      POA rootPOA = (POA)orb.resolve_initial_references("RootPOA");

      // STEP 1: Create a POA with the appropriate policies
      Policy[] tpolicy = new Policy[3];
      tpolicy[0] = rootPOA.create_lifespan_policy(
        LifespanPolicyValue.TRANSIENT );
      tpolicy[1] = rootPOA.create_request_processing_policy(
        RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY );
      tpolicy[2] = rootPOA.create_servant_retention_policy(
        ServantRetentionPolicyValue.RETAIN);
      POA tPOA = rootPOA.create_POA("MyTransientPOA", null, tpolicy);
          
      // STEP 2: Activate the POA Manager, otherwise all calls to the
      // servant hang because, by default, POAManager will be in the 
      // HOLD state.
      tPOA.the_POAManager().activate();

      // STEP 3: Instantiate the Servant and activate the Tie, If the
      // POA policy is USE_ACTIVE_OBJECT_MAP_ONLY
      HelloImpl helloImpl = new HelloImpl();
      _HelloImpl_Tie tie = (_HelloImpl_Tie)Util.getTie( helloImpl );
      String helloId = "hello";
      byte[] id = helloId.getBytes();
      tPOA.activate_object_with_id( id, tie );


      // STEP 4: Publish the object reference using the same object id
      // used to activate the Tie object.
      Context initialNamingContext = new InitialContext();
      initialNamingContext.rebind("HelloService", 
        tPOA.create_reference_with_id(id, 
          tie._all_interfaces(tPOA,id)[0]) );
      System.out.println("Hello Server: Ready...");
      
      // STEP 5: Get ready to accept requests from the client
      orb.run();
    } 
      catch (Exception e) {
        System.out.println("Problem running HelloServer: " + e);
        e.printStackTrace();
      } 
  }


  public static void main(String args[]) {
    new HelloServer( args );
  }
}

適切なポリシーを持つPortable Object Adapter (POA)を作成する

サーバーのmainメソッドでは、まず、適切なポリシーを持つPortable Object Adapter (POA)を作成する必要があります。たとえば、
      Policy[] tpolicy = new Policy[3];
      tpolicy[0] = rootPOA.create_lifespan_policy(
        LifespanPolicyValue.TRANSIENT );
      tpolicy[1] = rootPOA.create_request_processing_policy(
        RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY );
      tpolicy[2] = rootPOA.create_servant_retention_policy(
        ServantRetentionPolicyValue.RETAIN);
      POA tPOA = rootPOA.create_POA("MyTransientPOA", null, tpolicy);

Portable Object Adaptor (POA)は、複数のORB実装で使用できるオブジェクト・アダプタを提供するために設計されていて、異なるベンダーの実装に対応する場合も最低限の書直しで済むようになっています。

POAは、少なくともクライアントの立場からは持続オブジェクトが可能になるようにしています。つまり、サーバーが物理的に何度再起動されても、またはさまざまなオブジェクト実装による実装が行われても、クライアントに関係していればこれらの持続オブジェクトは常に存在し、格納されたデータ値は保守されています。

POAを利用すると、オブジェクトの実装者は、ずっと多くの制御が可能になります。以前は、オブジェクトを実装することは、メソッドの要求に応答して実行されるコードだけの責任でした。今では、それに加えて、オブジェクトの実装者が、オブジェクトの識別、状態、記憶領域、およびライフ・サイクルをもっと制御することができます。

この例では、次のようなポリシー値を設定しています。

POAポリシーの詳細は、CORBA/IIOP 2.3.1仕様(http://www.omg.org/cgi-bin/doc?formal/99-10-07)の第11章「Portable Object Adapter」を参照してください。

POAマネージャを起動する

各POAオブジェクトには、POAManagerオブジェクトが関連付けられています。POAマネージャには、1つまたは複数のPOAオブジェクトを関連付けることができます。POAマネージャは、関連付けられているPOAの処理状態をカプセル化します。このステップでは、POAマネージャを起動します。このステップを実行しないと、POAマネージャはデフォルトではHOLD状態になっているため、Servantに対するすべての呼出しがハング・アップしてしまいます。

      tPOA.the_POAManager().activate();

リモート・オブジェクトのインスタンスを作成し、Tieを起動する

サーバーのmainメソッドでは、リモート・オブジェクト実装のインスタンス(つまりサーバント)を作成する必要があります。たとえば、
    HelloImpl helloImpl = new HelloImpl();
コンストラクタはリモート・オブジェクトをエクスポートします。これは、リモート・オブジェクトが作成された時点で、そのリモート・オブジェクトは着呼を受け入れる準備ができていることを意味します。

RMI-IIOPテクノロジを使用している実装は、その実装をインタフェースに関連付けるために委譲(「Tieモデル」と呼ばれる)を使用します。上記のように、実装のインスタンスを作成したときは、そのインスタンスをCORBAインタフェースに関連付けるためにTieオブジェクトを作成する必要もあります。次のコード行は、Tieを起動するためのものです(ただし、POAポリシーがUSE_ACTIVE_OBJECT_MAP_ONLYの場合のみ)。

      _HelloImpl_Tie tie = (_HelloImpl_Tie)Util.getTie( helloImpl );
      String helloId = "hello";
      byte[] id = helloId.getBytes();
      tPOA.activate_object_with_id( id, tie );

Tieオブジェクトを起動するのに使用したのと同じオブジェクトIDを使ってオブジェクト参照を公開する

呼出し側(クライアント、ピア、またはクライアント・アプリケーション)がリモート・オブジェクトのメソッドを呼び出すには、呼出し側はまずリモート・オブジェクトへの参照を取得する必要があります。

リモート・オブジェクトがサーバーに登録されたあとは、呼出し側は、オブジェクトを名前で検索し(ネーム・サービスを利用する)、リモート・オブジェクトへの参照を取得してはじめて、そのオブジェクトのメソッドをリモートから呼び出せるようになります。この例では、Object Request Broker Daemon (orbd) (Solaris、LinuxまたはMac OS X用またはWindows用)を使用しています。orbdは、ブートストラップ・サービス、一時ネーム・サービス、持続ネーム・サービスおよびサーバー・マネージャが入っているデーモン・プロセスです。

たとえば、次のコードは、「HelloService」という名前をリモート・オブジェクトへの参照にバインドします。

      Context initialNamingContext = new InitialContext();
      initialNamingContext.rebind("HelloService", 
        tPOA.create_reference_with_id(id, 
          tie._all_interfaces(tPOA,id)[0]) );
      System.out.println("Hello Server: Ready...");

rebindメソッド呼出しの引数については、次の点に注意してください。

クライアントからの要求を受け付ける準備をする

次のコード行がメイン・スレッドから呼び出されると、ORBは、そのメイン・スレッドを使用して作業を実行できるようになります。
      orb.run();

リモート・サービスを利用するクライアント・プログラムを作成する

この例のクライアント・アプリケーションは、リモートからsayHelloメソッドを呼び出して、クライアント・アプリケーションが実行されたときに「Hello World!」という文字列を表示します。クライアント・アプリケーションのコードは、次のとおりです。

//HelloClient.java
import java.rmi.RemoteException;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import javax.rmi.*;
import java.util.Vector;
import javax.naming.NamingException;
import javax.naming.InitialContext;
import javax.naming.Context;

public class HelloClient {

  public static void  main( String args[] ) {
    Context ic;
    Object objref;
    HelloInterface hi;

    try {
      ic = new InitialContext();
    } catch (NamingException e) {
        System.out.println("failed to obtain context" + e);
        e.printStackTrace();
        return;
    }
        
    // STEP 1: Get the Object reference from the Name Service
    // using JNDI call.
    try {
      objref = ic.lookup("HelloService");
      System.out.println("Client: Obtained a ref. to Hello server.");
    } catch (NamingException e) {
        System.out.println("failed to lookup object reference");
        e.printStackTrace();
        return;
    }

    // STEP 2: Narrow the object reference to the concrete type and
    // invoke the method.
    try {
      hi = (HelloInterface) PortableRemoteObject.narrow(
        objref, HelloInterface.class);
      hi.sayHello();
    } catch (ClassCastException e) {
        System.out.println("narrow failed");
        e.printStackTrace();
        return;
      } catch( Exception e ) {
            System.err.println( "Exception " + e + "Caught" );
            e.printStackTrace( );
            return;
        }
  }
}

まず、クライアント・アプリケーションは、リモート・オブジェクト実装(「HelloService」として通知されている)への参照を、Java Naming and Directory Interface (JNDI)呼出しを使用してネーム・サービスから取得します。Naming.rebindメソッドと同様に、Naming.lookupメソッドは、検索するオブジェクトの名前を表すjava.lang.String値を引数として取ります。検索したいオブジェクトの名前をNaming.lookup()に提供すると、その名前にバインドされたオブジェクトが返されます。


クラス・ファイルのコンパイル

この例のソース・コードは、これで完成しました。ディレクトリには、次の4つのファイルが入っているはずです。 この項では、リモート・オブジェクト実装のファイルHelloImpl.javaをコンパイルして、rmicを実行するのに必要な.classファイルを作成します。次に、rmicコンパイラを実行して、スタブとスケルトンを作成します。スタブとは、リモート・オブジェクトのクライアント側のプロキシのことで、RMI-IIOP呼出しをサーバー側のディスパッチャに転送します。続いて、ディスパッチャは、その呼出しを実際のリモート・オブジェクト実装に転送します。最後に、残りの.javaソース・ファイルをコンパイルして、.classファイルを作成します。

このセクションで実行するタスクは次のとおりです。

  1. リモート・オブジェクト実装をコンパイルする
  2. rmicを使ってスタブおよびスケルトンを生成する
  3. ソース・ファイルをコンパイルする

リモート・オブジェクト実装をコンパイルする

スタブ・ファイルとスケルトン・ファイルを作成するには、リモート・オブジェクト実装の入ったコンパイル済みクラス・ファイルの完全指定パッケージ名について、rmicコンパイラを実行する必要があります。この例では、リモート・オブジェクト実装の入ったファイルはHelloImpl.javaです。スタブとスケルトンを生成するためには、まず、次のようにしてHelloImpl.javaをコンパイルする必要があります。

    javac -d . -classpath . HelloImpl.java

-d .」オプションは、生成されたファイルを、コンパイラを実行しているのと同じディレクトリに置くことを示します。「-classpath .」オプションは、HelloImpl.javaが依存しているファイルが、このディレクトリ内にあることを示します。

rmicを使ってスタブおよびスケルトンを生成する

CORBA対応のスタブおよびスケルトン・ファイルを作成するには、rmicコンパイラを、-poa -iiopオプションを指定して実行します。rmic -poa -iiopコマンドは、引数に1つ以上のクラス名をとり、_MyImpl_Tie.classおよび_MyInterface_Stub.classという形式のクラス・ファイルを生成します。この例では、リモート実装ファイルHelloImpl.classのクラス名を渡します。

rmicのオプションの詳細は、Solaris、LinuxまたはMac OS X用rmicのマニュアル・ページまたはMicrosoft Windows用rmicのマニュアル・ページを参照してください。

HelloImplリモート・オブジェクト実装のスタブおよびスケルトンを作成するには、次のようにrmicを実行します。

    rmic -poa -iiop HelloImpl

上記のコマンドによって、次のファイルが作成されます。

ソース・ファイルをコンパイルする

ソース・ファイルをコンパイルするには、次のjavacコマンドを実行します。

    javac -d . -classpath . HelloInterface.java HelloServer.java HelloClient.java

このコマンドにより、HelloInterface.classHelloServer.class、およびHelloClient.classの各クラス・ファイルが作成されます。これらのファイルはそれぞれ、リモート・インタフェース、サーバー、そしてクライアント・アプリケーションです。javacのオプションの詳細は、Solaris、LinuxまたはMac OS X用javacのマニュアル・ページまたはMicrosoft Windows用javacのマニュアル・ページを参照してください。


ネーム・サービス、サーバー、およびクライアント・アプリケーションの起動

このセクションで実行するタスクは次のとおりです。
  1. ネーム・サービスを起動する
  2. サーバーを起動する
  3. クライアント・アプリケーションを実行する

ネーム・サービスを起動する

この例では、Object Request Broker Daemon (orbd)を使用します。これには、一時ネーム・サービスと持続ネーム・サービスの両方が組み込まれており、JDKをダウンロードすれば入手できます。

呼出し側(クライアント、ピア、またはクライアント・アプリケーション)がリモート・オブジェクトのメソッドを呼び出すには、呼出し側はまずリモート・オブジェクトへの参照を取得する必要があります。

リモート・オブジェクトがサーバーに登録されると、呼出し側は、そのオブジェクトを名前によって検索して、リモート・オブジェクトへの参照を取得できます。そうすれば、そのオブジェクトのメソッドをリモートから呼び出せます。

ネーム・サービスを起動するには、コマンド行からorbdを実行します。このコマンドからは何の出力もありません。通常、バックグラウンドで実行されます。orbdツールの詳細は、orbdのマニュアル・ページ(Solaris、LinuxまたはMac OS X用またはWindows用)を参照してください。

この例の場合、Solarisオペレーティング・システムでは次のコマンドを実行します。

    orbd -ORBInitialPort 1060&

Microsoft Windowsオペレーティング・システムでは、次のコマンドを実行します。

    start orbd -ORBInitialPort 1060

orbdを実行するポートを指定する必要があります。この例でポートとして1060が選ばれているのは、Solarisオペレーティング・システムでは、プロセスを1024より下のポートで開始するユーザーはルートになる必要があるからです。

リモート・インタフェースを変更したり、変更または追加されたリモート・インタフェースをリモート・オブジェクトの実装で使用する場合は、必ずサーバーをいったん停止してから再起動する必要があります。そうしないと、ネーム・サービスでバインドされるオブジェクト参照の型が、変更されたクラスと一致しなくなります。

サーバーを起動する

端末ウィンドウをもう1つ開き、この例のソース・ファイルが入っているディレクトリに移ります。クライアントを実行するための下記のコマンドは、読みやすくするために複数行に分けてありますが、実際にコマンドを入力するときには改行を入れないでください。次のコマンドは、HelloServerサーバーを起動する方法を示しています。もちろん、orbdツールを起動するときに1060以外のポートやlocalhost以外のホストを使用した場合には、下記のコマンドの該当する値を、orbdを起動するときに使用した実際の値で置き換えてください。

    java 
      -classpath . 
      -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
      -Djava.naming.provider.url=iiop://localhost:1060 
      HelloServer 

javaのオプションの詳細は、Solaris、LinuxまたはMac OS X用javaのマニュアル・ページまたはMicrosoft Windows用javaのマニュアル・ページを参照してください。

出力は、次のようになります。

Hello Server: Ready ...

クライアント・アプリケーションを実行する

ネーム・サービスとサーバーを起動したあとは、クライアント・アプリケーションを実行することができます。新しい端末ウィンドウから、ソース・コードのディレクトリに移り、下記の例のようにしてコマンド行からクライアント・アプリケーションを実行します。クライアントを実行するための下記のコマンドは、読みやすくするために複数行に分けてありますが、実際にコマンドを入力するときには改行を入れないでください。もちろん、orbdツールを起動するときに1060以外のポートやlocalhost以外のホストを使用した場合には、下記のコマンドの該当する値を、orbdを起動するときに使用した実際の値で置き換えてください。
    java 
      -classpath . 
      -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
      -Djava.naming.provider.url=iiop://localhost:1060 
      HelloClient 
クライアント・アプリケーションを実行すると、次のような出力が端末ウィンドウまたはコマンド・プロンプト・ウィンドウに表示されます。
Client: Obtained a ref. to Hello server.

サーバー・ウィンドウが次のメッセージを返します。

It works! Hello World!!

これでチュートリアルを終わります。さらに複雑なアプリケーションの作成に進む場合は、次に挙げる情報が役に立ちます。


Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.