gaob13 / kryo

Automatically exported from code.google.com/p/kryo
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

java.nio.BufferUnderflowException #70

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Created an Exception class and serialized the class using Kryo and wrote the 
data to a file, using Java 1.6.0_30
2. Now, reading the file to de-serialize the Exception class using Kryo, using 
Java 1.7.0_05. I am getting BufferUnderflowException.

What is the expected output? What do you see instead?
Expected to de-serialize the Exception class without getting 
BufferUnderflowException.

What version of the Kryo are you using?
I am using Kryo 1.03 version. I tried using Kryo 1.05 as well, and found the 
same issue. I do not want to use Kryo 2.x, as I need to change a lot in my 
application.

Please provide any additional information below.
The src is attached.

Original issue reported on code.google.com by batchuch...@gmail.com on 13 Jun 2012 at 6:33

GoogleCodeExporter commented 8 years ago
the write program is KryoWrite.java, and the read program is KryoRead.java

When I executed both programs on Java 1.6.0_30, I did not see any issue.

Original comment by batchuch...@gmail.com on 13 Jun 2012 at 6:36

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
If the exception classes are different between Java versions, deserialization 
will fail when using ReferenceFieldSerializer. You may also have this issue:
https://groups.google.com/group/kryo-users/browse_thread/thread/e8f0ecef53357bd6
/a07613df9901d89b

You class KryoWrite fails with:
Exception in thread "main" com.esotericsoftware.kryo.SerializationException: 
Unable to serialize object of type: kryo.HttpResult
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:524)
    at com.esotericsoftware.kryo.ObjectBuffer.writeObject(ObjectBuffer.java:159)
    at kryo.KryoWrite.main(KryoWrite.java:25)
Caused by: com.esotericsoftware.kryo.SerializationException: Serialization 
trace:
suppressedExceptions (java.lang.Exception)
m_result (kryo.HttpResult)
    at com.esotericsoftware.kryo.serialize.FieldSerializer.writeObjectData(FieldSerializer.java:191)
    at com.esotericsoftware.kryo.serialize.ReferenceFieldSerializer.writeObjectData(ReferenceFieldSerializer.java:52)
    at com.esotericsoftware.kryo.serialize.FieldSerializer.writeObjectData(FieldSerializer.java:175)
    at com.esotericsoftware.kryo.serialize.ReferenceFieldSerializer.writeObjectData(ReferenceFieldSerializer.java:52)
    at com.esotericsoftware.kryo.Serializer.writeObject(Serializer.java:43)
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:520)
    ... 2 more
Caused by: java.lang.IllegalArgumentException: Class is not registered: 
java.util.Collections$UnmodifiableRandomAccessList
    at com.esotericsoftware.kryo.Kryo.getRegisteredClass(Kryo.java:319)
    at com.esotericsoftware.kryo.Kryo.writeClass(Kryo.java:374)
    at com.esotericsoftware.kryo.serialize.FieldSerializer.writeObjectData(FieldSerializer.java:173)
    ... 7 more

Original comment by nathan.s...@gmail.com on 14 Jun 2012 at 10:04

GoogleCodeExporter commented 8 years ago
Thanks for the response Nathan.

KryoWrite gives the exception 
Class is not registered: java.util.Collections$UnmodifiableRandomAccessList, 
when the java version used is 1.7. KryoWrite does not give any exception when 
it is executed on java 1.6.

Instead of using ReferenceFieldSerializer, I used FieldSerializer for 
registering the FXServletException class, and I am still getting the same 
issue, even after initializing the cause to null.

    public FXServletException()
    {
        super();
        initCause(null); 
    }

Please verify the attached src.

Original comment by batchuch...@gmail.com on 15 Jun 2012 at 3:05

Attachments:

GoogleCodeExporter commented 8 years ago
Java 1.7 has a field that uses UnmodifiableRandomAccessList. Java 1.6 doesn't. 
This can't be serialized automatically. FieldSerializer accesses a class' 
fields directly. If you don't own the class, you are serializing a private API 
that is subject to change, which will break your serialization. Better to write 
a serializer that can handle the exception using only the public API.

Exception does not have a setMessage method, so likely you'll have to use an 
application specific exception class that does have a setMessage method. 
Because of this, the serializer is app specific and doesn't belong in Kryo.

You might consider converting the exception to string and sending that.

Here is a little code that you might use to write the data. You'll have to 
write the code to read the data:

Exception object...
output.writeString(object.getMessage());
kryo.writeClassAndObject(output, object.getCause());
StackTraceElement[] stackTraces = object.getStackTrace();
output.writeInt(stackTraces.length, true);
for (int i = 0, n = stackTraces.length; i < n; i++) {
    StackTraceElement stackTrace = stackTraces[i];
    output.writeString(stackTrace.getClassName());
    output.writeString(stackTrace.getMethodName());
    output.writeString(stackTrace.getFileName());
    output.writeInt(stackTrace.getLineNumber() + 1, true);
}

Original comment by nathan.s...@gmail.com on 15 Jun 2012 at 10:11