Reputation: 1810
I am running into a strange issue with Kryo. I can serialize a generic class (such as List) just fine. I can even serialize a generic class that has no generic fields. However, if I serialize a generic class with generic fields it is failing. An example should show the problem.
Here is the class I want to serialize:
import java.util.ArrayList;
public class GenericClass<T>
{
private final ArrayList<T> list;
public GenericClass()
{
list = new ArrayList<T>();
}
}
And here is the code that tests it. The second call to writeClassAndObject() throws the exception. The ArrayList write is simply to prove that works just fine.
public void testWhySoDumb()
{
File s = Environment.getExternalStorageDirectory();
String dir = s.getAbsolutePath() + "/pagetest";
String fileLocation = dir + "/filetest";
new File(dir).mkdirs();
Output output = null;
Kryo kryo = new Kryo();
kryo.setAsmEnabled(true);
kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
// Test writing ArrayList (this works)
List<Integer> arrayList = new ArrayList<Integer>();
try
{
output = new Output(new FileOutputStream(fileLocation));
kryo.writeClassAndObject(output, arrayList);
}
catch (Exception e)
{
System.out.println(e.getMessage()); // No problem here
}
finally
{
if (output != null)
{
output.close();
}
}
// Test writing GenericClass (this does NOT work)
GenericClass<Integer> genericClass = new GenericClass<Integer>();
try
{
output = new Output(new FileOutputStream(fileLocation));
kryo.writeClassAndObject(output, genericClass); // throws exception!!! <------
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
finally
{
if (output != null)
{
output.close();
}
}
}
And I am getting the following exception:
com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: type cannot be null.
Serialization trace:
list (com.myapp.page.history.GenericClass)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:82)
at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.write(CompatibleFieldSerializer.java:42)
at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:624)
at com.myapp.page.history.TestGenerics.testWhySoDumb(TestGenerics.java:57)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
Caused by: java.lang.IllegalArgumentException: type cannot be null.
at com.esotericsoftware.kryo.Kryo.isFinal(Kryo.java:1135)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.setGenerics(CollectionSerializer.java:60)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:60)
... 15 more
What is very odd is that if I change the type of "list" from "ArrayList" to just "T", it works fine. Kryo doesn't seem to know what to do with the ArrayList field. I am using Kryo version 3.0.0.
Thanks!
Upvotes: 2
Views: 1778
Reputation: 1131
I don't know if you still have this problem. I would probably think that this is a version problem or something specific to Android because this should work with the current version.
Kryo kryo = new Kryo();
Output output = new Output(new FileOutputStream("fileLocation"));
kryo.writeObject(output, new GenericClass<String>());
Upvotes: 1