アクティベーションの使用: Setupプログラム

このチュートリアルでは、リモート・オブジェクトの起動記述子をJava Remote Method Invocation (Java RMI)起動システム・デーモン(rmid)に登録し、rmiregistryでそのリモート・オブジェクトのスタブをバインドしてクライアントが検索できるようにするプログラムの記述方法について説明します。

このチュートリアルでは、次の手順を実行します。

このチュートリアルの実行に必要なファイルは、次のとおりです。

Setupプログラムの実装

examples.activation.Setupクラスにより実装されるSetupプログラムは、起動記述子をrmidに登録して、その起動記述子によって指定されるオブジェクトの将来のアクティベーションを可能にします。このプログラムではリモート・オブジェクトのインスタンスは生成されませんが、代わりにリモート・オブジェクトのスタブをrmiregistryに登録して、クライアントが検索できるようにします。このSetupプログラムは、アクティベーションに関するほかのチュートリアルで説明されているどのクライアントを実行するよりも前に実行する必要があります。

Setupプログラムでは、多くのシステム・プロパティを使用して、rmidrmiregistryに登録されている情報をカスタマイズします。また、このプログラムでは、登録されている起動可能なリモート・オブジェクトの実装クラスのパッケージ修飾された名前を指定する、単一コマンド行の引数を取ります。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プログラムのポリシー・ファイルの例を次に示します。

  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プログラムには、次のアクセス権が必要です。

この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プロパティは、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つのアクセス権が必要です。

グループ記述子の登録

次に、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.java
setupDirは、クラス・ファイルを配置するルート・デスティネーション・ディレクトリです。

rmidrmiregistry、および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のセキュリティ・ポリシー・ファイルは、起動グループVMの起動時に、rmidが特定のコマンドを実行し、特定のコマンド行オプションを使用するアクセス権を付与します。たとえば、ユーザーは、1つまたは複数のシステム・プロパティ、またはほかのjavaコマンド行オプションを使用して、起動グループVMを起動する特定のアクセス権を付与することができます。この例では、rmidがシステム・プロパティjava.security.policyjava.class.pathexamples.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

次にそれぞれの意味を示します。

: 上記のいずれかのコード・ベースのファイルURLを使用する場合は、各ファイルURLの末尾にスラッシュがあることを確認してください。末尾にスラッシュがない場合、コード・ベースは無効になります。

Setupプログラムからの出力は、次のようになります。

Activation group descriptor registered.
Activation descriptor registered.
Stub bound in registry.

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.