0

POJO パラメータを持つメソッドを持つリモート クラスがあるとします。

class MyRemote implements Remote {

    void service(Param param) throws RemoteException;

}

クライアントはスタブを取得して、次のことを行います。

// DerivedParam is defined by the client
// and is derived from Param
DerivedParam dparam = getDerivedParam();
myService.service(dparam);

サーバーは DerivedParam クラス (およびおそらく実装するインターフェイス) について手がかりがないため、失敗します。

質問: これらのクラスをクライアントからサーバーに渡して、そのような呼び出しを可能にすることは可能ですか?

4

1 に答える 1

3

私はこのテーマの専門家ではありませんが、少し前にこのトリックを実行しました。マジックは、プロパティを設定することによるコード モビリティjava.rmi.server.codebaseの使用にあります。

このプロパティは、共有クラスが存在する URL またはスペースで区切られた URL のリストを指すようにします。これは、たとえば、共通のクラスを持つ jar ファイルが存在する FTP サーバーまたは HTTP サーバーである可能性があります。

セットアップが完了すると、サーバーとクライアントによってマーシャリングされたすべてのオブジェクトにコードベース アノテーションが含まれます。いずれかの当事者がクラスを見つけられない場合は、コード ベースで提供されている URL で検索し、動的にロードします。

Java RMI による動的コードのダウンロード をお読みください。

クライアント専用のインターフェースを提供し、実装は特定のコードベースに配置されるとします。次に、クライアントはサーバーに特定のオブジェクトを送信するように要求し、クライアントは特定のインターフェイスを実装するオブジェクトを受信することを期待しますが、実際の実装はクライアントには不明です。送信されたオブジェクトを逆シリアル化するときは、コードに移動する必要があるときです。渡される実際のオブジェクトに対応する実装クラスを base およびダウンロードします。

これにより、クライアントが非常に薄くなり、すべてのクライアントを更新する必要がなく、コード ベース内のクラスを非常に簡単に更新できます。

次のインターフェースを持つ RMI サーバーがあるとします。

public interface MiddleEarth {
     public List<Creature> getAllCreatures();
}

クライアントには と のインターフェースしかありMiddleEarthませCreatureんが、クラスパスには実装がありません。

の実装は、タイプ、、およびCreatureのシリアライズ可能なオブジェクトです。これらの実装はコード ベースにありますが、クライアントのクラス パスにはありません。ElfManDwarfHobbit

RMI サーバーに中つ国のすべての生物のリストを送信するように依頼するとCreature、上記のクラスのいずれかを実装するオブジェクトが送信されます。

クライアントはシリアライズされたオブジェクトを受け取ると、デシリアライズするためにクラス ファイルを探す必要がありますが、これらはローカル クラス パスにはありません。このストリーム内のすべてのオブジェクトは、欠落しているクラスを探すために使用できる特定のコード ベースでタグ付けされています。したがって、クライアントはコード ベースに頼ってこれらのクラスを探します。そこには、実際に使用されているクリーチャー クラスが表示されます。

コード ベースは双方向で動作するため、サーバーに a Creature(つまり an Ent) を送信すると、コード ベースでも検索されます。

これは、クライアントとサーバーの両方が新しいタイプのクリーチャーを公開する必要がある場合creaturesImpl.jar、コード ベースの を更新するだけで済み、サーバーまたはクライアント アプリケーション自体は何も更新しないことを意味します。

于 2012-05-29T12:24:00.970 に答える