Was getting this error when I was trying to set a custom object:
memCachedClient.set(“customerObj”, 3600, new Customer(“John”, “Doe”));
2014-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(); } } } }