このチュートリアルでは、おなじみの「Hello World」プログラムの分散システム版を、Java TM の RMI (Remote Method Invocation、リモートメソッド呼び出し) を Internet Inter-ORB Protocol (IIOP) 経由で使用して作成する手順を説明します。 RMI-IIOP は、Java RMI に CORBA (Common Object Request Broker Architecture) 機能を追加することにより、標準規格に基づいた相互運用性と接続性を、ほかの多くのプログラミング言語およびプラットフォームに提供します。 RMI-IIOP を利用すると、Web ベースの分散 Java アプリケーションから、Object Management Group によって定義された業界標準である IIOP を使用しているリモートネットワークサービス上の操作を、透過的に呼び出すことができます。 ランタイムコンポーネントには、IIOP 通信を使った分散コンピューティング用の Java ORB が含まれています。
RMI-IIOP は、IIOP を背後のトランスポートとして使用して、RMI インタフェースに対するプログラムを作成したい Java プログラマ向けです。 RMI-IIOP はさまざまな言語で実装される CORBA オブジェクトとの相互運用性を提供しますが、リモートインタフェースをあらかじめ Java RMI インタフェースとして定義しておく必要があります。 EJB のリモートオブジェクトモデルは RMI ベースなので、Enterprise JavaBeans (EJB) を使うプログラマには特に有用です。
分散アプリケーションを作成するためのもう 1 つの選択肢として、Java TM IDL があります。 Java IDL は、CORBA インタフェース定義言語 (IDL) で定義されたインタフェースに基づいて Java プログラミング言語でプログラムを記述したい CORBA プログラマ向けです。 これは「通常どおりの」CORBA プログラミングで、C++ や COBOL のような他の言語とまったく同じ方法で Java をサポートしています。
ここで例として紹介する分散型の「Hello World」プログラムでは、クライアントアプリケーションから IIOP 経由でサーバ (そのクライアントアプリケーションのダウンロード元のホスト上で稼動している) に対してリモートメソッド呼び出し行います。 このクライアントアプリケーションを実行すると、「Hello World!」が表示されます。
このチュートリアルの構成は、次のとおりです。
ここで行う作業は 4 つあります。
このチュートリアルで作成するソースファイルは、次のとおりです。HelloInterface.java
- リモートインタフェース
HelloImpl.java
- HelloInterface
を実装するリモートオブジェクトの実装
HelloServer.java
- リモートオブジェクト実装のインスタンスを作成し、そのインスタンスをネームサービスの名前にバインドする、RMI サーバ
HelloClient.java
- リモートメソッド sayHello()
を呼び出すクライアントアプリケーション
Remote
インタフェースを実装するクラスのインスタンスです。 作成するリモートインタフェースでは、ほかのマシンから呼び出したい各メソッドを宣言します。 リモートインタフェースには、次の特性があります。
public
として宣言する必要がある。 そうしないと、クライアントがリモートインタフェースと同じパッケージ内にある場合を除いて、リモートインタフェースを実装しているリモートオブジェクトをクライアントがロードしようとした時点でエラーが発生する
java.rmi.Remote
インタフェースを継承する
throws
節内で java.rmi.RemoteException
(または RemoteException
のスーパークラス) を宣言する必要がある
HelloImpl
) ではなく、リモートインタフェースの型 (たとえば、HelloInterface
) として宣言する必要がある
この例では、すべてのソースファイルを同じディレクトリ (たとえば、$HOME/mysrc/helloWorld
) 内に作成します。 リモートインタフェース 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
をスローすることにより通信エラーを報告します。分散システム上のエラーおよび復元の詳細については、「A Note on Distributed Computing」を参照してください。
リモートオブジェクトの実装クラス 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復習: リモートオブジェクトの実装クラスが行う必要のある事柄は、次のとおりです。
java.rmi.RemoteException
をスローするようにコンストラクタを定義する
HelloImpl
クラスのコンストラクタは、次のとおりです。 public HelloImpl() throws java.rmi.RemoteException { super(); }次の点に注意してください。
super
メソッド呼び出しは、リモートオブジェクトをエクスポートする javax.rmi.PortableRemoteObject
の引数なしのコンストラクタを呼び出す
java.rmi.RemoteException
をスローする必要がある
java.rmi.RemoteException
が実行時例外ではなくチェックされる例外である理由については、rmi-users 電子メールリストの下記のアーカイブを参照してください。
http://java.sun.com/products/jdk/rmi/archives/3490.html
スーパークラスの引数なしのコンストラクタ 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
内のコア Java クラスの大部分は、Serializable
インタフェースを実装しています。 RMI では、次のようになります。
static
または transient
とマークされたもの以外は、オブジェクトのすべてのデータメンバ (またはフィールド) がコピーされる。 直列化のデフォルト動作を変更する方法については、「Java オブジェクト直列化仕様」を参照
rmic
を使ってスタブおよびスケルトンを生成する」で説明する。
サーバクラスは、リモートオブジェクト実装のインスタンスを生成し、そのインスタンスをネームサービスの名前にバインドする main
メソッドを持ちます。 この main
メソッドを含むクラスは、実装クラスそのものである場合も、まったく別のクラスである場合もあります。
この例では、main
は HelloServer.java
の一部として含まれており、次の処理を実行します。
HelloServer.java
のソースは次のとおりです。そのあと、上記の各ステップについて説明します。
//HelloServer.java import javax.naming.InitialContext; import javax.naming.Context; import javax.rmi.PortableRemoteObject; 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 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 ); } }
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 のサポートは、J2SE バージョン 1.4 の新機能です。
POA は、少なくともクライアントの立場からは持続オブジェクトが可能になるようにしています。 つまり、サーバが物理的に何度再起動されても、または多くの異なるオブジェクト実装によって実装が提供されても、そのクライアントが関係する範囲では、これらのオブジェクトは常に稼動しており、オブジェクトに格納されたデータ値が維持されています。
POA を利用すると、オブジェクトの実装者は、ずっと多くの制御が可能になります。 以前は、オブジェクトを実装することは、メソッドの要求に応答して実行されるコードだけの責任でした。 今では、それに加えて、オブジェクトの実装者が、オブジェクトの識別、状態、記憶領域、およびライフサイクルをもっと制御することができます。
この例では、次のようなポリシー値を設定しています。
LifespanPolicyValue
には、次の値を指定できる
TRANSIENT
- POA で実装されたオブジェクトは、そのオブジェクトが最初に作成された POA インスタンスより長く持続することはできない
PERSISTENT
- POA で実装されたオブジェクトは、そのオブジェクトが最初に作成されたプロセスより長く持続できる
RequestProcessingPolicyValue
には、次の値を指定できる
USE_ACTIVE_OBJECT_MAP_ONLY
- オブジェクト ID がアクティブオブジェクトマップ内に見つからない場合、クライアントに OBJECT_NOT_EXIST
例外が返される。 この場合、RETAIN
ポリシーも必要
USE_DEFAULT_SERVANT
- オブジェクト ID がアクティブオブジェクトマップ内に見つからない場合か、NON_RETAIN
ポリシーが存在する場合、set_servant
操作を使ってデフォルトサーバントが POA に登録されているなら、要求はデフォルトサーバントにディスパッチされる
USE_SERVANT_MANAGER
- オブジェクト ID がアクティブオブジェクトマップ内に見つからない場合か、NON_RETAIN
ポリシーが存在する場合、set_servant_manager
操作を使ってサーバントマネージャが POA に登録されているなら、サーバントマネージャがサーバントを検索するか、例外を発生させる
ServantRetentionPolicyValue
には、次の値を指定できる
RETAIN
- POA がアクティブオブジェクトマップ内にアクティブなサーバントを保持することを示す。 POA の作成時に ServantRetentionPolicy
が指定されていない場合、デフォルトは RETAIN
になる
NON_RETAIN
- サーバントが POA によって保持されないことを示す
POA ポリシーの詳細は、CORBA/IIOP 2.3.1 仕様 (http://cgi.omg.org/cgi-bin/doc?formal/99-10-07) の第 11 章「Portable Object Adapter」を参照してください。
各 POA
オブジェクトには、POAManager
オブジェクトが関連付けられています。 POA マネージャは、1 つ以上の POA オブジェクトに関連付けられることがあります。 POA マネージャは、関連付けられている POA の処理状態をカプセル化します。 このステップでは、POA マネージャを起動します。 このステップを実行しないと、POA マネージャはデフォルトでは HOLD
状態になっているため、Servant
に対するすべての呼び出しがハングアップしてしまいます。
tPOA.the_POAManager().activate();
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 );
リモートオブジェクトがサーバに登録されたあとは、呼び出し側は、オブジェクトを名前で検索し (ネームサービスを利用する)、リモートオブジェクトへの参照を取得してはじめて、そのオブジェクトのメソッドをリモートから呼び出せるようになります。 この例では、Object Request Broker Daemon ( たとえば、次のコードは、「HelloService」という名前をリモートオブジェクトへの参照にバインドします。
この例のクライアントアプリケーションは、リモートから まず、クライアントアプリケーションは、リモートオブジェクト実装 (「HelloService」として公開されている) への参照を、Java Naming and Directory Interface [TM] (JNDI) 呼び出しを使用してネームサービスから取得します。
Tie オブジェクトを起動するのに使用したのと同じオブジェクト ID を使ってオブジェクト参照を公開する
呼び出し側 (クライアント、ピア、またはクライアントアプリケーション) がリモートオブジェクトのメソッドを呼び出すには、呼び出し側はまずリモートオブジェクトへの参照を取得する必要があります。
orbd
) を使用しています。orbd
は、ブートストラップサービス、一時ネームサービス、持続ネームサービス、およびサーバマネージャが入っているデーモンプロセスです。
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
メソッド呼び出しの引数については、次の点に注意してください。
"HelloService"
は、バインドするリモートオブジェクトの名前を表す java.lang.String
である
tPOA.create_reference_with_id(id, tie._all_interfaces(tPOA,id)[0]
は、バインドするリモートオブジェクトのオブジェクト ID である
クライアントからの要求を受け付ける準備をする
次のコード行がメインスレッドから呼び出されると、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;
}
}
}
Naming.rebind
メソッドと同じく、Naming.lookup
メソッドも、検索するオブジェクトの名前を表す java.lang.String
値を引数として取ります。 検索したいオブジェクトの名前を Naming.lookup() に提供すると、その名前にバインドされたオブジェクトが返されます。
_HelloImpl_Stub
インスタンスを返す
lookup
メソッドは、リモートオブジェクト (HelloImpl
) のスタブインスタンスを受け取り、スタブクラス (_HelloImpl_Stub
) をロードする
Naming.lookup
は、呼び出し側 (HelloClient
) にスタブを返す
sayHello()
メソッドをリモートから呼び出して、コマンド行に「It works! Hello World!!」という文字列を表示させる
HelloInterface.java
- リモートインタフェースのソースコードが入っている
HelloImpl.java
- リモートオブジェクト実装のソースコードが入っている
HelloServer.java
- サーバのソースコードが入っている
HelloClient.java
- クライアントアプリケーションのソースコードが入っている
HelloImpl.java
をコンパイルして、rmic
を実行するのに必要な .class
ファイルを作成します。 次に、rmic
コンパイラを実行して、スタブとスケルトンを作成します。 スタブとは、リモートオブジェクトのクライアント側のプロキシのことで、RMI-IIOP 呼び出しをサーバ側のディスパッチャに転送します。続いて、ディスパッチャは、その呼び出しを実際のリモートオブジェクト実装に転送します。 最後に、残りの .java
ソースファイルをコンパイルして、.class
ファイルを作成します。
このセクションで実行する作業は次のとおりです。
スタブファイルとスケルトンファイルを作成するには、リモートオブジェクト実装の入ったコンパイル済みクラスファイルの完全指定のパッケージ名について、rmic
を実行する必要があります。 この例では、リモートオブジェクト実装の入ったファイルは HelloImpl.java
です。 スタブとスケルトンを生成するためには、まず、次のようにして HelloImpl.java
をコンパイルする必要があります。
javac -d . -classpath . HelloImpl.java
「-d .
」オプションは、生成されたファイルを、コンパイラを実行しているのと同じディレクトリに置くことを示します。 「-classpath .
」オプションは、HelloImpl.java
が依存しているファイルが、このディレクトリ内にあることを示します。
rmic
を使ってスタブおよびスケルトンを生成するrmic
を、-poa -iiop
オブションを指定して実行します。 rmic -poa -iiop
コマンドは、引数に 1 つ以上のクラス名をとり、_MyImpl_Tie.class
および _MyInterface_Stub.class
という形式のクラスファイルを生成します。 この例では、リモート実装ファイル HelloImpl.class
のクラス名を渡します。
rmic
のオプションの詳細は、Solaris 用 rmic
のマニュアルページまたは Win32 用 rmic
のマニュアルページを参照してください。
HelloImpl
リモートオブジェクト実装のスタブおよびスケルトンを作成するには、次のように rmic
を実行します。
rmic -poa -iiop HelloImpl
上記のコマンドによって、次のファイルが作成されます。
_HelloInterface_Stub.class
- クライアントスタブ
_HelloImpl_Tie.class
- サーバスケルトン
ソースファイルをコンパイルするには、次の javac
コマンドを実行します。
javac -d . -classpath . HelloInterface.java HelloServer.java HelloClient.java
このコマンドにより、HelloInterface.class
、HelloServer.class
、および HelloClient.class
の各クラスファイルが作成されます。 これらのファイルはそれぞれ、リモートインタフェース、サーバ、そしてクライアントアプリケーションです。 javac
のオプションの詳細は、Solaris 用 javac
のマニュアルページまたは Win32 用 javac
のマニュアルページを参照してください。
orbd
) を使用します。これには、一時ネームサービスと持続ネームサービスの両方が組み込まれており、J2SE 1.4 以降をダウンロードすれば入手できます。
呼び出し側 (クライアント、ピア、またはクライアントアプリケーション) がリモートオブジェクトのメソッドを呼び出すには、呼び出し側はまずリモートオブジェクトへの参照を取得する必要があります。
リモートオブジェクトがサーバに登録されると、呼び出し側は、そのオブジェクトを名前によって検索して、リモートオブジェクトへの参照を取得できます。そうすれば、そのオブジェクトのメソッドをリモートから呼び出せます。
ネームサービスを起動するには、コマンド行から orbd
を実行します。 このコマンドからは何の出力もありません。通常、バックグラウンドで実行されます。 orbd
ツールの詳細は、orbd
のマニュアルページを参照してください。
この例の場合、Solaris オペレーティングシステムでは次のコマンドを実行します。
orbd -ORBInitialPort 1060&
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 用 java
のマニュアルページまたは Win32 用 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 © 2001 Sun Microsystems, Inc. All Rights Reserved. コメントの送付先: rmi-iiop@sun.com |