Was getting this error when I was trying to set a custom object:
memCachedClient.set(“customerObj”, 3600, new Customer(“John”, “Doe”));
2026-03-01 15:47:21.339 WARN net.spy.memcached.transcoders.SerializingTranscoder: Caught CNFE decoding 150 bytes of data 2014-03-01T15:47:21.340137+00:00 app[web.1]: java.lang.ClassNotFoundException: com.example.model.Customer 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.net.URLClassLoader$1.run(URLClassLoader.java:217) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.security.AccessController.doPrivileged(Native Method) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.lang.ClassLoader.loadClass(ClassLoader.java:321) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.lang.ClassLoader.loadClass(ClassLoader.java:266) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.lang.Class.forName0(Native Method) 2014-03-01T15:47:21.340436+00:00 app[web.1]: at java.lang.Class.forName(Class.java:266)
This occurs because the memcached client is loaded using a classloader and the serialized object class is loaded using another classloader. To fix this you must pass to the memcahed client connector factory a custom transcoder.
MemcachedClient mc = new MemcachedClient( new ConnectionFactoryBuilder() .setTranscoder(new CustomSerializingTranscoder()) //Add this line .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY) .setAuthDescriptor(ad).build(),
package com.example.cache;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import net.spy.memcached.transcoders.SerializingTranscoder;
public class CustomSerializingTranscoder extends SerializingTranscoder{
@Override
protected Object deserialize(byte[] bytes) {
final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
ObjectInputStream in = null;
try {
ByteArrayInputStream bs = new ByteArrayInputStream(bytes);
in = new ObjectInputStream(bs) {
@Override
protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
try {
return currentClassLoader.loadClass(objectStreamClass.getName());
} catch (Exception e) {
return super.resolveClass(objectStreamClass);
}
}
};
return in.readObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
closeStream(in);
}
}
private static void closeStream(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}