jerrinot/subzero

Exception while deserializing List<String>

Closed this issue · 6 comments

I am getting this exception while deserializing List element from cache

caused by: java.lang.NullPointerException
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:234) ~[?:1.8.0_101]
    at java.util.ArrayList.ensureCapacity(ArrayList.java:218) ~[?:1.8.0_101]
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:114) ~[kryo-4.0.0.jar:?]
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:40) ~[kryo-4.0.0.jar:?]
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:731) ~[kryo-4.0.0.jar:?]
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125) ~[kryo-4.0.0.jar:?]
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:540) ~[kryo-4.0.0.jar:?]
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:813) ~[kryo-4.0.0.jar:?]
    at info.jerrinot.subzero.internal.strategy.GlobalKryoStrategy.readObject(GlobalKryoStrategy.java:18) ~[subzero-core-0.3.jar:?]
    at info.jerrinot.subzero.internal.strategy.KryoStrategy.read(KryoStrategy.java:47) ~[subzero-core-0.3.jar:?]
    at info.jerrinot.subzero.Serializer.read(Serializer.java:40) ~[subzero-core-0.3.jar:?]
    at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:46) ~[hazelcast-3.7.jar:3.7]
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:172) ~[hazelcast-3.7.jar:3.7]

The class is of the format

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
class MyClass {
  private List<String> myVals;
}

I am having global serialisation with overrideJavaSerialization=true

GlobalSerializerConfig globalSerializerConfig =
        new GlobalSerializerConfig().setClassName(Serializer.class.getName())
            .setOverrideJavaSerialization(true);
    config.getSerializationConfig().setGlobalSerializerConfig(globalSerializerConfig);

versions

hazelcast 3.7
subzero-core 0.3

Hi @thekalinga,

thanks for reporting, I'll have a look!

@thekalinga

do you have a reproducer? it appears to work fine for me. NPE in ArrayList is a strong indication of a concurrency problem.

I even tried to important the lombok library and use various generated way to construct the object - but it still seems to work OK. Any hint to reproduce it is much appreciated!

After I have locally updated KryoStrategy<T> to the following, I no longer receive this exception

public abstract class KryoStrategy<T> {

  private static final int BUFFER_SIZE = getInteger("subzero.buffer.size.kb", 16) * 1024;

  private static final ThreadLocal<KryoContext> KRYOS = new ThreadLocal<KryoContext>() {
    protected KryoContext initialValue() {
      Kryo kryo = new Kryo();
      kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy())); // <-- This is the change
      OutputChunked output = new OutputChunked(BUFFER_SIZE);
      InputChunked input = new InputChunked(BUFFER_SIZE);
      return new KryoContext(kryo, input, output);
    }
  };
  // a lot more code
}

i.e attempting to use No args constructor followed by StdInstantiatorStrategy as fallback. Not sure why StdInstantiatorStrategy as default is causing the issue in my app.

The docs also talks about this Kryo object creation

@thekalinga: excellent, many thanks for the report and analysis!
I just released version 0.4 with the fix. It should be in Maven central in a few minutes.

Thanks