in api/src/main/java/com/google/appengine/api/memcache/MemcacheSerialization.java [140:226]
public static Object deserialize(byte[] value, int flags)
throws ClassNotFoundException, IOException {
Flag flagval = Flag.fromInt(flags);
switch (flagval) {
case BYTES:
return value;
case BOOLEAN:
if (value.length != 1) {
throw new InvalidValueException("Cannot deserialize Boolean: bad length", null);
}
switch (value[0]) {
case TRUE_VALUE:
return Boolean.TRUE;
case FALSE_VALUE:
return Boolean.FALSE;
}
throw new InvalidValueException("Cannot deserialize Boolean: bad contents", null);
case BYTE:
case SHORT:
case INTEGER:
case LONG:
long val = new BigInteger(new String(value, US_ASCII)).longValue();
switch (flagval) {
case BYTE:
return (byte) val;
case SHORT:
return (short) val;
case INTEGER:
return (int) val;
case LONG:
return val;
default:
throw new InvalidValueException("Cannot deserialize number: bad contents", null);
}
case UTF8:
return new String(value, UTF_8);
case OBJECT:
if (value.length == 0) {
return null;
}
ByteArrayInputStream baos = new ByteArrayInputStream(value);
ObjectInputStream objIn = null;
if (UseThreadContextClassLoaderHolder.INSTANCE) {
objIn = new ObjectInputStream(baos) {
// If there are more user-defined class loaders, the default class loader by
// ObjectInputStream might not be enough. For example, in Jetty, there are two
// user-defined class loaders, i.e. startJarLoader (the parent) and WebAppClassLoader
// (the child). startJarLoader normally loads this class, and WebAppClassLoader
// normally loads application classes. When an application object is serialized,
// startJarLoader will load this class and WebAppClassLoader will the application
// class. However, when the application object is deserialized, startJarLoader will
// be unfortunately used according to the logic of ObjectInputStream. This will cause
// ClassNotFoundException because startJarLoader could not find the application class.
@Override
protected Class<?> resolveClass(ObjectStreamClass objectStreamClass)
throws ClassNotFoundException, IOException {
ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
if (threadClassLoader == null) {
return super.resolveClass(objectStreamClass);
}
try {
return Class.forName(objectStreamClass.getName(), false, threadClassLoader);
} catch (ClassNotFoundException ex) {
return super.resolveClass(objectStreamClass);
}
}
};
} else {
objIn = new ObjectInputStream(baos);
}
Object response = objIn.readObject();
objIn.close();
return response;
default:
assert false;
}
return null;
}