java.rmi.activation.Activatable
を継承して、既存の UnicastRemoteObject
を起動可能なオブジェクトに移行する手順について説明します。このページは、既存のクラスをUnicastRemoteObject
のサブクラスから java.rmi.activation.Activatable
のサブクラスに変更する開発者を対象としています。チュートリアルでは、起動可能オブジェクトの作成方法やjava.rmi.activation.Activatable を継承しないオブジェクトの起動方法についての説明もします。
JavaTM 2 SDK をリリースする前は、UnicastRemoteObject
のインスタンスへのアクセスは、(1) リモートオブジェクトのインスタンスを生成し、かつ (2) 常時稼動中である、サーバプログラムからアクセスできました。現在では、java.rmi.activation.Activatable
クラスおよび RMI デーモン rmid
の導入により、常時ではなく「必要に応じて」作成され、実行されるリモートオブジェクトの実装情報を登録するプログラムの記述が可能になりました。RMI デーモン rmid
は、Java 仮想マシン* (JVM) を提供します。 この JVM からほかの JVM インスタンスを生成させることも可能です。
注 - 以降のチュートリアルでは、「起動可能オブジェクトの実装」、「起動可能オブジェクト」、および「実装」と言った場合、すべて、リモートインタフェースを実装する起動可能なクラス examples.activation.MyRemoteInterfaceImpl
を指します。
このチュートリアルの構成は、次のとおりです。
このチュートリアルの実行に必要なファイルは、次のとおりです。
Client2.java
- 起動可能オブジェクトのメソッドを呼び出すクラス
MyRemoteInterface.java
- 以下のクラスにより実装される、java.rmi.Remote
を継承するインタフェース
MyRemoteInterfaceImpl.java
- 起動されるクラス
Setup2.java
- 起動可能クラスに関する情報を RMI レジストリおよび RMI デーモンに登録するクラス
ここでは、クライアントコードも示しますが、実装クラスやセットアップクラスの場合のように、手順を追った説明はしません。これは、起動可能オブジェクトのクライアントコードが、起動可能でないリモートオブジェクトにアクセスするための RMI クライアントコードと同じであるためです。起動は、厳密にはサーバ側での実装によって決定されます。
このチュートリアルで使われているソースコードは、次のファイル形式から選ぶことができます。
この例の実装クラスは、examples.activation.MyRemoteInterfaceImpl です。 UnicastRemoteObject
から継承した既存の実装クラスを移行させるには、次の 4 つのステップを実行します。
java.rmi.activation.Activatable
から継承する
ステップ 1:
実装クラスに対し適切なインポートを実行するimport java.rmi.*; import java.rmi.activation.*;ステップ 2:
クラス宣言を変更し、クラスをjava.rmi.activation.Activatable
から継承するpublic class MyRemoteInterfaceImpl extends Activatable implements examples.activation.MyRemoteInterface {ステップ 3:
引数をとらない古いコンストラクタを削除またはコメントアウトする// public MyRemoteInterfaceImpl() throws RemoteException // { // }ステップ 4:
2 つの引数をとる実装クラスのコンストラクタを宣言するpublic MyRemoteInterfaceImpl(ActivationID id, MarshalledObject data) throws RemoteException { // Register the object with the activation system // then export it on an anonymous port // super(id, 0); }
実装が利用可能な間はずっと稼動する必要のある RMI サーバクラスと異なり、「セットアップ」クラスは、リモートオブジェクトのインスタンスを生成しなくても、起動可能クラスに必要なすべての情報を作成することができます。この例のセットアップクラスは、examples.activation.Setup2
です。
セットアップクラスは、起動可能クラスに関する情報を rmid
に渡し、リモート参照 (実行可能クラスのスタブクラスのインスタンス) および識別子 (名前) を rmiregistry
に登録します。 そのあと、セットアップクラスは終了できます。セットアップクラスは、7 つのステップで作成します。
SecurityManager
をインストールする
ActivationGroup
のインスタンスを生成する
ActivationDesc
のインスタンスを生成する
rmid
に起動記述子を登録する
rmiregistry
の名前にバインドする
ステップ 1:
セットアップクラスで適切なインポートを実行するimport java.rmi.*; import java.rmi.activation.* import java.util.Properties;ステップ 2:
SecurityManager
をインストールするSystem.setSecurityManager(new RMISecurityManager());ステップ 3:
ActivationGroup
のインスタンスを生成する注: ここでは、例を単純にするために、すべての位置のすべてのユーザにグローバルなアクセス権を与える policy ファイルを使用します。このポリシーファイルは、実稼働環境では使用しないでください。
java.security.policy
ファイルを使ってアクセス権を適切に指定する方法については、次のドキュメントを参照してください。
デフォルトの Policy の実装とポリシーファイルの構文
セットアップアプリケーションにおける起動グループ記述子の役割は、
rmid
が適切な既存の JVM にアクセスしたり、起動可能オブジェクト用の新しい JVM を生成したりする際に必要になるすべての情報を提供することです。注 - このコードを実際にシステム上で実行するには、ポリシーファイルの位置を、ソースコードに付属するサンプルのポリシーファイルをインストールした絶対パスに変更する必要があります。
// Because of the Java 2 security model, a security policy should // be specified for the ActivationGroup VM. The first argument // to the Properties put method, inherited from Hashtable, is // the key and the second is the value // Properties props = new Properties(); props.put("java.security.policy", "/home/rmi_tutorial/activation/policy"); ActivationGroupDesc.CommandEnvironment ace = null; ActivationGroupDesc exampleGroup = new ActivationGroupDesc(props, ace); // Once the ActivationGroupDesc has been created, register it // with the activation system to obtain its ID // ActivationGroupID agi = ActivationGroup.getSystem().registerGroup(exampleGroup);ステップ 4:
ActivationDesc
のインスタンスを生成する起動記述子の役割は、
rmid
が実装クラスの新しいインスタンスの生成に必要とするすべての情報を提供することです。注 - このコードをシステム上で実行するには、ファイルの URL の位置を、サンプルソースコードを実際にインストールしたディレクトリの位置に変更する必要があります。
// Don't forget the trailing slash at the end of the URL // or your classes won't be found // String location = "file:/home/rmi_tutorial/activation/"; // Create the rest of the parameters that will be passed to // the ActivationDesc constructor // MarshalledObject data = null; // The location argument to the ActivationDesc constructor will be used // to uniquely identify this class; it's location is relative to the // URL-formatted String, location. // ActivationDesc desc = new ActivationDesc (agi, "examples.activation.ActivatableImplementation", location, data);
ステップ 5:
実装クラス作成への参照を削除して、リモートインタフェースのインスタンスを宣言し、rmid
に起動記述子を登録する// MyRemoteInterfaceImpl mri = new MyRemoteInterfaceImpl(); // the above line is replaced with the following: // MyRemoteInterface mri = (MyRemoteInterface)Activatable.register(desc); System.out.println("Got the stub for the MyRemoteInterfaceImpl");
ステップ 6:
Activatable.register
メソッドによって返されたスタブをrmiregistry
の名前にバインドするNaming.rebind("MyRemoteInterfaceImpl", mri); System.out.println("Exported MyRemoteInterfaceImpl");
System.exit(0);
コードのコンパイルおよび実行は、次の 6 つのステップで行います。
rmic
を実行する
rmiregistry
を開始する
rmid
を開始する
* この Web サイトで使用されている用語「Java 仮想マシン」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。ステップ 1:
リモートインタフェース、実装、クライアント、およびセットアップの各クラスをコンパイルする% javac -d . MyRemoteInterface.java % javac -d . MyRemoteInterfaceImpl.java % javac -d . Client2.java % javac -d . Setup2.java
% rmic -d . examples.activation.MyRemoteInterfaceImpl
% rmiregistry &注 - rmiregistry を開始する前に、
registry
を実行するシェルまたはウィンドウに CLASSPATH が設定されていないこと、あるいは設定されていても、クライアントにダウンロードするクラスへのパス (リモートオブジェクトの実装クラスのスタブを含む) が含まれていないことを確認してください。
rmiregistry
が、その開始時に CLASSPATH 内でスタブクラスを見つけると、サーバのjava.rmi.server.codebase
プロパティは無視されます。その結果、クライアントは、そのリモートオブジェクトのスタブコードをダウンロードできません。% rmid -J-Djava.security.policy=rmid.policy &rmid.policy
は、rmid
のセキュリティポリシーファイル名です。注: デフォルトでは、
rmid
は現在、セキュリティポリシーファイルを要求します。 このファイルは、起動グループ用の JVM の起動に、各ActivationGroupDescriptor
の情報を使用できるかどうかを確認するために使用されます。完全な詳細については、rmid
の Solaris オペレーティング環境用マニュアルページおよびrmid
の Microsoft の Windows プラットフォーム用マニュアルページを参照してください。コードベースのプロパティを実装スタブの位置に設定して、セットアップを実行します。次の 4 つを同じコマンド行に記述する必要があります。
java
」コマンド- セキュリティポリシーファイルの位置を指定するプロパティの「名前」=「値」のペア
- スタブコードの位置を指定するプロパティ (「-D」から最後の「/」まで空白文字は含めない)
- セットアッププログラムの完全指定されたパッケージ名
空白文字は、
java
という語の直後に 1 つ、2 つのプロパティの間に 1 つ、および (ブラウザまたは紙上では判別しにくいですが)examples
という語の直前に 1 つ必要です。
% java -Djava.security.policy=/home/rmi_tutorial/activation/policy -Djava.rmi.server.codebase=file:/home/rmi_tutorial/activation/ examples.activation.Setup2
コードベースプロパティは URL として解釈処理されます。 このため、コードベースプロパティは
http://aHost/somesource/
かfile:/myDirectory/location/
の形式、またはオペレーティングシステムによってはfile:///myDirectory/location/
(file:
のあとにスラッシュが 3 つ続く) の形式でなければなりません。サンプルコードを実行するには
file:
形式の URL の方が使いやすい場合があります。しかし、この場合、サーバにアクセスできるクライアントは、(サーバと同じマシン上で実行したり NFS などの共用ファイルシステムを使用して) サーバと同じファイルシステムにアクセスできるクライアントだけになります。HTTP サーバがまだ稼動していない場合は、米国サン・マイクロシステムズ社またはその関係会社の HTTP サーバからダウンロードすることができます。これらのサンプル URL の各文字列には、末尾に「/」があることに注意してください。
java.rmi.server.codebase
プロパティで指定する URL では、実装がクラス定義を適切に解釈処理 (検索) するために、末尾のスラッシュが必要です。コマンド行からのjava.rmi.server.codebase
プロパティの設定についての詳細は、java.rmi.server.codebase
プロパティを使用した動的なコードのダウンロードについてのチュートリアルを参照してください。プロパティ上の末尾のスラッシュを忘れたり、ソースファイルで指定された位置にクラスファイルが見つからない (ダウンロード可能でない) 場合、またはプロパティ名を間違って入力した場合は、
java.lang.ClassNotFoundException
がスローされます。この例外は、リモートオブジェクトをrmiregistry
にバインドしようとした場合、または最初のクライアントがそのオブジェクトのスタブにアクセスしようとした場合にスローされます。後者の場合は、rmiregistry
が CLASSPATH 内でスタブを検索するため、さらに問題が発生する場合があります。サーバ側の出力は、次のようになります。
Got the stub for the MyRemoteInterfaceImpl Exported MyRemoteInterfaceImplステップ 6:
クライアントを実行するクライアントプログラムへの引数は、実装サーバのホスト名で、この場合は
vector
です。% java -Djava.security.policy=/home/rmi_tutorial/activation/policy examples.activation.Client2 vectorクライアント側の出力は次のようになります。
Got a remote reference to the newly-Activatable object Returned from remote call Result: Successful execution of callMeRemotely() in MyRemoteInterfaceImpl
Copyright © 1999 Sun Microsystems, Inc. All Rights Reserved. コメントの送付先: rmi-comments@java.sun.com |