Using Arrays.asList() created lists causes NPE when deserializing
Closed this issue · 1 comments
When sending a message with a List<> property that was created with Arrays.asList a null pointer exception is thrown while deserializing. I've add a test to reproduce this problem.
ERROR c.b.c.c.c.a.i.s.ArrayListSerializationTest$TestActor - swallowing exception during message send
com.esotericsoftware.kryo.KryoException: java.lang.NullPointerException
Serialization trace:
strings (**.ArrayListSerializationTest$TestMessage)
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:144) ~[kryo-3.0.3.jar:na]
at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:551) ~[kryo-3.0.3.jar:na]
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:790) ~[kryo-3.0.3.jar:na]
at com.romix.akka.serialization.kryo.KryoBasedSerializer.fromBinary(KryoSerializer.scala:483) ~[akka-kryo-serialization_2.11-0.4.1.jar:na]
at com.romix.akka.serialization.kryo.KryoSerializer.fromBinary(KryoSerializer.scala:339) ~[akka-kryo-serialization_2.11-0.4.1.jar:na]
at akka.serialization.Serialization$$anonfun$deserialize$3.apply(Serialization.scala:142) ~[akka-actor_2.11-2.4.2.jar:na]
at scala.util.Try$.apply(Try.scala:192) ~[scala-library-2.11.7.jar:na]
at akka.serialization.Serialization.deserialize(Serialization.scala:142) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.dungeon.Dispatch$class.sendMessage(Dispatch.scala:128) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.ActorCell.sendMessage(ActorCell.scala:374) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.UnstartedCell$$anonfun$replaceWith$1.apply$mcV$sp(RepointableActorRef.scala:215) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.UnstartedCell$$anonfun$replaceWith$1.apply(RepointableActorRef.scala:197) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.UnstartedCell$$anonfun$replaceWith$1.apply(RepointableActorRef.scala:197) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.UnstartedCell.locked(RepointableActorRef.scala:285) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.UnstartedCell.replaceWith(RepointableActorRef.scala:196) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.RepointableActorRef.point(RepointableActorRef.scala:106) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.ActorCell.handleSupervise(ActorCell.scala:624) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.ActorCell.supervise(ActorCell.scala:616) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:468) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.actor.ActorCell.systemInvoke(ActorCell.scala:483) ~[akka-actor_2.11-2.4.2.jar:na]
at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:282) [akka-actor_2.11-2.4.2.jar:na]
at akka.dispatch.Mailbox.run(Mailbox.scala:223) [akka-actor_2.11-2.4.2.jar:na]
at akka.dispatch.Mailbox.exec(Mailbox.scala:234) [akka-actor_2.11-2.4.2.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.7.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.7.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.7.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.7.jar:na]
Caused by: java.lang.NullPointerException: null
at java.util.Arrays$ArrayList.size(Arrays.java:3818) ~[na:1.8.0_91]
at java.util.AbstractList.add(AbstractList.java:108) ~[na:1.8.0_91]
at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:127) ~[kryo-3.0.3.jar:na]
at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:40) ~[kryo-3.0.3.jar:na]
at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:708) ~[kryo-3.0.3.jar:na]
at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125) ~[kryo-3.0.3.jar:na]
... 26 common frames omitted
Reproduction test:
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.testkit.JavaTestKit;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
/**
* Created by bob on 6/27/16.
*/
public class ArrayListSerializationTest {
private static ActorSystem system;
@BeforeClass
public static void setup() {
system = ActorSystem.create("myAkkaCluster");
}
@Test
public void asList(){
TestMessage testMessage = new TestMessage(Arrays.asList("test1", "test2"));
runTest(testMessage);
}
@Test
public void arrayListConstructor(){
List<String> strings = new ArrayList<>();
strings.add("test1");
strings.add("test2");
TestMessage testMessage = new TestMessage(strings);
runTest(testMessage);
}
private void runTest(TestMessage testMessage) {
new JavaTestKit(system) {{
ActorRef actorRef = system.actorOf(Props.create(TestActor.class));
actorRef.tell(testMessage, getRef());
String s = expectMsgClass(String.class);
assertThat(s, is("test1"));
String s1 = expectMsgClass(String.class);
assertThat(s1, is("test2"));
}};
}
public static class TestActor extends UntypedActor {
@Override
public void onReceive(Object message) throws Exception {
TestMessage testMessage = (TestMessage) message;
for (String s : testMessage.getStrings()) {
getSender().tell(s, getSelf());
}
}
}
public static class TestMessage implements Serializable{
public List<String> getStrings() {
return strings;
}
private final List<String> strings;
public TestMessage(List<String> strings) {
this.strings = strings;
}
}
}
Currently fixed this by adding a custom kryo initializer (https://github.com/romix/akka-kryo-serialization#how-to-create-a-custom-initializer-for-kryo) and adding the serializers available in https://github.com/magro/kryo-serializers.