views:

2248

answers:

2

I'm trying to serialize and deserialize an array list with a object inside:

HairBirt param = new HairBirt();
param.setName("name");
param.setValue(2.3f);

HairBirt param2 = new HairBirt();
param2.setName("name2");
param2.setValue(2.4f);

ArrayList<HairBirt> list = new ArrayList<HairBirt>();

list.add(param);

list.add(param2);

ByteArrayOutputStream bos = null;
try {
 bos = new ByteArrayOutputStream();
 ObjectOutputStream obj_out = new ObjectOutputStream(bos);
 obj_out.writeObject(list);
} catch (IOException e) {
 e.printStackTrace();
}

String encoded = bos.toString();
try {
 encoded = URLEncoder.encode(encoded, "UTF-8");
} catch (UnsupportedEncodingException e1) {
 e1.printStackTrace();
}
System.out.print("The serialized output is: " + encoded); 

//DECODE

ArrayList<HairBirt> paramDecoded;

String myParam = null;
try {
 myParam = URLDecoder.decode(encoded, "UTF-8");
} catch (UnsupportedEncodingException e1) {
 e1.printStackTrace();
}
System.out.println("Got parameters");
ByteArrayInputStream bis = new ByteArrayInputStream(myParam.getBytes());

try {
 ObjectInputStream obj_in = new ObjectInputStream(bis);

 paramDecoded = (ArrayList<HairBirt>) obj_in.readObject();
} catch (IOException e) {
 e.printStackTrace();
} catch (ClassNotFoundException e) {
 e.printStackTrace();
}

The HairList object is also a serializable object.

This code execution is returning the following error:

java.io.InvalidClassException: java.util.ArrayList; local class incompatible: stream classdesc serialVersionUID = 8664875232659988799, local class serialVersionUID = 8683452581122892189

in line paramDecoded = (ArrayList<HairBirt>) obj_in.readObject();

I don't know what i'm doing wrong. Can you give a tip?

Update:

Resolved: Just used a native array of HairBirt instead of a ArrayList and it works:

HairBirt[] list = new HairBirt[x];

instead of

ArrayList<HairBirt> list = new ArrayList<HairBirt>();

Thank you all for your help.

+4  A: 

Don't use ByteArrayOutputStream.toString() - instead, use toByteArray() and base64-encode that binary data to convert it into a string without losing information.

I strongly suspect that's the main problem - that you were losing the data after serialization. You should probably also close or at least flush the ObjectOutputStream. I don't know offhand whether that actually does anything in this case, but it would seem to be a good idea.

I don't believe there's any base64 support directly in Java (in a public class, anyway) but there are various 3rd party libraries you can use, such as the one in the Apache Commons Codec library.

Jon Skeet
Yup, that's the problem, but i really need to use String on that move... This is not the real problem, it's a simplification of it.
sakana
What do you mean by 'on that move'? You will *have* to convert the BAOS to a string in a lossless way if you want to be able to deserialize it. Whether that's with base64 or not is a different matter, but I think it's a good way of doing it.
Jon Skeet
@sakana: base64 is a string format with a limited character set.
R. Bemrose
What do you mean by 'on that move'? I mean that I really need to use a String between the Encode and Decode code. It's the only parameter type i'm able to use.
sakana
That's fine - that's why you use base64 to convert from byte[] to String without losing information.
Jon Skeet
A: 

Have you tried overriding this behavior by declaring your own serialVersionUID in your custom class?

Do you have a specific reason for doing the extra step of serializing through a string? Normally you would just deserialize through an ObjectOutputStream.

Steve B.
Declaring a serialVersionUID doesn't help here.
Michael Myers