diff --git a/src/main/java/org/crazycake/shiro/serializer/MultiClassLoaderObjectInputStream.java b/src/main/java/org/crazycake/shiro/serializer/MultiClassLoaderObjectInputStream.java new file mode 100644 index 000000000..3ab2c069d --- /dev/null +++ b/src/main/java/org/crazycake/shiro/serializer/MultiClassLoaderObjectInputStream.java @@ -0,0 +1,52 @@ +package org.crazycake.shiro.serializer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MultiClassLoaderObjectInputStream extends ObjectInputStream { + private static Logger log = LoggerFactory.getLogger(MultiClassLoaderObjectInputStream.class); + + MultiClassLoaderObjectInputStream(InputStream str) throws IOException { + super(str); + } + + @Override + protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { + String name = desc.getName(); + //log.debug("resolveClass:"+name); + + try { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + return Class.forName(name, false, cl); + } catch (Throwable ex) { + log.debug(ex.getMessage()); + // Cannot access thread context ClassLoader - falling back... + } + + try { + // No thread context class loader -> use class loader of this class. + ClassLoader cl = MultiClassLoaderObjectInputStream.class.getClassLoader(); + return Class.forName(name, false, cl); + } catch (Throwable ex) { + log.debug(ex.getMessage()); + // Cannot access thread context ClassLoader - falling back... + } + + // getClassLoader() returning null indicates the bootstrap ClassLoader + try { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + return Class.forName(name, false, cl); + } catch (Throwable ex) { + log.debug(ex.getMessage()); + // Cannot access system ClassLoader - oh well, maybe the caller can live with null... + } + + return super.resolveClass(desc); + } + +} diff --git a/src/main/java/org/crazycake/shiro/serializer/ObjectSerializer.java b/src/main/java/org/crazycake/shiro/serializer/ObjectSerializer.java index 67b19557d..d5ccffe04 100644 --- a/src/main/java/org/crazycake/shiro/serializer/ObjectSerializer.java +++ b/src/main/java/org/crazycake/shiro/serializer/ObjectSerializer.java @@ -1,13 +1,18 @@ package org.crazycake.shiro.serializer; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + import org.crazycake.shiro.exception.SerializationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; - public class ObjectSerializer implements RedisSerializer { - private static Logger logger = LoggerFactory.getLogger(ObjectSerializer.class); + private static Logger log = LoggerFactory.getLogger(ObjectSerializer.class); public static final int BYTE_ARRAY_OUTPUT_STREAM_SIZE = 128; @@ -45,7 +50,7 @@ public Object deserialize(byte[] bytes) throws SerializationException { try { ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes); - ObjectInputStream objectInputStream = new ObjectInputStream(byteStream); + ObjectInputStream objectInputStream = new MultiClassLoaderObjectInputStream(byteStream); result = objectInputStream.readObject(); } catch (IOException e) { throw new SerializationException("deserialize error", e);