Setup
プログラムこのチュートリアルでは、リモート・オブジェクトの起動記述子をJava Remote Method Invocation (Java RMI)起動システム・デーモン(rmid
)に登録し、rmiregistry
でそのリモート・オブジェクトのスタブをバインドしてクライアントが検索できるようにするプログラムの記述方法について説明します。
このチュートリアルでは、次の手順を実行します。
このチュートリアルの実行に必要なファイルは、次のとおりです。Setup.java
- メインSetup
プログラムsetup.policy
- Setup
プログラムのセキュリティ・ポリシー・ファイルrmid.policy
- rmid
のセキュリティ・ポリシー・ファイルgroup.policy
- 起動グループのセキュリティ・ポリシー・ファイルSetup
プログラムの実装examples.activation.Setup
クラスにより実装されるSetup
プログラムは、起動記述子をrmid
に登録して、その起動記述子によって指定されるオブジェクトの将来のアクティベーションを可能にします。このプログラムではリモート・オブジェクトのインスタンスは生成されませんが、代わりにリモート・オブジェクトのスタブをrmiregistry
に登録して、クライアントが検索できるようにします。このSetup
プログラムは、アクティベーションに関するほかのチュートリアルで説明されているどのクライアントを実行するよりも前に実行する必要があります。
Setup
プログラムでは、多くのシステム・プロパティを使用して、rmid
とrmiregistry
に登録されている情報をカスタマイズします。また、このプログラムでは、登録されている起動可能なリモート・オブジェクトの実装クラスのパッケージ修飾された名前を指定する、単一コマンド行の引数を取ります。Setup
プログラムは次のように実行します。
java -cp classpath \ -Djava.security.policy=setup.policy \ -Djava.rmi.server.codebase=codebase \ -Dexamples.activation.setup.codebase=setupCodebase \ -Dexamples.activation.impl.codebase=implCodebase \ -Dexamples.activation.name=name \ [-Dexamples.activation.file=filename] \ [-Dexamples.activation.policy=group.policy] \ examples.activation.Setup implClass
次にそれぞれの意味を示します。
Setup
プログラムと実装クラスを含むクラス・パスですSetup
プログラムのセキュリティ・ポリシー・ファイルですSetup
プログラムのクラスの場所(URL)です(setup.policyファイルでSetup
プログラムにアクセス権を付与するときに使用)group.policy
)Setup
プログラムのポリシー・ファイルの例を次に示します。
grant codeBase "${examples.activation.setup.codebase}" { // permissions to read system properties required by setup program permission java.util.PropertyPermission "examples.activation.impl.codebase","read"; permission java.util.PropertyPermission "examples.activation.policy","read"; permission java.util.PropertyPermission "examples.activation.file","read"; permission java.util.PropertyPermission "examples.activation.name","read"; // permission to connect to the activation system and the registry permission java.net.SocketPermission "*:1098-1099","connect"; };
アクセス権が付与されるコード・ベースは、Setup
プログラムの実装クラスの場所を指定するURLです。このURLは、examples.activation.setup.codebase
システム・プロパティの値で、Setup
プログラムの実行時に定義されます。Setup
プログラムには、次のアクセス権が必要です。
java.util.PropertyPermission
- Setup
プログラムが必要とするさまざまなシステム・プロパティを読み取るjava.net.SocketPermission
- 起動システム(ポート1098
)に接続して起動記述子を登録し、また、レジストリ(ポート1099
)に接続して起動可能なオブジェクトのスタブを名前にバインドするこのSetup
プログラムは、次のようなステップで記述します。
Setup
クラスには、上記のすべてのステップを実行するstaticメソッドmain
があります。ステップを実行する前に、main
メソッドは、SecurityManager
を設定して、起動可能なリモート・オブジェクトの実装クラスのパッケージ修飾された名前を指定する単一コマンド行の引数を取得します。残りのステップについては、次のセクションを参照してください。完全なソース・コードについては、Setup.java
を参照してください。
アプリケーションで特定の起動可能なリモート・オブジェクトの情報を登録する前に、そのオブジェクトが含まれることになる起動グループに関する情報を登録する必要があります。起動グループは、起動可能なオブジェクトのセットのコンテナ仮想マシン(VM)です。各起動グループでは、1つ以上の起動可能なオブジェクトの実行を管理します。起動グループ記述子には、起動システムが起動グループのVMを起動するのに必要な情報が含まれます。アプリケーションでは、起動グループ記述子を起動システムrmid
に登録して、その起動可能なオブジェクトに使用する起動グループ識別子を取得できます。または、前のグループ登録から取得した起動グループ識別子を使うことができます。
java.rmi.activation.ActivationGroupDesc
クラスのインスタンスである起動グループ記述子は、いくつかの方法で構築できます。このチュートリアルでは、パラメータが2つのコンストラクタActivationGroupDesc(Properties,CommandEnvironment)
を使用します。Properties
マップには、起動グループVMのシステム・プロパティのオーバーライドが含まれています。このチュートリアルでは、起動グループVMで次のシステム・プロパティを定義する必要があります。
java.security.policy
- グループのセキュリティ・ポリシー・ファイルjava.class.path
- 起動グループがローカルのクラス・パスから実装クラスをロードしないようにするダミーのクラス・パスexamples.activation.impl.codebase
- グループのポリシー・ファイルがアクセス権を付与するのに使用する実装クラスの場所examples.activation.file
- オブジェクトの持続状態が書かれたファイルjava.security.policy
プロパティは、examples.activation.policy
システム・プロパティにより指定され、デフォルトではgroup.policy
という名前のファイルです。このファイルは、実際には、rmid
が実行される作業ディレクトリにあります。java.class.path
プロパティは、no_classpath
として定義されます。examples.activation.impl.codebase
およびexamples.activation.file
プロパティは、それぞれ現在の値により指定され、Setup
プログラムの実行時に定義されます。
グループ記述子は次のように構成されています。
String policy = System.getProperty("examples.activation.policy", "group.policy"); String implCodebase = System.getProperty("examples.activation.impl.codebase"); String filename = System.getProperty("examples.activation.file", ""); Properties props = new Properties(); props.put("java.security.policy", policy); props.put("java.class.path", "no_classpath"); props.put("examples.activation.impl.codebase", implCodebase); if (filename != null && !filename.equals("")) { props.put("examples.activation.file", filename); } ActivationGroupDesc groupDesc = new ActivationGroupDesc(props, null);
アクティベーションの例として、適切なアクセス権を付与するgroup.policy
ファイルの例を次に示します。
grant codeBase "${examples.activation.impl.codebase}" { // permission to read and write object's file permission java.io.FilePermission "${examples.activation.file}","read,write"; // permission to listen on an anonymous port permission java.net.SocketPermission "*:1024-","accept"; };
アクセス権が付与されるコード・ベースは、起動可能なオブジェクトの実装クラスの場所を指定するURLです。このURLは、examples.activation.impl.codebase
システム・プロパティの値で、起動グループのVMで定義されます。グループ内の起動可能なオブジェクトには、2つのアクセス権が必要です。
java.io.FilePermission
- 起動可能なオブジェクトの持続状態を含むファイルの読書きを行うjava.net.SocketPermission
- 起動可能なオブジェクトをエクスポートして、匿名ポートの接続を受け入れるSetup
プログラムは、起動グループ記述子を起動システムに登録して、java.rmi.activation.ActivationGroupID
クラスのインスタンスであるそのグループのIDを取得する必要があります。java.rmi.activation.ActivationGroup
クラスには、その起動システムのスタブを取得するためのstaticメソッドgetSystem
があります。Setup
プログラムは、起動システムのリモート・メソッドregisterGroup
を呼び出し、上記で作成したグループ記述子を渡して、起動グループを登録します。
ActivationGroupID groupID = ActivationGroup.getSystem().registerGroup(groupDesc);
起動グループ識別子が取得されると、Setup
プログラムでは、起動記述子を登録できるようになります。起動記述子には、次の4つの基本的な情報が含まれます。
この例では、起動グループ識別子は上記で取得した識別子になっています。実装のクラス名はimplClassというクラス名で、Setup
プログラムへのコマンド行引数として提供されます。場所(URL)は、システム・プロパティexamples.activation.impl.codebase
により指定されます。初期化データ(オプション)は、システム・プロパティexamples.activation.file
により指定されるファイル名です。
起動記述子は次のように構成されています。
MarshalledObject data = null; if (filename != null && !filename.equals("")) { data = new MarshalledObject(filename); } ActivationDesc desc = new ActivationDesc(groupID, implClass, implCodebase, data);
次に、Setup
プログラムでは、起動記述子を起動システムに登録する必要があります。Activatable
クラスには、簡易staticメソッドregister
があります。このメソッドは、起動記述子を起動システムに登録して、その記述子により指定される起動可能なオブジェクトのスタブを返します。
Remote stub = Activatable.register(desc);
注: register
メソッドは、スタブ・インスタンスを作成するために、実装クラスのスタブ・クラスをロードしようとします。register
メソッドが事前に生成されたスタブ・クラスをロードできない場合は、実装クラスのすべてのインタフェースを実装する、動的に生成されたプロキシ・クラスのインスタンスを使用します。後者の場合、register
メソッドは、実装クラスが実装するリモート・インタフェースを決定するために、実装クラスをロードする必要があります。そのため、事前に生成されたスタブ・クラスを使用するか、動的に生成されたスタブ・クラスを使用するかによって、register
メソッドの動作にわずかな違いが生じます。
rmiregistry
でのリモート・オブジェクトのスタブのバインド最後に、リモート・オブジェクトのスタブを、デフォルトの1099
ポートで実行中のレジストリ内の名前にバインドします。名前は、システム・プロパティexamples.activation.name
により指定されます。
String name = System.getProperty("examples.activation.name"); LocateRegistry.getRegistry().rebind(name, stub);
この例のソース・ファイルは、次のようにしてコンパイルできます。
javac -d setupDir Setup.javasetupDirは、クラス・ファイルを配置するルート・デスティネーション・ディレクトリです。
rmid
、rmiregistry
、およびSetup
プログラムの起動このSetup
プログラムを実行するには、次の操作を行う必要があります。
rmid
の起動rmid
を起動するには、サーバーのホストでrmid
コマンドを実行します。このコマンドでは、次のように指定したセキュリティ・ポリシー・ファイルを使用して実行した場合は、何も出力されません。詳細は、rmid
のツール・ドキュメント(Solaris、LinuxまたはMac OS X用、Windows用)を参照してください。
Solarisオペレーティング・システムでの例:
rmid -J-Djava.security.policy=rmid.policy \ -J-Dexamples.activation.policy=group.policy &
Windowsプラットフォームでは、次のコマンドを実行します。
start rmid -J-Djava.security.policy=rmid.policy \ -J-Dexamples.activation.policy=group.policy
次にそれぞれの意味を示します。
rmid
のセキュリティ・ポリシー・ファイルrmid
のポリシー・ファイルで使用されるrmid
のセキュリティ・ポリシー・ファイルは、起動グループVMの起動時に、rmid
が特定のコマンドを実行し、特定のコマンド行オプションを使用するアクセス権を付与します。たとえば、ユーザーは、1つまたは複数のシステム・プロパティ、またはほかのjava
コマンド行オプションを使用して、起動グループVMを起動する特定のアクセス権を付与することができます。この例では、rmid
がシステム・プロパティjava.security.policy
、java.class.path
、examples.activation.impl.codebase
、およびexamples.activation.file
を定義する起動グループVMを起動できるようになっています。次のセキュリティ・ポリシー・ファイルの例では、これらの特定のプロパティを定義して、起動グループVMを起動するアクセス権を付与しています。
grant { // allow activation groups to use certain system properties permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=${examples.activation.policy}"; permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.class.path=no_classpath"; permission com.sun.rmi.rmid.ExecOptionPermission "-Dexamples.activation.impl.codebase=*"; permission com.sun.rmi.rmid.ExecOptionPermission "-Dexamples.activation.file=*"; };
最初のExecOptionPermission
アクセス権の付与では、java.security.policy
システム・プロパティを、rmid
の実行時に定義されるシステム・プロパティexamples.activation.policy
により指定されるファイルに限定しています。次の権限付与では、グループがシステム・プロパティjava.class.path
を、グループが有効なクラス・パスを持たないようにするダミーのクラス・パスno_classpath
として定義できるようにします。次の権限付与では、グループがシステム・プロパティexamples.activation.impl.codebase
を任意の値として定義できるようにします。最後の権限付与では、examples.activation.file
システム・プロパティを任意の値にできるようにします。
rmiregistry
の起動レジストリを起動するには、サーバーのホストでrmiregistry
コマンドを実行します。このコマンドからは成功時に何の出力もありません。通常、バックグラウンドで実行されます。詳細は、rmiregistry
のツール・ドキュメント(Solaris、LinuxまたはMac OS X用、Windows用)を参照してください。
Solarisオペレーティング・システムでの例:
rmiregistry &
Windowsプラットフォームでは、次のコマンドを実行します。
start rmiregistry
デフォルトでは、レジストリはTCPポート番号1099で実行されます。別のポート上でレジストリを実行するには、コマンド行でポート番号を指定します。たとえば、Windowsプラットフォーム上のポート2001でレジストリを起動するには、次のようにします。
start rmiregistry 2001
注: rmiregistry
のクラス・パスにはローカルのクラス・パスからクラスをロードしないようにする実装クラスが何もないことを確認してください。
レジストリが1099以外のポートで実行される予定の場合は、Setup
プログラム内、およびこのレジストリにアクセスするすべてのクライアント内のLocateRegistry.getRegistry
の呼出しに、ポート番号を指定する必要があります。たとえば、この例でレジストリをポート番号2001で実行する場合、getRegistry
の呼出しは次のようになります。
Registry registry = LocateRegistry.getRegistry(2001);
また、1099
以外のレジストリ・ポートを使う場合は、Setup
およびクライアント・プログラムのポリシー・ファイルを変更して、そのレジストリのポートへの接続許可を与える必要もあります。
Setup
プログラムの実行Setup
プログラムを起動するには、次のjava
コマンドを使用してSetup
クラスを実行します。
java -cp setupDir:implDir \ -Djava.security.policy=setup.policy \ -Djava.rmi.server.codebase=codebase \ -Dexamples.activation.setup.codebase=setupCodebase \ -Dexamples.activation.impl.codebase=implCodebase \ -Dexamples.activation.name=name \ [-Dexamples.activation.file=file] \ [-Dexamples.activation.policy=group.policy] \ examples.activation.Setup implClass
次にそれぞれの意味を示します。
Setup
プログラムのクラスのルート・ディレクトリですSetup
プログラムのセキュリティ・ポリシー・ファイルですSetup
プログラムのクラスの場所(URL)です(setup.policyファイルでSetup
プログラムにアクセス権を付与するときに使用)data
として登録されているオブジェクトの持続状態が書かれたファイルの名前です(デフォルト値: なし)group.policy
)注: 上記のいずれかのコード・ベースのファイルURLを使用する場合は、各ファイルURLの末尾にスラッシュがあることを確認してください。末尾にスラッシュがない場合、コード・ベースは無効になります。
Setup
プログラムからの出力は、次のようになります。
Activation group descriptor registered. Activation descriptor registered. Stub bound in registry.