Details
Description
PropertyUtils.clearDescriptors() is being called from ActionServlet.destroy() when undeploying an appliction. This call is made after LogFactory.release(). LogFactory.release() removes the application classloader instance from the LogFactory class. However PropertyUtils.clearDescriptors() causes LogFactory.getFactory() to be invoked again:
getFactory():218, org.apache.commons.logging.LogFactory
getLog():351, org.apache.commons.logging.LogFactory
<init>():130, org.apache.commons.beanutils.ConvertUtilsBean
<init>():110, org.apache.commons.beanutils.BeanUtilsBean
initialValue():68, org.apache.commons.beanutils.BeanUtilsBean$1
get():80, org.apache.commons.beanutils.ContextClassLoaderLocal
getInstance():78, org.apache.commons.beanutils.BeanUtilsBean
getInstance():101, org.apache.commons.beanutils.PropertyUtilsBean
clearDescriptors():121, org.apache.commons.beanutils.PropertyUtils
destroy():308, org.apache.struts.action.ActionServlet
This puts the application classloader instance back in the factories hashmap in LogFactory after which it is never removed. This causes a leak.
I think that the PropertyUtils.clearDescriptors() call should be made before LogFactory.release() and that should fix this problem. I just tried using an earlier version of struts without the PropertyUtils.clearDescriptors() call and that solved the application classloader memory leak.