Bug de sérialization avec writeReplace et ReadResolve ?
Bonjour,
J'ai le soucis suivant avec la sérialization en Java, j'ai effectué quelques recherches sur Google mais personne ne semble avoir rencontré le meme probleme...
J'essaie de sérializer des proxy CGLIB en les remplacant à la volée par des objets de transport lors de la sérialisation puis en recréant les proxy pendant la phase de déserialization. Pour faire cela j'utilise les fonctions writeReplace et readResolve prévues par l'algo de serialization Java.
Pour illustrer le probleme, j'ai créé une classe de test qui est une version tres simplifiée de mon cas concret d'utilisation, mais qui reproduit bien le probleme qui semble etre un bug.
Voici le code qui met en evidence le probleme :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
import java.io.*;
import java.util.Map;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.start();
}
static class Center implements Serializable {
public User user;
public String name;
}
static class User implements Serializable {
public Center center;
public String name;
public Object writeReplace() {
DataTransfer dt = new DataTransfer();
dt.params.put("name", name);
dt.params.put("center", center);
return dt;
}
}
static class DataTransfer implements Serializable {
public Map<String, Object> params = new HashMap<String, Object>();
public Object readResolve() {
User user = new User();
String name = (String) params.get("name");
Center center = (Center) params.get("center");
user.name = name;
user.center = center;
return user;
}
}
public static <I> I serialize(I o) {
try {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(buf);
out.writeObject(o);
out.flush();
out.close();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buf.toByteArray()));
Object dest = in.readObject(); // EXCEPTION LEVEE !!!
in.close();
return (I) dest;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void start() {
Center center = new Center();
center.name = "centre1";
User user = new User();
user.name = "Dupont";
user.center = center;
center.user = user;
User user1 = serialize(user);
System.err.println("result : "+user1);
}
} |
L'execution de ce programme produit un ClassCastException.
Il semble que le probleme vienne du fait que le graphe d'objets dans cet exemple est cyclique (tout fonctionne bien lorsqu'il n'est pas cyclique).
En tracant au debugger, on dirait que la phase de sérialisation se passe bien, mais que pendant la désérialisation, selon quel objet est sérialisé en premier dans le graphe, certains objets ne sont pas bien résolus (ils restent dans leur classe de transport et la méthode readresolve n'est pas appelée)
Si quelqu'un a une idee...
Mael