0

RMI、シリアル化、およびランタイム ポリモーフィズムに関する質問があります。

以下のRMIサーバーがあります。

public interface Shape extends Remote, Serializable { 
    public double getArea() throws RemoteException;
}

public class Circle implements Shape {
  double radius;
  public Circle( double r) { radius = r; }
  public double getArea() { return Math.PI * radius * radius; }
}

Circle クラスのオブジェクトcObjが RMI レジストリに登録されます。

Circle cObj = new Circle (10);
registry.bind("cObj", cObj);

クライアント側では、CLASSPATH に Shape.class ファイルがありますが、CLASSPATH に Circle.class ファイルがありません。RMI クライアントで以下を実行することは可能ですか?

Shape obj = (Shape) registry.lookup("cObj");
obj.getArea();

Circle.class は RMI クライアントの CLASSPATH になく、クライアントのコードは Circle クラスを直接参照していないことに注意してください。Shape インターフェイス タイプのみを参照しています。

これをどのように見るかというと、クライアントがルックアップを実行し、cObj 名と Circle タイプのオブジェクトを見つける可能性があります。サーバーは Circle が Shape のサブタイプであることを認識し、オブジェクトをシリアル化してクライアントに送信します。現在、クライアントが Circle クラス定義にアクセスせずにそれをスーパークラス (Shape) 型にキャストできるかどうかはわかりません。

助けていただければ幸いです。

4

1 に答える 1

1

Circle クラスをクライアントにデプロイしたくない場合は、次の 2 つの選択肢があります。

  1. RMI コードベース機能を使用します。ここで説明するには大きすぎるトピックなので、調べる必要がありますが、基本的には、RMI サーバーによって指定された追加の場所からのクラスロードが可能になります。

  2. これをエクスポートされたリモート オブジェクトにして、その呼び出しが RMI 呼び出しでもあるようにします。Shape を Remote に拡張することで、すでに道半ばですが、UnicastRemoteObject を拡張するか、構築時に UnicastRemoteObject.exportObject() を呼び出して、Circle をエクスポートする必要もあります。

Remote を拡張することで、(2) を最初から実行するつもりだったように思えます。これを行う場合、Shape を Serializable に拡張する必要はありません。(2)をしないとShapeでRemoteを拡張しても意味がありません。どちらか一方を削除する必要があります。これらは相互に排他的です。

于 2013-01-31T22:17:34.050 に答える