2

クラスの異なるバージョン間での下位互換性のためのフレームワークに取り組んでいます (シリアル化されたバイナリ表現から)。

私が行き詰まっていることの1つは、クラスで使用されるフィールドを、実行時にフィールドのクラスの別のバージョンに置き換える方法です。

問題のクラスが親オブジェクトである場合、クラスローダーを使用してそれを行う方法を知っています( Java - 同じクラスの異なるバージョンをロードする方法は? )。

しかし、これは、既にオブジェクトがあり、そのフィールドを変更する必要がある場合 (または方法がわからない場合) には機能しません。リフレクション API には、インスタンス化された後にクラスを設定するメソッドもないようです。

分かりやすいように例を出します。ラッパークラスがあるとしましょう:

class Wrapper{
  int version;
  Object content;
}

ここで、変数 content としてロードしているクラスが 20 バージョン前に変更されたとします。当時から使用されていた元の .java (または .class-) ファイルがまだあります。私がやろうとしているのは、コンテンツの古いクラス バージョンでラッパーのインスタンスを作成し、それをディスクからロードし、それを変換して、コンテンツに使用されるクラスの現在のバージョンでラッパーの最新バージョンに書き込むことです。

また、非常に汎用的である必要があるため、ラッパーで実際のクラスではなくオブジェクトを使用しているのはそのためです。本当の問題は、プロトスタッフのランタイム (デ) シリアル化にこれが必要だということです。つまり、Wrapper.class を protostuff に渡し、シリアル化スキーマを生成します。これは現在、wrapper.class ファイルが新しいバージョン (プロジェクトのパッケージにある) を自動的に参照するため、失敗します。

Schema<Wrapper> schema= RuntimeSchema.getSchema(Wrapper.class);
Wrapper resultWrapper = schema.newMessage();

これがクラスローダーを通過するかどうかはわかりません。しなければならないとは思いますが、これがいつ起こるかはわかりません。

これにアプローチする最良の方法は何ですか?

4

1 に答える 1

1

できることの 1 つは、ClassLoaderバージョンごとに個別のオブジェクトを用意することです。はクラスのアイデンティティの一部であるため、そのClassLoaderパッケージと名前に加えて、クラスの複数のバージョンをメモリに保持できます。このアプローチの唯一の問題は、これらのオブジェクトを操作するためにリフレクションに頼ることになることです。

次に、現在のバージョンのオブジェクトを作成し、リフレクションを使用してそれらのフィールドの値を転送できます。これにより、実行時にフィールド タイプを変更しなければならないという問題を回避できます。

于 2015-02-24T15:50:02.703 に答える