Serialize/Deserialze java.util.Arrays.ArrayList

2,711 views
Skip to first unread message

Cristiano Costantini

unread,
Jun 27, 2013, 4:14:39 PM6/27/13
to kryo-...@googlegroups.com
Hello All,
I'm trying to use Kryo to serialize data from an existing application.
I have some problems as this data has java.util.List which may have been created with Arrays.asList(T...a), and it does return a java.util.Arrays.ArrayList (note it is not  java.util.ArrayList) and it does not work using the FieldSerializer...

How can I manage these classes with Kryo?
Can I force Kryo to use  java.util.ArrayList instead of  java.util.Arrays.ArrayList in some way?

Thank you for your support!
Cristiano


PS: Here a simple JUnit test that capture the essence of my problem:

public class TestKryoArrays {
  public static class MyData {
    public List<String> value;
  }

  @Test
  public void testMydata() {
    MyData original = new MyData();
    original.value = Arrays.asList("one", "two", "three");

    Kryo kryo = new Kryo();

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Output output = new Output(bos);

    kryo.writeObject(output, original);
    output.close();

    byte[] outBytes = bos.toByteArray();

    ByteArrayInputStream bis = new ByteArrayInputStream(outBytes);
    Input input = new Input(bis);
    MyData processed = kryo.readObject(input, MyData.class);  // throw KryoException!!! see below
    input.close();

    assertEquals(3, processed.value.size());
    assertEquals(original.value.get(0), processed.value.get(0));
    assertEquals(original.value.get(1), processed.value.get(1));
    assertEquals(original.value.get(2), processed.value.get(2));
  }
}


==> 

com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): java.util.Arrays$ArrayList
Serialization trace:
value (com.thalesgroup.it.aocc.camel.TestKryoArrays$MyData)
at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1050)
at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1062)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.create(CollectionSerializer.java:82)
...

Nate

unread,
Jun 28, 2013, 3:29:36 AM6/28/13
to kryo-...@googlegroups.com
There is this:
https://github.com/magro/kryo-serializers/blob/master/src/main/java/de/javakaffee/kryoserializers/ArraysAsListSerializer.java
It accesses a private API though, so may not run with all class libraries (which is why it isn't in Kryo).

If you don't care that you get an ArrayList, you can do this:
kryo.register(Arrays.asList( "" ).getClass(), yourSerializer);

-Nate


--
You received this message because you are subscribed to the "kryo-users" group.
http://groups.google.com/group/kryo-users
---
You received this message because you are subscribed to the Google Groups "kryo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kryo-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Cristiano Costantini

unread,
Jun 28, 2013, 3:46:28 AM6/28/13
to kryo-...@googlegroups.com
Hi Nate,
thank you!

For me the second options would be great!
as I'm not used to write Kryo serializers, what would you recommend me to do to make one that reuse a simple java.util.ArrayList?

I would start writing something inspired from the link you have sent but maybe there is a more simple solution reusing a FieldSerializer and forcing it to create a ArrayList instead of the Arrays.ArrayList

Thanks again,

Cristiano

Nate

unread,
Jun 28, 2013, 4:24:58 AM6/28/13
to kryo-...@googlegroups.com
Try this:

List list = Arrays.asList("1", "two");


Kryo kryo = new Kryo();
kryo.register(Arrays.asList().getClass(), new CollectionSerializer() {
    protected Collection create (Kryo kryo, Input input, Class<Collection> type) {
        return new ArrayList();
    }
});

System.out.println(list);
Output output = new Output(1024);
kryo.writeClassAndObject(output, list);
output.close();

Input input = new Input(output.getBuffer(), 0, output.total());
Object list2 = kryo.readClassAndObject(input);
System.out.println(list2);
Reply all
Reply to author
Forward
0 new messages