Skip to content

Instantly share code, notes, and snippets.

@magro
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magro/8746529 to your computer and use it in GitHub Desktop.
Save magro/8746529 to your computer and use it in GitHub Desktop.
Test for deserialization issue with kryo and class extending HashMap
package de.javakaffee.web.msm.serializer.kryo;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.testng.annotations.Test;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.serialize.MapSerializer;
import de.javakaffee.web.msm.MemcachedBackupSession;
public class ValueObjectFix {
public static class ValueObjectImplSerializerRegistration implements KryoCustomization {
@Override
public void customize(final Kryo kryo) {
kryo.register(ValueObjectImpl.class, new MapSerializer(kryo) {
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public <T> T newInstance(final Kryo kryo, final Class<T> type) {
return (T) new ValueObjectImpl();
}
});
}
}
@Test
public void testDeserializationError() {
final KryoTranscoderFactory transcoderFactory = new KryoTranscoderFactory();
transcoderFactory.setCustomConverterClassNames(new String[] {ValueObjectImplSerializerRegistration.class.getName()});
final KryoTranscoder transcoder = transcoderFactory.createTranscoder(Thread.currentThread().getContextClassLoader());
final ValueObjectImpl<String, String> obj = new ValueObjectImpl<String, String>();
obj.put("foo", "bar");
// serialize one instance
final MemcachedBackupSession memcachedBackupSession = new MemcachedBackupSession();
final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
attributes.put("obj", obj);
final byte[] data = transcoder.serializeAttributes(memcachedBackupSession, attributes);
final Map<String, Object> deserializeAttributes = transcoder.deserializeAttributes(data);
final Object actual = deserializeAttributes.get("obj");
assertNotNull(actual);
assertEquals(actual, obj);
}
@SuppressWarnings("serial")
static class ValueObjectImpl<K, V> extends HashMap<K, V> {
@Override
public V get(final Object key) {
return key != null ? super.get(key): null;
}
@Override
public V put(final K key, final V value) {
return key != null ? super.put(key, value) : null;
}
}
}
package de.javakaffee.web.msm.serializer.kryo;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.testng.annotations.Test;
import com.esotericsoftware.kryo.serialize.MapSerializer;
import de.javakaffee.web.msm.MemcachedBackupSession;
public class ValueObjectTest {
@Test
public void testDeserializationError() {
final KryoTranscoder transcoder = new KryoTranscoderFactory().createTranscoder(Thread.currentThread().getContextClassLoader());
final ValueObjectImpl<String, String> obj = new ValueObjectImpl<String, String>();
obj.put("foo", "bar");
// serialize one instance
final MemcachedBackupSession memcachedBackupSession = new MemcachedBackupSession();
final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
attributes.put("obj", obj);
final byte[] data = transcoder.serializeAttributes(memcachedBackupSession, attributes);
final Map<String, Object> deserializeAttributes = transcoder.deserializeAttributes(data);
final Object actual = deserializeAttributes.get("obj");
assertNotNull(actual);
assertEquals(actual, obj);
}
@SuppressWarnings("serial")
public static class ValueObjectImpl<K, V> extends HashMap<K, V> {
@Override
public V get(final Object key) {
return key != null ? super.get(key): null;
}
@Override
public V put(final K key, final V value) {
return key != null ? super.put(key, value) : null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment