Activatable
を拡張するこのチュートリアルでは、java.rmi.activation.Activatable
クラスを拡張することで起動可能なリモート・オブジェクトを実装する方法について説明します。このチュートリアルでは、Setup
プログラム(「アクティベーションの使用: Setup
プログラム」チュートリアルを参照)を使用します。このプログラムは、起動可能なリモート・オブジェクトに関する情報をJava Remote Method Invocation (Java RMI)起動システム・デーモン(rmid
)に登録し、rmiregistry
でそのリモート・オブジェクトのスタブをバインドして、クライアントが検索できるようにします。この前に、そのチュートリアルを読むことをお薦めします。
このチュートリアルでは、次の手順を実行します。
このチュートリアルの実行に必要なファイルは、次のとおりです。
MyRemoteInterface.java
- 単純なリモート・インタフェースExtendsActivatable.java
- リモート・インタフェースの「起動可能な」実装Client.java
- リモート・インタフェースを使用するクライアントclient.policy
- クライアントのセキュリティ・ポリシー・ファイル起動可能なリモート・オブジェクトを実装するには、いくつかの基本的な方法があります。このチュートリアルでは、構築中に起動可能なリモート・オブジェクトをエクスポートするjava.rmi.activation.Activatable
クラスを拡張することで起動可能なリモート・オブジェクトを実装する方法について説明します。
リモート・オブジェクトは、クライアントが起動可能なリモート・オブジェクトのスタブでリモート・メソッドを呼び出すときに起動されます。起動可能なリモート・オブジェクトのスタブには、リモート・オブジェクトの起動識別子と、そのリモート・オブジェクトのJava RMI起動システム・デーモン(rmid
)にコンタクトする方法に関する情報が含まれます。スタブは、リモート・オブジェクトの最新のアドレス(つまり、ホスト/ポート)に接続できない場合、リモート・オブジェクトのアクティベータ(rmid
)にコンタクトしてそのオブジェクトを起動します。rmid
は、起動要求を受け取ると、リモート・オブジェクトの起動グループがまだ実行されていない場合は、そのグループ(またはコンテナ)のVMを起動します。次に、rmid
は、グループにそのリモート・オブジェクトのインスタンスを作成するように要求します。グループは、リモート・オブジェクトを構築すると、そのリモート・オブジェクトのスタブをrmid
に返します。次に、rmidは実際のスタブを起動スタブに返して、起動スタブが将来そのリモート・オブジェクトにコンタクトする方法についての情報を更新できるようにします。
このアクティベーションを行う前に、アプリケーションでは、使用する必要のある起動可能なリモート・オブジェクトに関する情報を登録する必要があります。次の別個のチュートリアルでは、リモート・オブジェクトの起動に必要な情報と、その情報をrmid
に登録する方法について説明します。
この例では、起動可能なリモート・オブジェクトが次のexamples.activation.MyRemoteInterface
リモート・インタフェースを実装します。
package examples.activation; import java.rmi.*; public interface MyRemoteInterface extends Remote { Object remoteMethod(Object obj) throws RemoteException; }
起動可能なリモート・オブジェクトのexamples.activation.ExtendsActivatable
実装クラスは次のとおりです。
package examples.activation; import java.rmi.*; import java.rmi.activation.*; public class ExtendsActivatable extends Activatable implements MyRemoteInterface { public ExtendsActivatable(ActivationID id, MarshalledObject data) throws RemoteException { super(id, 0); } public Object remoteMethod(Object obj) { return obj; } }
ExtendsActivatable
クラスは、Activatable
クラスを拡張して、リモート・インタフェースMyRemoteInterface
を実装します。
ExtendsActivatable
クラスは、起動グループが起動プロセス中にインスタンスを構築するために呼び出す特別な「起動」コンストラクタを宣言します。この特別なコンストラクタは、次の2つのパラメータを取ります。
ActivationID
で、起動可能なリモート・オブジェクトの識別子です。アプリケーションが起動記述子をrmid
に登録すると、rmid
はそれに起動識別子を割り当て、この起動識別子が記述子に関連する情報を参照します。リモート・オブジェクトが起動されると、この同じ起動識別子(リモート・オブジェクトのスタブにも含まれている)がコンストラクタに渡されます。MarshalledObject
で、rmid
にあらかじめ登録された初期化データが含まれています。この初期化データには、たとえば、オブジェクトの持続状態が書かれたファイル名などがあります。この例では、リモート・オブジェクトを構築する初期化データは必要ありません。コンストラクタは、単純にスーパー・クラス(Activatable
)のコンストラクタを呼び出して、匿名ポートにオブジェクトをエクスポートします。
最後に、クラスは、リモート・インタフェースの単一メソッドであるremoteMethod
を実装して、引数として渡されたオブジェクトを返します。
Client
プログラムは、オプションの第1引数として提供されたホストのレジストリ内のリモート・オブジェクトのスタブ(リモート・インタフェースMyRemoteInterface
を実装するスタブ)を検索して、そのスタブのremoteMethod
メソッドを呼び出します。レジストリから獲得したスタブでこのクライアントがリモート・メソッドを呼び出すと、リモート・オブジェクトが起動されていない場合にはリモート・オブジェクトが起動されます。
プログラムのソースは次のとおりです。
package examples.activation; import java.rmi.*; import java.rmi.registry.*; public class Client { public static void main(String args[]) throws Exception { String hostname = "localhost"; if (args.length < 1) { System.err.println( "usage: java [options] examples.activation.Client <hostname>"); System.exit(1); } else { hostname = args[0]; } if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } String name = System.getProperty("examples.activation.name"); Registry registry = LocateRegistry.getRegistry(hostname); MyRemoteInterface stub = (MyRemoteInterface) registry.lookup(name); System.err.println("Obtained stub from the registry."); System.err.println("Invoking remote method..."); String result = (String) stub.remoteMethod("hello there!"); System.err.println("Returned from remote call."); System.err.println("Result: " + result); } }
このプログラムを次のように実行します。
java -cp clientDir \ -Djava.security.policy=client.policy \ -Dexamples.activation.client.codebase=clientCodebase \ -Dexamples.activation.name=name \ examples.activation.Client [host]
次にそれぞれの意味を示します。
注: このプログラムを実行する前に、rmid
がそのデフォルト・ポートで稼働し、rmiregistry
がそのデフォルト・ポート(両方ともリモート・ホスト上)で稼働している必要があります。
アクティベーションの例として、適切なアクセス権を付与するclient.policy
ファイルの例を次に示します。
grant codeBase "${examples.activation.client.codebase}" { // permissions to read system properties required by the client permission java.util.PropertyPermission "examples.activation.name","read"; // permission to connect to the registry, activation system, and remote host permission java.net.SocketPermission "*:1024-","connect"; };
アクセス権が付与されるコード・ベースは、クライアントのクラスの場所を指定するファイルURLです。このファイルURLは、examples.activation.client.codebase
システム・プロパティの値で、クライアント・プログラムの実行時に定義されます。クライアントには2つのアクセス権が必要です。
java.util.PropertyPermission
- レジストリ内のスタブの名前を指定するシステム・プロパティexamples.activation.name
を読み取るjava.net.SocketPermission
- レジストリ、起動システム、およびリモート・オブジェクトのホストに接続するこの例のソース・ファイルは、次のようにしてコンパイルできます。
javac -d implDir MyRemoteInterface.java ExtendsActivatable.java javac -d clientDir MyRemoteInterface.java Client.java
implDirは実装のクラス・ファイルを配置する生成先ディレクトリで、clientDirはクライアントのクラス・ファイルを配置する生成先ディレクトリです。
Setup
プログラムの実行実装段階が完了したら、起動可能なオブジェクトに関する情報を登録して、クライアントが使えるようにする必要があります。Setup
プログラムは、「アクティベーションの使用: Setup
プログラム」チュートリアルで説明されているように、起動可能なオブジェクトの起動記述子をrmid
に登録し、rmiregistry
でリモート・オブジェクトのスタブをバインドして、クライアントが検索できるようにします。
この例のSetup
プログラムを実行するには、Setupプログラムのチュートリアルのセクション「rmid
、rmiregistry
、およびSetup
プログラムの起動」を参照してください。rmid
、rmiregistry
、およびSetup
プログラム自体の起動方法について説明しています。
Setup
チュートリアルの手順に従ってrmid
とrmiregistry
を実行したら、Setup
プログラムを実行して、examples.activation.ExtendsActivatable
クラスを実装する起動可能なオブジェクトの起動記述子を登録する必要があります。次のコマンド行では、使用する各コード・ベースの適切なファイルURLを指定してSetup
プログラムを実行します。
java -cp setupDir:implDir \ -Djava.security.policy=setup.policy \ -Djava.rmi.server.codebase=file:/implDir/ \ -Dexamples.activation.setup.codebase=file:/setupDir/ \ -Dexamples.activation.impl.codebase=file:/impDir/ \ -Dexamples.activation.name=examples.activation.MyRemoteInterface \ -Dexamples.activation.policy=group.policy \ examples.activation.Setup examples.activation.ExtendsActivatable
次にそれぞれの意味を示します。
Setup
プログラムのクラスのルート・ディレクトリですSetup
プログラムのセキュリティ・ポリシー・ファイルですexamples.activation.file
システム・プロパティは、ExtendsActivatable
実装クラスでは使用されないため、指定する必要はありません。前述の各ファイルURLには、必須の末尾のスラッシュがあることにも注意してください。このチュートリアルに適したグループとセットアップ・ポリシー・ファイルの例は、セット・アップのチュートリアルに示されていますが、次にも示しておきます。
Setup
プログラムからの出力は、次のようになります。
Activation group descriptor registered. Activation descriptor registered. Stub bound in registry.
正常にExtendsActivatable
実装の起動記述子を登録したら、クライアント・プログラムを実行できるようになります。クライアント・プログラムは、最初の実行時に起動可能なオブジェクトを起動します。
次のコマンド行は、クライアント・コード・ベースのファイルURLを指定してクライアント・プログラムを実行する方法を示しています。
java -cp clientDir \ -Djava.security.policy=client.policy \ -Dexamples.activation.client.codebase=file:/clientDir/ \ -Dexamples.activation.name=examples.activation.MyRemoteInterface \ examples.activation.Client [host]
次にそれぞれの意味を示します。
注:
Setup
プログラムに提供される名前と一致する必要があります。この例では、examples.activation.MyRemoteInterface
という名前を使用しました。rmid
とrmiregistry
は、サーバーのホスト上で稼働している必要があります。サーバーのホストがローカル・ホストでない場合、host引数は、それらが稼働しているリモート・ホストを指定する必要があります。クライアントからの出力は、次のようになります。
Obtained stub from the registry. Invoking remote method... Returned from remote call. Result: hello there!