Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.shiro.lang.io.Serializer;
import org.apache.shiro.lang.util.ByteSource;
import org.apache.shiro.lang.util.ByteUtils;
import org.apache.shiro.lang.util.ClassUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.SubjectContext;
Expand Down Expand Up @@ -509,7 +510,12 @@ protected byte[] decrypt(byte[] encrypted) {
* @return the serialized principal collection in the form of a byte array
*/
protected byte[] serialize(PrincipalCollection principals) {
return getSerializer().serialize(principals);
ClassUtils.setAdditionalClassLoader(AbstractRememberMeManager.class.getClassLoader());
try {
return getSerializer().serialize(principals);
} finally {
ClassUtils.removeAdditionalClassLoader();
}
}

/**
Expand All @@ -520,7 +526,12 @@ protected byte[] serialize(PrincipalCollection principals) {
* @return the deserialized (reconstituted) {@code PrincipalCollection}
*/
protected PrincipalCollection deserialize(byte[] serializedIdentity) {
return getSerializer().deserialize(serializedIdentity);
ClassUtils.setAdditionalClassLoader(AbstractRememberMeManager.class.getClassLoader());
try {
return getSerializer().deserialize(serializedIdentity);
} finally {
ClassUtils.removeAdditionalClassLoader();
}
}

/**
Expand Down
55 changes: 52 additions & 3 deletions lang/src/main/java/org/apache/shiro/lang/util/ClassUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public final class ClassUtils {
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtils.class);

private static final ThreadLocal<ClassLoader> ADDITIONAL_CLASS_LOADER = new ThreadLocal<>();

/**
* SHIRO-767: add a map to mapping primitive data type
Expand Down Expand Up @@ -75,13 +76,24 @@ protected ClassLoader doGetClassLoader() throws Throwable {
/**
* @since 1.0
*/
private static final ClassLoaderAccessor CLASS_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
private static final ClassLoaderAccessor CLASS_LANG_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
@Override
protected ClassLoader doGetClassLoader() throws Throwable {
return ClassUtils.class.getClassLoader();
}
};

/**
* @since 2.0.4
*/
private static final ClassLoaderAccessor ADDITIONAL_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
@Override
protected ClassLoader doGetClassLoader() throws Throwable {
ClassLoader cl = ADDITIONAL_CLASS_LOADER.get();
return cl != null ? cl : ClassUtils.class.getClassLoader();
}
};

/**
* @since 1.0
*/
Expand Down Expand Up @@ -117,7 +129,15 @@ public static InputStream getResourceAsStream(String name) {
LOGGER.trace("Resource [" + name + "] was not found via the thread context ClassLoader. Trying the "
+ "current ClassLoader...");
}
is = CLASS_CL_ACCESSOR.getResourceStream(name);
is = CLASS_LANG_CL_ACCESSOR.getResourceStream(name);
}

if (is == null) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Resource [" + name + "] was not found via the org.apache.shiro.lang ClassLoader. Trying the "
+ "additionally set ClassLoader...");
}
is = ADDITIONAL_CL_ACCESSOR.getResourceStream(name);
}

if (is == null) {
Expand Down Expand Up @@ -157,7 +177,15 @@ public static <T> Class<T> forName(String fqcn) throws UnknownClassException {
LOGGER.trace("Unable to load class named [" + fqcn
+ "] from the thread context ClassLoader. Trying the current ClassLoader...");
}
clazz = CLASS_CL_ACCESSOR.loadClass(fqcn);
clazz = CLASS_LANG_CL_ACCESSOR.loadClass(fqcn);
}

if (clazz == null) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Unable to load class named [" + fqcn
+ "] from the org.apache.shiro.lang ClassLoader. Trying the additionally set ClassLoader...");
}
clazz = ADDITIONAL_CL_ACCESSOR.loadClass(fqcn);
}

if (clazz == null) {
Expand Down Expand Up @@ -259,6 +287,27 @@ public static List<Method> getAnnotatedMethods(final Class<?> type, final Class<
return methods;
}

/**
* Sets additional ClassLoader for {@link #getResourceAsStream(String)} and {@link #forName(String)} to use
* It is used in addition to the thread context class loader and the system class loader.

* @param classLoader class loader to use
* @since 2.0.4
*/
public static void setAdditionalClassLoader(ClassLoader classLoader) {
ADDITIONAL_CLASS_LOADER.set(classLoader);
}

/**
* Removes the additional ClassLoader set by {@link #setAdditionalClassLoader(ClassLoader)}.
* This must be called to avoid memory leaks.
*
* @since 2.0.4
*/
public static void removeAdditionalClassLoader() {
ADDITIONAL_CLASS_LOADER.remove();
}

/**
* @since 1.0
*/
Expand Down