Nov11 / kryo

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

Enums with Method definitions #37

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create an Enum A where the constant values have method definitions. Create a 
class B with a public field of type A.
2.Instantiate B and serialize it where handling of unregistered classes is 
enabled.
3.Deserialize it.

What is the expected output? What do you see instead?
The expected output is that the original output gets recovered. Instead, a null 
pointer exception is thrown (which gets re-thrown as a serialization exception.

What version of the Kryo are you using?
I tried this with 1.03 and the current head of trunk.

Please provide any additional information below.

For Enums where the constant values have method definitions, Java assigns each 
enumeration value its own inner class. For an Enum A with values "One" and 
"Two", the class of A.One would be A$1. This seems to cause trouble with Kryo. 
When registration is mandatory, Kryo will fail on serialization because A$1 has 
not been registered even though A has. But even if I register A.One and A.Two 
explicitly, this still causes trouble inside the FieldSerializer for objects 
that use this enum as a field type.

Maybe using the declaring class of an enum constant (i.e. 
A.One.getDeclaringClass()) rather than getClass() would solve the problem.

Example stack trace:
com.esotericsoftware.kryo.SerializationException: Unable to deserialize object 
of type: edu.umd.umiacs.dogma.diskgraph.serializer.test.TestClass
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:596)
    at edu.umd.umiacs.dogma.diskgraph.serializer.test.SerializerUnitTest.objectWriteRead(SerializerUnitTest.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
    at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.esotericsoftware.kryo.SerializationException: Serialization 
trace:
e (edu.umd.umiacs.dogma.diskgraph.serializer.test.TestClass)
    at com.esotericsoftware.kryo.serialize.FieldSerializer.readObjectData(FieldSerializer.java:237)
    at com.esotericsoftware.kryo.serialize.FieldSerializer.readObjectData(FieldSerializer.java:199)
    at com.esotericsoftware.kryo.Serializer.readObject(Serializer.java:61)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:592)
    ... 25 more
Caused by: java.lang.NullPointerException
    at com.esotericsoftware.kryo.serialize.EnumSerializer.readObjectData(EnumSerializer.java:24)
    at com.esotericsoftware.kryo.serialize.FieldSerializer.readObjectData(FieldSerializer.java:219)
    ... 28 more

Original issue reported on code.google.com by knowledg...@gmail.com on 28 Jan 2011 at 2:42

GoogleCodeExporter commented 9 years ago
The stacktrace shows that you have constructed an EnumSerializer using a type 
that is not an enum. I have added a better exception for this in r140.

I have added serialization of an enum using optional registration in r141. It 
doesn't match your repro steps exactly, but does show the appropriate code is 
working correctly. Further tests, not checked in, confirm your exact use case 
works correctly.

Please post sample code if possible to show the problem.

Original comment by nathan.s...@gmail.com on 28 Jan 2011 at 6:39

GoogleCodeExporter commented 9 years ago
Here is a little code snippet. I am not sure if I am doing something wrong 
here. I did not construct any serializer but used the default ones.
BTW, great library - I like it a lot.

import java.nio.ByteBuffer;
import com.esotericsoftware.kryo.Kryo;

public class KryoEnumTest {

    public static void main(String[] args)  {
        Kryo kryo = new Kryo();
        kryo.register(E.class);
        ByteBuffer b = ByteBuffer.allocate(100);
        kryo.writeObjectData(b, E.E1);
        b.rewind();
        E instance = kryo.readObjectData(b, E.class);

    }

}

enum E {
    E1 { }, //Assuming some method definitions go here - left blank for simplicity

    E2 { };
}

Original comment by knowledg...@gmail.com on 3 Feb 2011 at 5:25

GoogleCodeExporter commented 9 years ago
Ah, I see. Interested bug. Fixed in r143. Thanks!

Original comment by nathan.s...@gmail.com on 4 Feb 2011 at 2:31