目次 | 前の項目 | 次の項目 | Java Remote Method Invocation |
RMI 起動プロトコルでは、システムの正常な動作のために、アクティベータは、次の 2 つの規約を保証します。
アクティベータは、起動処理に関与するグループとオブジェクトから成る適切な情報のデータベースを保持します。
アクティベータは、起動プロセス中にかかわるエンティティの 1 つです。前述したように、フォルト参照 (スタブ内) は、起動可能リモートオブジェクトへの「ライブ」参照を取得するため、アクティベータのactivate
メソッドを呼び出します。アクティベータは、起動要求を受け取ると、指定された起動識別子に対応する起動記述子を探し、そのオブジェクトを起動すべきグループを特定して、その起動グループのインスタンシエータのnewInstance
メソッドを呼び出します (リモートインタフェース ActivationGroup については後述)。必要であれば、アクティベータは起動グループの実行を開始します。たとえば、特定のグループ記述子に対応する起動グループがまだ実行されていない場合、アクティベータはその起動グループの子 VM を生成し、生成した VM 内で起動グループを立ち上げます。アクティベータは、起動グループのエラーを監視、検出し、エラーの際は、その内部テーブルから古いリモート参照を削除します。
package java.rmi.activation; public interface Activator extends java.rmi.Remote { java.rmi.MarshalledObject activate(ActivationID id, boolean force) throws UnknownObjectException, ActivationException, java.rmi.RemoteException; }
activate
メソッドは、起動識別子 id に関連付けられたオブジェクトを起動します。そのオブジェクトがすでにアクティブな状態にあることをアクティベータが知っており、なおかつ force パラメータが false の場合は、スタブが「ライブ」参照とともにただちに呼び出し側に返されます。一方、対応するリモートオブジェクトがアクティブな状態にあることをアクティベータが知らないか、または force パラメータが true の場合は、アクティベータは起動記述子情報 (前に id を取得するため登録したもの) を使用して、オブジェクトを起動すべきグループ (VM) を特定します。特定したオブジェクトのグループに対応する ActivationInstantiator がすでに存在する場合は、アクティベータは起動インスタンシエータのnewInstance
メソッドを、オブジェクトの id と起動記述子を引数として呼び出します。特定したオブジェクトのグループ記述子に対応する起動インスタンシエータ (グループ) がまだ存在しない場合は、アクティベータは、子プロセスを生成するなどの方法により ActivationInstantiator の新しい生成の実行を開始させます。アクティベータは、特定のグループの ActivationInstantiator を再作成するときは、そのグループの生成番号をインクリメントしなければなりません。生成番号はゼロから始まります。起動システムは、生成番号により、新しい
ActivationSystem.activeGroup
およびActivationMonitor.inactiveGroup
の呼び出しを検出します。同じグループで、現在の生成番号よりも若い生成番号を持つ呼び出しは破棄されます。
注 - 新しい起動グループを実行するときは、アクティベータは起動グループの識別子、記述子、および生成番号を利用しなければなりません。アクティベータは、独立した VM 内 (たとえば、別のプロセスや子プロセスとして) で起動グループを生成します。したがって、アクティベータは、ActivationGroup.createGroup
メソッドで起動グループを作成するのに必要な情報を引き渡す必要があります。この情報を生成されたプロセスにどのように引き渡すかについては規定されていませんが、整列化されたオブジェクトの形式で子プロセスの「標準入力」に送ることが可能です。
アクティベータは、ActivationSystem.activeGroup
メソッドにより起動グループの参照と生成番号が含まれる起動グループのコールバックを受け取ると、その起動インスタンシエータのnewInstance
メソッドを呼び出して、保留状態になっている起動要求を起動インスタンシエータに転送し、結果 (「整列化された」リモートオブジェクトの参照、つまりスタブ) をそれぞれの呼び出し側に返すことができます。アクティベータは、オブジェクトのコードをロードしたり、オブジェクトの分散ガベージコレクションに関与したりしなくてもよいように、Remote オブジェクトではなく MarshalledObject を受け取ります。リモートオブジェクトへの強い参照を保持していれば、通常の分散ガベージコレクション機構の下では、アクティベータはリモートオブジェクトがガベージコレクトされるのを防ぐことができます。
起動が失敗した場合、
activate
メソッドは ActivationException をスローします。起動が失敗する原因としては、クラスが見つからない、起動グループにアクセスできないなど、さまざまな理由があります。指定された起動識別子 id に対応する起動記述子がこのアクティベータで登録されていない場合は、activate
メソッドは UnknownObjectException をスローします。アクティベータのリモート呼び出しが失敗した場合は、RemoteException をスローします。
ActivationSystem は、グループと、そのグループ内で起動すべき「起動可能」オブジェクトを登録する手段を提供します。ActivationSystem は、ActivationSystem で登録されたオブジェクトを起動する Activator と、アクティブなオブジェクトや、アクティブでないオブジェクト、またはアクティブでないグループに関する情報を取得する ActivationMonitor の双方と密接に共同動作します。
package java.rmi.activation; public interface ActivationSystem extends java.rmi.Remote { public static final int SYSTEM_PORT = 1098; ActivationGroupID registerGroup(ActivationGroupDesc desc) throws ActivationException, java.rmi.RemoteException; ActivationMonitor activeGroup(ActivationGroupID id, ActivationInstantiator group, long incarnation) throws UnknownGroupException, ActivationException, java.rmi.RemoteException; void unregisterGroup(ActivationGroupID id) throws ActivationException, UnknownGroupException, java.rmi.RemoteException; ActivationID registerObject(ActivationDesc desc) throws ActivationException, UnknownGroupException, java.rmi.RemoteException; void unregisterObject(ActivationID id) throws ActivationException, UnknownObjectException, java.rmi.RemoteException; void shutdown() throws java.rmi.RemoteException; }
注 - セキュリティ保護のため、上記のすべてのメソッド (registerGroup
、activeGroup
、unregisterGroup
、registerObject
、unregisterObject
、およびshutdown
) は、起動システムとは異なるホスト上で動作しているクライアントから呼び出された場合、java.rmi.RemoteException
のサブクラスであるjava.rmi.AccessException
をスローします。
registerObject
メソッドは、起動記述子 desc の登録と、起動可能リモートオブジェクトの起動識別子の取得に使用します。ActivationSystem は、起動記述子 desc で指定されたオブジェクトの ActivationID (起動識別子) を作成し、起動記述子と、それに関連付けられた識別子を安定した記憶領域に記録します。Activator は、特定の識別子を対象としたactivate
要求を受け取ると、指定された識別子に対応する起動記述子 (前に登録したもの) を探し、その情報を使用してオブジェクトを起動します。desc で参照されているグループがこのシステムに登録されていない場合は、registerObject
メソッドは UnknownGroupException をスローします。データベースの更新の失敗などが原因で登録が失敗した場合は、ActivationException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。
unregisterObject
は、起動識別子 id と、それに関連付けられ、ActivationSystem に登録されている記述子を削除します。呼び出し完了後は、オブジェクトはその起動 id では起動できなくなります。指定されたオブジェクト id が起動システムが知らない (登録されていない) 識別子である場合は、unregisterObject
メソッドは UnknownObjectException をスローします。データベース更新の失敗などが原因で登録解除処理が失敗した場合は、ActivationException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。
registerGroup
メソッドは、グループ記述子 desc で指定された起動グループを起動システムに登録し、そのグループに割り当てられた ActivationGroupID を返します。オブジェクトを起動グループに登録する前に、その起動グループを ActivationSystem に登録しておく必要があります。グループの登録が失敗した場合は、このメソッドは ActivationException をスローします。リモート呼び出しが失敗した場合は、ActivationException をスローします。
activeGroup
メソッドは、ActivationGroup からのコールバック (識別子 id を伴う) であり、group が現在アクティブな状態にあり、その VM の ActivationInstantiator になっていることを起動システムに知らせます。このメソッドは、そのグループ内のグループまたはオブジェクトがアクティブでなくなったなど、オブジェクトとグループの状態の変化をシステムに伝えるためにグループが使用する ActivationMonitor を取得するため、ActivationGroup.createGroup
メソッドにより内部的に呼び出されます。指定されたグループが登録されていない場合は、activeGroup
メソッドは UnknownGroupException をスローします。指定されたグループがすでにアクティブな状態にある場合は、ActivationException をスローします。起動システムのリモート呼び出しが失敗した場合は、RemoteException をスローします。
unregisterGroup
メソッドは、指定された識別子 id を持つ起動グループを起動システムから削除します。起動グループは、自分自身を破棄すべきであることをアクティベータに伝えるため、このコールバックを行います。この呼び出しが成功した場合は、そのグループにオブジェクトを登録したり、そのグループ内でオブジェクトを起動したりすることはできなくなります。そのグループに関する情報と、そのグループに関連付けられたオブジェクトはすべてシステムから削除されます。指定されたグループが登録されていない場合は、このメソッドは UnknownGroupException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。データベースの更新の失敗などが原因で登録解除に失敗した場合は、ActivationException をスローします。
shutdown
メソッドは、起動システムと、関連するすべての起動プロセス (アクティベータ、モニタ、およびグループ) を所定の手順により非同期に終了させます。起動デーモンによって生成されたグループはすべて破棄され、起動デーモンはその実行を終了します。起動システムデーモン rmid を停止させるには、次のコマンドを実行します。
rmid -stop [-port num]
このコマンドは、指定したポートで動作している起動デーモンを停止させます。ポートの指定を省略した場合は、デフォルトポート上の起動デーモンが停止されます。
ActivationMonitor は ActivationGroup に固有のクラスで、ActivationSystem.activeGroup
の呼び出し (ActivationGroup.createGroup
メソッドにより内部的に呼び出される) によりグループの報告が行われたときに取得されます。起動グループは、そのオブジェクトがアクティブになったとき、アクティブでなくなったとき、またはグループ全体がアクティブでなくなったときに、そのことを ActivationMonitor に伝える必要があります。
package java.rmi.activation; public interface ActivationMonitor extends java.rmi.Remote { public abstract void inactiveObject(ActivationID id) throws UnknownObjectException, RemoteException; public void activeObject(ActivationID id, java.rmi.MarshalledObject mobj) throws UnknownObjectException, java.rmi.RemoteException; public void inactiveGroup(ActivationGroupID id, long incarnation) throws UnknownGroupException, java.rmi.RemoteException; }
起動グループは、そのモニタのinactiveObject
メソッドを、グループ内のオブジェクトがアクティブでなくなったときに呼び出します。起動グループは、その VM 内のオブジェクト (グループがその起動にかかわったオブジェクト) が、起動グループのinactiveObject
メソッドの呼び出しによりアクティブでなくなったことを検出します。
inactiveObject
は、起動識別子 id を持つオブジェクトを指すリモートオブジェクト参照が有効でなくなったことを ActivationMonitor に知らせます。これにより、モニタは id に関連付けられた参照が古い参照であると見なします。この参照は古い参照であると見なされるため、それ以降、同じ起動識別子を指定してactivate
を呼び出すと、リモートオブジェクトは再度起動されます。指定されたオブジェクトが ActivationMonitor が知らないオブジェクトである場合は、inactiveObject
メソッドは UnknownObjectException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。
activeObject
は、id に関連付けられたオブジェクトが現在アクティブな状態にあることを ActivationMonitor に知らせます。パラメータ mobj には、オブジェクトの整列化された形式のスタブを指定します。ActivationGroup は、グループ内のオブジェクトがシステムにより直接起動される以外の方法でアクティブになった場合 (オブジェクトが自分自身で登録して起動した場合など) は、それをモニタに知らせなければなりません。指定されたオブジェクト id が登録されていない場合は、activeObject
は UnknownObjectException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。
inactiveGroup
は、id と incarnation で指定されたグループが現在アクティブでないことをモニタに知らせます。グループ内のオブジェクトを起動する要求がそれ以降発生すると、グループはより大きな生成番号で再作成されます。グループ内のすべてのオブジェクトが、自分がアクティブでなくなったことを報告すると、グループはアクティブでなくなります。指定されたグループ id が登録されていないか、指定された生成番号がグループの現在の生成番号よりも小さい場合は、inactiveGroup
メソッドは UnknownGroupException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。
ActivationInstantiator は、起動可能オブジェクトのインスタンスを生成する役割を持ちます。ActivationGroup の具体的なサブクラスでは、グループ内でのオブジェクトの作成を処理するためnewInstance
を実装しています。
package java.rmi.activation; public interface ActivationInstantiator extends java.rmi.Remote { public MarshalledObject newInstance(ActivationID id, ActivationDesc desc) throws ActivationException, java.rmi.RemoteException; }
アクティベータは、起動識別子 id と起動記述子 desc を持つオブジェクトをグループ内に再作成するため、インスタンシエータのnewInstance
メソッドを呼び出します。インスタンシエータは、次のような役割を持ちます。
また、インスタンシエータは、適切なinactiveObject
を呼び出せるように、作成または起動したオブジェクトがアクティブでなくなったことをその ActivationMonitor に報告する役割も持ちます (詳細は ActivationGroup クラスを参照)。オブジェクトの起動が失敗した場合は、newInstance メソッドは ActivationException をスローします。リモート呼び出しが失敗した場合は、RemoteException をスローします。
起動グループ記述子 (ActivationGroupDesc) には、同じ Java VM 内でオブジェクトを起動する起動グループを作成または再作成するのに必要な情報が含まれます。
グループのクラスは、ActivationGroup の具体的なサブクラスでなければなりません。ActivationGroup のサブクラスは、次の 2 つの引数をとる特別なコンストラクタを呼び出す static メソッドActivationGroup.createGroup
により作成または再作成されます。
package java.rmi.activation; public final class ActivationGroupDesc implements java.io.Serializable { public ActivationGroupDesc(java.util.Properties props, CommandEnvironment env);; public ActivationGroupDesc(String className, String codebase, java.rmi.MarshalledObject data, java.util.Properties props, CommandEnvironment env); public String getClassName(); public String getLocation(); public java.rmi.MarshalledObject getData(); public CommandEnvironment getCommandEnvironment(); public java.util.Properties getPropertiesOverrides(); }
1 つ目のコンストラクタは、グループの実装とコードの場所としてシステムの既定値を使用するグループ記述子を作成します。プロパティでは、Java 環境のオーバーライド値 (グループの実装の VM におけるシステムプロパティをオーバーライドする値) を指定します。コマンド環境を使用すれば、子 VM の起動に使用するコマンドやオプションを細かく指定できます。null に設定すれば、rmid の既定値が使用されます。2 つ目のコンストラクタは 1 つ目のコンストラクタと同じですが、Properties と CommandEnvironment を指定できます。
getClassName
メソッドは、グループのクラス名を返します。
getLocation
メソッドは、グループのクラスのロード元となるコードベースパスを返します。
getData
メソッドは、整列化された形式のグループの初期化データを返します。getCommandEnvironment メソッドは、コマンド環境 (null の場合もあり) を返します。
getPropertiesOverrides メソッドは、この記述子のプロパティのオーバーライド (null の場合もあり) を返します。
CommandEnvironment クラスでは、デフォルトのシステムプロパティをオーバーライドしたり、実装によって定義される ActivationGroup のオプションを指定したりすることができます。
public static class CommandEnvironment implements java.io.Serializable { public CommandEnvironment(String cmdpath, String[] args); public boolean equals(java.lang.Object); public String[] getCommandOptions(); public String getCommandPath(); public int hashCode(); }
このコンストラクタは、指定されたコマンド cmdpath と追加のコマンド行オプション args を使って、CommandEnvironment を生成します。
equals
は、コマンド環境オブジェクトと内容が等しいかどうかをチェックします。hashCode
メソッドでは、必要に応じて CommandEnvironment をハッシュテーブルに格納できます。getCommandOptions メソッドは、環境オブジェクトのコマンド行オプションを返します。
getCommandPath メソッドは、環境オブジェクトのコマンド文字列を返します。
登録された起動グループの識別子は、次のような役割を持ちます。
ActivationGroupID は、ActivationSystem.registerGroup を呼び出すことで取得でき、起動システム内でのグループの識別に使用されます。このグループ識別子は、起動グループの作成または再作成時に、起動グループの特別なコンストラクタに引数として引き渡すことができます。
package java.rmi.activation; public class ActivationGroupID implements java.io.Serializable { public ActivationGroupID(ActivationSystem system); public ActivationSystem getSystem(); public boolean equals(Object obj); public int hashCode(); }
ActivationGroupID のコンストラクタは、ActivationSystem が system で指定された一意のグループ識別子を作成します。
getSystem
メソッドは、グループの起動システムを返します。
hashCode
メソッドは、グループの識別子のハッシュコードを返します。同じリモートグループを参照する 2 つのグループ識別子は、同じハッシュコードを持ちます。
equals
メソッドは、2 つのグループ識別子を比較して、内容が等しいかどうかを調べます。このメソッドは、一意の識別子が内容的に同一であり、なおかつ、それぞれの識別子で指定された起動システムが同一のリモートオブジェクトを参照している場合は、true を返します。
ActivationGroup は、そのグループ内に「起動可能」オブジェクトの新しいインスタンスを生成し、そのオブジェクトがアクティブになったとき、アクティブでなくなったとき、またはグループ全体がアクティブでなくなったときに、そのことを ActivationMonitor に知らせる役割を持ちます。ActivationGroup が「最初に」作成されるのは、次のどれかの場合です。
ActivationGroup を「再作成」できるのはアクティベータだけです。アクティベータは、登録されている起動グループごとに、必要に応じて独立した VM (たとえば、子プロセスとして) を生成し、起動要求を適切なグループに転送します。VM をどのように生成するかは、実装に任せられます。起動グループは、static メソッドActivationGroup.createGroup
により作成します。createGroup
メソッドには、作成するグループに関して、1) グループは ActivationGroup の具体的なサブクラスでなければならない、2) グループは次の 2 つの引数をとるコンストラクタを持っていなければならない、という決まりがあります。
作成時、ActivationGroup のデフォルトの実装では、システムプロパティは ActivationGroupDesc が作成されたときのシステムプロパティ値に設定され、セキュリティマネージャは java.rmi.RMISecurityManager に設定されます。グループ内でオブジェクトが起動されるときに、いくつかのプロパティについては独自の値を設定したい場合は、任意の ActivationDesc が作成される前、つまり、デフォルトの ActivationGroupDesc が作成される前に設定するようにすべきです。
package java.rmi.activation; public abstract class ActivationGroup extends UnicastRemoteObject implements ActivationInstantiator { protected ActivationGroup(ActivationGroupID groupID) throws java.rmi.RemoteException; public abstract MarshalledObject newInstance(ActivationID id, ActivationDesc desc) throws ActivationException, java.rmi.RemoteException; public abstract boolean inactiveObject(ActivationID id) throws ActivationException, UnknownObjectException, java.rmi.RemoteException; public static ActivationGroup createGroup(ActivationGroupID id, ActivationGroupDesc desc, long incarnation) throws ActivationException; public static ActivationGroupID currentGroupID(); public static void setSystem(ActivationSystem system) throws ActivationException; public static ActivationSystem getSystem() throws ActivationException; protected void activeObject(ActivationID id, java.rmi.MarshalledObject mobj) throws ActivationException, UnknownObjectException, java.rmi.RemoteException; protected void inactiveGroup() throws UnknownGroupException, java.rmi.RemoteException; }
アクティベータは、起動記述子 desc を持つオブジェクトを起動するため、起動グループのnewInstance
メソッドを呼び出します。起動グループは、次のような役割を持ちます。
指定された記述子に対応するインスタンスを生成できなかった場合は、newInstance
メソッドは ActivationException をスローします。グループの
inactiveObject
メソッドは、Activatable.inactive
メソッドの呼び出しを介して間接的に呼び出されます。リモートオブジェクトの実装では、そのオブジェクトがアクティブでなくなったとき (アクティブでなくなったとみなされるとき) に Activatable のinactive
メソッドを呼び出さなければなりません。オブジェクトは、アクティブでなくなったときにActivatable.inactive
を呼び出すようにしないと、グループは作成したオブジェクトへの強い参照を保持したままになるため、そのようなオブジェクトのガベージコレクトは行われなくなります。グループの
inactiveObject
メソッドは、リモートオブジェクトがクライアントからの RMI 呼び出しに応じられないようにするため、id に関連付けられたリモートオブジェクトを RMI ランタイムからアンエクスポートします。ただし、アンエクスポートされるのは、そのリモートオブジェクトに対する保留状態の呼び出しや実行中の呼び出しがない場合に限ります。保留状態の呼び出しや実行中の呼び出しがある場合、inactiveObject
は false を返し、処理は何も行いません。
unexportObject
処理が成功した場合、つまり、そのリモートオブジェクトに対する保留状態の呼び出しや実行中の呼び出しがない場合、グループは、リモートオブジェクトが現在アクティブでない状態にあり、したがって、それ以降の起動要求時にはアクティベータによって再度起動できることを、その ActivationMonitor に知らせます (モニタのinactiveObject
を使用)。処理が成功した場合、inactiveObject
は true を返します。リモートオブジェクトがすでにアンエクスポートされていても、ActivationGroup によってアクティブな状態にあると見なされる場合は、この処理は成功することがあります。このオブジェクトがアクティブでないとすでに報告されている場合や、この起動グループで一度も起動されたことがない場合など、起動グループがこのオブジェクトを知らない場合は、
inactiveObject
メソッドは UnknownObjectException をスローします。アクティベータまたは起動グループのリモート呼び出しが失敗した場合など、非起動処理が失敗した場合は、RemoteException をスローします。
createGroup
メソッドは、現在の VM 用に起動グループを作成し、設定を行います。起動グループを設定できるのは、それが現在設定されていない場合だけです。起動グループは、activate
要求を処理するため、Activator が起動グループの再作成を開始したときにcreateGroup
によって設定されます。グループをこのメソッドで作成する前には、グループ記述子を ActivationSystem に登録しておく必要があります (前の登録から得た ActivationID を渡す)。ActivationGroupDesc (desc) で指定するグループは、ActivationGroup の具体的なサブクラスでなければならず、そのグループの ActivationGroupID と、そのグループの初期化データが含まれた MarshalledObject (ActivationGroupDesc から取得) の 2 つの引数をとる public コンストラクタを持っていなければなりません。注: 独自のカスタム起動グループを作成する場合、グループのコンストラクタでセキュリティマネージャを設定するようにしなければなりません。コンストラクタ内にセキュリティマネージャを設定しないと、グループの中でオブジェクトを起動することはできません。
グループが作成されたら、グループの ActivationMonitor を返す
activeGroup
メソッドの呼び出しによりグループがアクティブな状態になったことが、ActivationSystem に知らされます。このコールバックの処理はcreateGroup
メソッドが行うので、アプリケーション側で個別にactiveGroup
を呼び出す必要はありません。グループが作成されると、それがアクティブでなくなるまで
currentGroupID
メソッドによりこのグループの識別子が返されます。グループがアクティブでなくなると、currentGroupID
メソッドは null を返します。パラメータ incarnation は、グループの現在の生成番号 (このグループが起動された回数を表す) を示します。生成番号は、グループの作成に成功した後、
activeGroup
メソッドへのパラメータとして使用されます。生成番号はゼロから始まります。指定されたグループがすでに存在する場合、またはグループの作成中にエラーが発生した場合は、createGroup
メソッドは ActivationException をスローします。
setSystem
メソッドは、VM の ActivationSystem (system) を設定します。起動システムを設定できるのは、アクティブな状態のグループがない場合だけです。setSystem
の明示的な呼び出しにより起動システムが設定されなかった場合、getSystem
メソッドは、アクティベータのレジストリから java.rmi.activation.ActivationSystem という名前を探すことで ActivationSystem への参照の取得を試みます。起動システムを探すためにデフォルトで使用されるポート番号は、ActivationSystem.SYSTEM_PORT で定義されています。この値は、java.rmi.activation.port プロパティを設定することでオーバーライドできます。setSystem
メソッドを呼び出したときにすでに起動システムが設定されている場合は、setSystem
メソッドは ActivationException をスローします。
getSystem
メソッドは、VM の起動システムを返します。起動システムはsetSystem
メソッドで設定できます (前述)。
activeObject
メソッドは、指定された起動 id を持ち、スタブが mobj に含まれるリモートオブジェクトが現在アクティブな状態にあることをグループのモニタに知らせるため、モニタへのactiveObject
コールバックを行うことを目的としてサブクラスが使用する protected メソッドです。このメソッドの呼び出しは、単純にグループの ActivationMonitor に転送されます。
inactiveGroup
メソッドは、グループがアクティブでなくなったことをグループのモニタに知らせるため、サブクラスが使用する protected メソッドです。サブクラスは、VM の中でグループが起動にかかわっているオブジェクトがアクティブでなくなるたびに、このメソッドを呼び出します。
MarshalledObject はオブジェクトのコンテナで、RMI 呼び出しの際にオブジェクトをパラメータとして引き渡せるようにするものですが、受け取った側でのオブジェクトの直列化復元は、コンテナオブジェクトを介してアプリケーションがそのオブジェクトを明示的に要求するまで延期されます。MarshalledObject に含まれる直列化可能なオブジェクトは、RMI 呼び出しの際に引き渡されたパラメータと同じセマンティクスで、要求時に直列化および直列化復元が行われます。つまり、MarshalledObject に含まれるオブジェクトはすべて、そのスタブの直列化されたインスタンスにより表されます。MarshalledObject に含めることができるオブジェクトは、リモートオブジェクト、非リモートオブジェクト、またはリモートオブジェクトと非リモートオブジェクトのグラフ全体のどれかです。オブジェクトが MarshalledObject ラッパーの中に置かれると、直列化されたそのオブジェクトにコードベース URL (クラスのロード元) の情報が付加されます。同様に、MarshalledObject ラッパーからオブジェクトが取り出されるときは、そのオブジェクトのコードがローカルになければ、直列化の際に付加された URL から、そのオブジェクトのクラスのバイトコードがロードされます。
package java.rmi; public final class MarshalledObject implements java.io.Serializable { public MarshalledObject(Object obj) throws java.io.IOException; public Object get() throws java.io.IOException, ClassNotFoundException; public int hashCode(); public boolean equals(); }
MarshalledObject のコンストラクタは、引数として直列化可能なオブジェクト obj をとり、オブジェクトがバイトストリームに整列化された形式のものを保持します。整列化された形式のオブジェクトは、次のように、RMI 呼び出しの際に引き渡されるオブジェクトのセマンティクスを保持します。
MarshalledObject クラスのインスタンスが java.io.ObjectOutputStream に書き出されるときは、その中に含まれる整列化された形式のオブジェクト (構築時に作成されたもの) がストリームに書き出されます。したがって、バイトストリームだけが直列化されます。MarshalledObject が java.io.ObjectInputStream から読み出されるときは、その中に含まれるオブジェクトは具体的なオブジェクトに直列化復元はされません。整列化されたオブジェクトの
get
メソッドが呼び出されるまで、オブジェクトは整列化された形式のままです。
get
メソッドは、常に、整列化された形式で含められているオブジェクトの新しいコピーを再構築します。内部表現は、RMI 呼び出しの非整列化パラメータに対して使用されるセマンティクスで直列化復元されます。したがって、オブジェクトの表現を直列化復元すると、直列化されたオブジェクトのストリームに埋め込まれた URL 情報を使用してクラスコードがロードされます (ローカルにない場合)。整列化された形式のオブジェクトの
hashCode
は、コンストラクタに引き渡されたオブジェクトと同じです。equals
メソッドは、整列化された形式のオブジェクトどうしを比較し、それらが等価であれば true を返します。比較時には、クラスのコードベース情報は無視されます。したがって、直列化された形式のオブジェクトに含まれる各クラスのコードベースを除き、直列化表現が同じであれば、2 つのオブジェクトは等価になります。