
clime.messadmin.providers.lifecycle.KnownThreadLocalsCleaner Maven / Gradle / Ivy
The newest version!
/**
*
*/
package clime.messadmin.providers.lifecycle;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import clime.messadmin.providers.spi.RequestExceptionProvider;
import clime.messadmin.providers.spi.RequestLifeCycleProvider;
/**
* Takes care of clean (some of) the ThreadLocals
* thereby avoiding (well, trying to avoid)
* OOM (java.lang.OutOfMemoryError) on hot restart...
*
* @see Memory leaks where the classloader cannot be garbage collected
* @author Cédrik LIME
* @since 4.1
*/
public class KnownThreadLocalsCleaner implements RequestLifeCycleProvider, RequestExceptionProvider {
/* From ProviderUtils:
* "Providers are cached, keyed by its Interface, and by a ClassLoader.
* This enables different WebApps (different ClassLoaders) to have their own set of plugins (same Interface)."
*
* Thus we have a copy of plugins per webapp. Which means the ClassLoader is an invariant for each
* instance of this class.
*/
private Method log4jNDCRemoveMethod;
private Method log4jMDCContextMethod;
private Method logBackMDCClearMethod;
/**
*
*/
public KnownThreadLocalsCleaner() {
super();
final ClassLoader thisClassLoader = Thread.currentThread().getContextClassLoader();//this.getClass().getClassLoader();
// Apache Logging Log4J 1.x
// org.apache.log4j.NDC.remove();
try {
Class log4jNdcClass = thisClassLoader.loadClass("org.apache.log4j.NDC");//$NON-NLS-1$
log4jNDCRemoveMethod = log4jNdcClass.getMethod("remove", null);//$NON-NLS-1$
} catch (Throwable e) {
// ignore
}
// org.apache.log4j.MDC.getContext().clear();
try {
Class log4jMdcClass = thisClassLoader.loadClass("org.apache.log4j.MDC");//$NON-NLS-1$
log4jMDCContextMethod = log4jMdcClass.getMethod("getContext", null);//$NON-NLS-1$
} catch (Throwable e) {
// ignore
}
// LOGBack
// ch.qos.logback.classic.MDC.clear();
try {
Class logBackMdcClass = thisClassLoader.loadClass("ch.qos.logback.classic.MDC");//$NON-NLS-1$
logBackMDCClearMethod = logBackMdcClass.getMethod("clear", null);//$NON-NLS-1$
} catch (Throwable e) {
// ignore
}
}
/* (non-Javadoc)
* @see clime.messadmin.providers.spi.BaseProvider#getPriority()
*/
public int getPriority() {
return Integer.MAX_VALUE;
}
/* (non-Javadoc)
* @see clime.messadmin.providers.spi.RequestLifeCycleProvider#requestInitialized(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext)
*/
public void requestInitialized(HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext) {
// do nothing
}
/* (non-Javadoc)
* @see clime.messadmin.providers.spi.RequestLifeCycleProvider#requestDestroyed(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext)
*/
public void requestDestroyed(HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext) {
cleanThreadLocals();
}
/* (non-Javadoc)
* @see clime.messadmin.providers.spi.RequestExceptionProvider#requestException(java.lang.Exception, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.ServletContext)
*/
public void requestException(Exception e, HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext) {
cleanThreadLocals();
}
protected void cleanThreadLocals() {
// ThreadLocals - With Great Power, comes Great Responsibility
// Can't do anything here. You need to manually set all your ThreadLocals to null yourself (myThreadLocal.remove() or myThreadLocal.set(null))...
// Apache Logging Log4J 1.x
// org.apache.log4j.NDC.remove();
if (log4jNDCRemoveMethod != null) {
try {
log4jNDCRemoveMethod.invoke(null, null);
} catch (Exception e) {
// do nothing
}
}
// org.apache.log4j.MDC.getContext().clear();
if (log4jMDCContextMethod != null) {
try {
Map context = (Map) log4jMDCContextMethod.invoke(null, null);
if (context != null) {
context.clear();
}
} catch (Exception e) {
// do nothing
}
}
// LOGBack
// ch.qos.logback.classic.MDC.clear();
if (logBackMDCClearMethod != null) {
try {
logBackMDCClearMethod.invoke(null, null);
} catch (Exception e) {
// do nothing
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy