java.rmi.activation.Activatable を継承して、起動可能オブジェクトを作成する手順を示します。また、UnicastRemoteObject を起動可能にする方法や java.rmi.activation.Activatable を継承しないオブジェクトの起動方法を理解するためにも役立ちます。
JDK 1.2 のリリース以前は、UnicastRemoteObject のインスタンスには、(1) リモートオブジェクトのインスタンスを生成し、かつ (2) 常時稼動中であるサーバプログラムから、アクセスできました。現在では、java.rmi.activation.Activatable クラスおよび RMI デーモン rmid の導入により、常時ではなく「必要に応じて」作成され、実行されるリモートオブジェクトの実装情報を登録するプログラムの記述が可能になりました。RMI デーモン rmid は、Java Virtual Machine (JVM) を提供します。この JVM からほかの JVM インスタンスを生成させることも可能です。
注: 以降のチュートリアルでは、「起動可能オブジェクトの実装」、「起動可能オブジェクト」、および「実装」と言った場合、すべて、リモートインタフェースを実装する起動可能クラス examples.activation.ActivatableImplementation を指します。
このチュートリアルの構成は、次のとおりです。
このチュートリアルの実行に必要なファイルは、次のとおりです。
Client.java - 起動可能オブジェクトのメソッドを呼び出すクラス
MyRemoteInterface.java - java.rmi.Remote を継承するインタフェース。以下のクラスにより実装される
ActivatableImplementation.java - 起動されるクラス
Setup.java - 起動可能クラスに関する情報をレジストリおよび RMI デーモンに登録するクラス
ここでは、クライアントコードも示しますが、実装クラスやセットアップクラスの場合のように、手順を追った説明はしません。これは、起動可能オブジェクトのクライアントコードが、起動可能でないリモートオブジェクトにアクセスするための RMI クライアントコードと同じであるためです。起動は、厳密にはサーバ側での実装によって決定されます。
このチュートリアルで使われているソースコードは、次のファイル形式から選ぶことができます。
この例の実装クラスは examples.activation.ActivatableImplementation です。実装クラスは、次の 4 つのステップで作成します。
java.rmi.activation.Activatable から継承する
ステップ 1:
実装クラスに対し、適切なインポートを実行するimport java.rmi.*; import java.rmi.activation.*;ステップ 2:
作成するクラスをjava.rmi.activation.Activatableから継承するpublic class ActivatableImplementation extends Activatable implements examples.activation.MyRemoteInterface {ステップ 3:
2 つの引数をとる実装クラスのコンストラクタを宣言するpublic ActivatableImplementation(ActivationID id, MarshalledObject data) throws RemoteException { // Register the object with the activation system // then export it on an anonymous port super(id, 0); }public Object callMeRemotely() throws RemoteException { return "Success"; }
「セットアップ」クラスの役割は、リモートオブジェクトのインスタンスを生成しない場合でも、起動可能クラスに必要なすべての情報を作成可能にすることです。この例のセットアップクラスは、examples.activation.Setup です。
セットアップクラスは、起動可能クラスに関する情報を 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ファイルを使ってアクセス権を適切に指定する方法については、次のドキュメントを参照してください。
http://java.sun.com/products/jdk/1.2/docs/guide/security/PolicyFiles.htmlhttp://java.sun.com/products/jdk/1.2/docs/guide/security/permissions.htmlセットアップアプリケーションにおける起動グループ記述子の役割は、
rmidが適切な既存の VM にアクセスしたり、起動可能オブジェクト用の新しい VM を生成したりする際に必要になるすべての情報を提供することです。注: このコードを実際にシステム上で実行するには、ポリシーファイルの位置を、ソースコードに付属するサンプルのポリシーファイルをインストールした絶対パスに変更する必要があります。
// After JDK1.2Beta4, ActivationGroups are no longer created // implicitly as a side-effect of creating or registering the // first Activatable object // // Because of the 1.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); // Now explicitly create the group // ActivationGroup.createGroup(agi, exampleGroup, 0);ステップ 4:
ActivationDescのインスタンスを生成する起動記述子の役割は、
rmidが実装クラスの新しいインスタンスの生成に必要とするすべての情報を提供することです。注: このコードを実際にシステム上で実行するには、ファイルの URL の位置を、サンプルソースコードを実際にインストールしたディレクトリの位置に変更する必要があります。
// The "location" String specifies a URL from where the class // definition will come when this object is requested (activated). // 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 second 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 ("examples.activation.ActivatableImplementation", location, data);ステップ 5:
リモートインタフェースのインスタンスを宣言し、rmidに起動記述子を登録する
MyRemoteInterface mri = (MyRemoteInterface)Activatable.register(desc);System.out.println("Got the stub for the ActivatableImplementation");ステップ 6:
Activatable.registerメソッドによって返されたスタブをrmiregistryの名前にバインドする
Naming.rebind("ActivatableImplementation", mri);System.out.println("Exported ActivatableImplementation");
System.exit(0);
コードのコンパイルおよび実行は、次の 6 つのステップで行います。
- リモートインタフェース、実装、クライアント、およびセットアップの各クラスをコンパイルする
- 実装クラス上で
rmicを実行するrmiregistryを開始する- 起動デーモン
rmidを開始する- セットアッププログラムを実行する
- クライアントを実行する
ステップ 1:
リモートインタフェース、実装、クライアント、およびセットアップの各クラスをコンパイルする% javac -d . MyRemoteInterface.java % javac -d . ActivatableImplementation.java % javac -d . Client.java % javac -d . Setup.java% rmic -d . examples.activation.ActivatableImplementation% rmiregistry &注: rmiregistry を開始する前に、
registryを実行するシェルまたはウィンドウに CLASSPATH が設定されていないこと、あるいは設定されていてもクライアントにダウンロードするクラスへのパス (リモートオブジェクトの実装クラスのスタブを含む) が含まれていないことを確認してください。
rmiregistryが、その開始時に CLASSPATH 内でスタブクラスを見つけると、サーバのjava.rmi.server.codebaseプロパティは無視されます。その結果、クライアントは、そのリモートオブジェクトのスタブコードをダウンロードできません。
% rmid &コードベースプロパティを実装スタブの位置に設定して、セットアップを実行します。次の 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.Setupコードベースプロパティは URL として解釈処理されます。このため、プロパティは
http://aHost/somesource/かfile:/myDirectory/location/の形式、またはオペレーティングシステムによってはfile:///myDirectory/location/(file:のあとにスラッシュが 3 つ続く) の形式でなければなりません。これらのサンプル URL の各文字列には、末尾に「/」があることに注意してください。
java.rmi.server.codebaseプロパティで指定する URL では、実装がクラス定義を適切に解釈処理 (検索) するために、末尾のスラッシュが必要です。プロパティ上の末尾のスラッシュを忘れたり、ソース位置にクラスファイルが見つからない (ダウンロード可能ではない) 場合、またはプロパティ名の入力を間違えた場合は、
java.lang.ClassNotFoundExceptionがスローされます。この例外は、リモートオブジェクトをrmiregistryにバインドしようとした場合、または最初のクライアントがそのオブジェクトのスタブにアクセスしようとした場合にスローされます。後者の場合は、rmiregistryが CLASSPATH 内でスタブを検索するため、さらに問題が発生する場合があります。サーバ側の出力は、次のようになります。
Got the stub for the ActivatableImplementation Exported ActivatableImplementation
ステップ 6:
クライアントを実行する
examples.activation.Clientプログラムへの引数は、実装サーバのホスト名で、この場合はvectorです。% java examples.activation.Client vector
クライアント側の出力は次のようになります。
Got a remote reference to the object that extends Activatable. Making remote call to the server Returned from remote call Result: Success
Copyright © 1998 Sun Microsystems, Inc. All Rights Reserved.