2 つのアセンブリがあります
。1) シリアライザーを含むアセンブリ。これは、シリアライゼーションとデシリアライゼーションが開始される場所です。
2) シリアル化された型を含むアセンブリ。これは、最初のアセンブリからシリアライザを呼び出している場所です。
assembly1 のシリアライザーの考え方は単純です。バイト配列との間のオブジェクトの変換に使用される 2 つのメソッドがあります。そのシリアライザーのクライアント コードは次のようになります。
ISerializer serializer = ...
MyClass my = new MyClass();
byte[] data = serializer.Serialize(my);
Console.WriteLine(Encoding.ASCII.GetString(data)); // dump serialized form
MyClass another = (MyClass)serializer.Deserialize(data);
MyClass は assembly2 で定義されているため、assembly1 はそれについて何も知りません。このシナリオは、シリアライザーが次のように標準の .Net クラスで実装されている場合に機能します。
public class DotNetSerializer : ISerializer
{
public byte[] Serialize(object obj)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
byte[] result = stream.GetBuffer();
Array.Resize(ref result, (int)stream.Length);
return result;
}
}
public object Deserialize(byte[] data)
{
BinaryFormatter formatter = new BinaryFormatter();
using (Stream stream = new MemoryStream(data))
{
return formatter.Deserialize(stream);
}
}
}
MyClass のシリアル化された形式には、MyClass が定義されているアセンブリに関する情報が含まれます。ただし、(IKVM で変換された) Java のクラスを使用してシリアライザーが実装される場合、逆シリアル化中に ClassNotFound 例外がスローされます。これは、Java クラスを使用したシリアライザーの実装です。
public class JavaSerializer : ISerializer
{
public object Deserialize(byte[] data)
{
ByteArrayInputStream stream = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(stream);
return ois.readObject();
}
public byte[] Serialize(object obj)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(stream);
oos.writeObject(obj);
stream.flush();
return stream.toByteArray();
}
}
これは .Net では機能しませんが、BuddyPolicy や RegisterBuddy などのプラグイン マニフェストに追加のエントリを指定して Eclipse からロードした場合、Java では正常に機能します。JavaSerializer から DotNetSerializer に切り替えることはできません。私のアプリケーション (ほとんどが Java で記述されている) には、readObject、writeObject、readResolve などがたくさんあるためです。 . 現在、いくつかの仮説的な解決方法があります。
- ObjectOutputStream のいくつかのメソッドをオーバーロードするため、MyClass のシリアル化された形式には、「MyClass、MyAssembly、...」などのアセンブリ名も含まれます。
- ObjectInputStream でいくつかのメソッドをオーバーロードするため、クラスは別の方法でロードされます。おそらく、別のアセンブリで検索する必要があります。
- IKVM が MyClass を検索する場所を認識できるように、アセンブリ マニフェストにいくつかの情報を追加します。これの何かは本当ですか?この問題はどのように解決されるべきですか?