Deserializable exception : local class is not compatible cause of serialVersionID - java

Here is my code:
MyOwnObject deserializedObject = null;
try{
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject.getBytes());
ObjectInputStream ois= new ObjectInputStream(bis);
deserializedObject = (MyOwnObject)ois.readObject();
ois.close();
}catch(Exception e){
e.printStackTrace();
}
someMapper.insert(deserializedObject);
PS: serializedObject is a string which i get from serialization process before, and it's working well i think.
The code throws an exception:
local class incompatible: stream classdesc serialVersionUID = 1360826667802527544, local class serialVersionUID = 1360826667806852920
And in the stacktrace there's something about the type Integer of some attribute in my object.
UPDATE:
serializeObject is a string,from this code:
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(myObject);
so.flush();
serializedObject = bo.toString();
}catch (Exception e) {
System.out.println(e);
}
ANSWER:
//Serialization from object to string
String serializedObject="";
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
serializedObject = new String(Base64.encode(baos.toByteArray()));
oos.close();
}catch(Exception e){
e.printStackTrace();
}
//Deserialization from string to object
MyOwnObject deserializedObject = null;
try{
byte[] bytes = Base64.decode(serializedObject.getBytes());
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
deserializedObject = (MyOwnObject)ois.readObject();
ois.close();
}catch(Exception e){
e.printStackTrace();
}
From here,i can use deserializedObject as an object,and it worked well!

The problem is in how you create your serializedObject.
You use a ByteArrayOutputStream. You shouldn't call toString() on it. Instead call its toByteArray() method to get the underlying data as a byte array, and you can use that to create your ByteArrayInputStream and it will work.
Example:
// Serialization
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(myObject);
so.flush();
byte[] serializedObject = bo.toByteArray();
// Deserialization
MyOwnObject deserializedObject = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject);
ObjectInputStream ois = new ObjectInputStream(bis);
deserializedObject = (MyOwnObject)ois.readObject();
ois.close();
} catch (Exception e){
e.printStackTrace();
}
A serialized object is a sequence of bytes (a byte array) and not a sequence of characters. You cannot create a String from the bytes of a serialized object, because it may not contain valid unicode codepoints for example.
If you really need to represent the serialized object as a String, try representing the byte array in hex string or use base64 encoding.

besides base64, you can use hex string also!i always use it when i encounter a similar problems!

Related

Getting Object back from an ObjectOutputStream

I have created an ObjectOutputStream
ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream());
stream.writeObject(myObject);
but how do I now convert this back into an Object, or even a ByteArray?
I've tried getting an ObjectInputStream like this
ByteArrayOutputStream outputStream = (ByteArrayOutputStream) myProcess.getOutputStream();
final ObjectInputStream objectInputStream = new ObjectInputStream(
new ByteArrayInputStream(outputStream.toByteArray()));
however I get a compile error saying it can't cast the ObjectOutputStream to a ByteArrayOutputStream; yet there seem to be no methods on the ObjectOutputStream to get the data back?
Here how you do it
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(baos);
stream.writeObject(myObject);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream inputStream = new ObjectInputStream(bais);
Object o = inputStream.readObject();

reading bytearray upto specified location

Let me allow to describe my problem:
I have created socket server in python and client in java, from java I am sending multiple objects to server by using :
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteArrayOutputStream append = new ByteArrayOutputStream();
ObjectOutput out = null;
byte finalarr[]=null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(object);
out.flush();
byte[] objByte = bos.toByteArray();
bos.close();
out.close();
append.write(objByte.length);
append.write(objByte);
bos = new ByteArrayOutputStream();
out = new ObjectOutputStream(bos);
out.writeObject(value);
out.flush();
append.write(bos.toByteArray());
finalarr = append.toByteArray( );
os = sChannel.socket().getOutputStream();
oos = new ObjectOutputStream(os);
oos.write(finalarr);
} finally {
try {
bos.close();
} catch (IOException ex) {
}
}
Now, finalarr contains byte length of object then actual byte[] of object and then byte[] of value. Now in python after receiving this First I want to read length of byte which is written in first position of finalarr then whatever length I get I want to read received array upto that length so that I will get object separately then the remaining part separately.
In python I have done upto this:
total_data=b''
while True:
data = self.clientsocket.recv(1024)
if not data: break
total_data += data
In total_data I am getting entire bytearray, but I don't know how I can read it so that I can get two objects separately as explained.

Java GZIPOutputStream: Corrupted gzip with this method

does someone have an idea why this code to create a gzipped string is not working? CLI gzip on a Mac can't open the resulting file: "Not in gz format".
Please note: I need the string, not the file. Creating the gzipped file directly works, so does writing the JSON without zipping it.
The file writing in this example is just for testing purposes.
public someMethod {
String gzippedString = this.gzippedString(finalJSONObject.toJSONString());
OutputStream outputStream = new FileOutputStream(new File(this.jsonOutputPath + "/myfile.gz"));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
writer.append(gzippedString);
writer.close();
}
private String gzippedString(String inputString) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
gzipOutputStream.write(inputString.getBytes());
gzipOutputStream.close();
outputStream.close();
String gzippedString = outputStream.toString();
return gzippedString;
}
EDIT:
chrylis showed me the way:
public void someMethod() {
byte[] byteArray = this.gzippedByteArray(finalJSONObject.toJSONString());
FileOutputStream out = new FileOutputStream(this.jsonOutputPath + "/myfile.gz");
out.write(byteArray);
out.close();
}
private byte[] gzippedByteArray(String inputString) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
gzipOutputStream.write(inputString.getBytes());
gzipOutputStream.close();
outputStream.close();
byte[] gzippedByteArray = outputStream.toByteArray();
return gzippedByteArray;
}
This results in a working gzipped JSON.
Thanks a lot!
You're round-tripping binary data through a String, which has a character encoding and other such mangling. Use the byte[] directly instead.

Pass serilaized object as parameter to HTTPServer in Java

How can I pass a serilaized object as a param in a GET request to my HTTPServer? Please let me know as I have been unable to find a way to do the same.
You can try something like this
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.close();
String prm = URLEncoder.encode(new String(bos.toByteArray(), "ISO-8859-1"), "ISO-8859-1");
On the server side:
servletRequest.setCharacterEncoding("ISO-8859-1");
String s = servletRequeset.getParameter("obj");
byte[] bytes = s.getBytes("ISO-8859-1");
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
Object obj = ois.readObject();
It's also possible to use Base64 instead of URL Encoding, the main idea is to pass serialized bytes in URL

How to write part of header using BufferedOutputStream?

I want to write a ~20000 bytes to a replace the same number of bytes of file at offset OFFSET using a BufferedOutputStream. I try to do this with the following code:
headerOffset = 12000;
headerSize = 20000;
byte[] ba = new byte[20];
FileOutputStream os;
BufferedOutputStream bos;
try {
os = new FileOutputStream('file.dat');
bos = new BufferedOutputStream(os);
bos.write(ba, headerOffset, headerSize);
os.flush();
} catch (IOException e) { e.printStackTrace(); }
However, this results in the 'file.dat' being overwritten by the contents of ba overwriting the entire file and leaving it only as big as ba. What am I doing wrong?

Categories