私は非常に奇妙な問題を抱えています。大きな程度ではありませんが、変更された 2 つのクラスで HashMap を逆シリアル化しようとしています。著作権で保護されているため、コードを投稿できません。
特に、クラス 2 のコンストラクターには、逆シリアル化しようとしているファイルがシリアル化されているため、フィールド (文字列名) が追加されています。
クラス 1 は、クラス 2 の名前フィールドとして文字列にキャストしようとしているようです。
私は常に ObjectInputStream と ObjectOutputStream を使用しています。私が当惑したのは、クラス 1 にはクラス 2 型のメンバー変数がなく、HashMap 型は常に . 何が起こっているのかよくわからないので、この質問に投稿された解決策を試してみましたが、これには私が得ているのと同じ例外がありましたが、ClassLoaders に関する多くの調査にもかかわらず、私はまだ本当に理解しておらず、本当に知りませんでした「自由変数」として使用するクラスローダーを知っています。
私が遭遇している問題のスタック トレース (クラス名が変更されています) は次のとおりです。
java.lang.ClassCastException: cannot assign instance of [CLASS 1] to field [CLASS 2].name of type java.lang.String in instance of [CLASS 2]
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2034)
at java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.java:1207)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1975)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1327)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349)
at java.util.HashMap.readObject(HashMap.java:1030)
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1327)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349)
コードスニップ:
final ClassLoader loader = this.getClass().getClassLoader(); //attempt to solve ClassCastException issue below.
FileInputStream fin = new FileInputStream(targetFile);
InputStream buffer = new BufferedInputStream(fin);
ObjectInputStream ois = new ObjectInputStream(buffer) {
/*
* As seen here: https://stackoverflow.com/questions/2358886/how-can-i-deserialize-the-object-if-it-was-moved-to-another-package-or-renamed
*/
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
if (resultClassDescriptor.getName().equals("Class 1 [old path]"))
resultClassDescriptor = ObjectStreamClass.lookup(Class 1 [new path].class);
else if (resultClassDescriptor.getName().equals("Class 2 [old path]"))
resultClassDescriptor = ObjectStreamClass.lookup(Class 2 [new path].class);
return resultClassDescriptor;
}
/*
* As seen here : https://stackoverflow.com/questions/9110677/readresolve-not-working-an-instance-of-guavas-serializedform-appears
*/
@SuppressWarnings("rawtypes")
@Override
protected Class resolveClass(ObjectStreamClass objectStreamClass)
throws IOException, ClassNotFoundException {
return Class.forName(objectStreamClass.getName(), true, loader);
}
};
Object ob = ois.readObject(); //exception happens here
HashMap<Class 1, Class 2> loadedMap = (HashMap<Class 1, Class 2>)ob;
ois.close();
buffer.close();
fin.close();