-
Bug
-
Resolution: Obsolete
-
Major
-
None
-
2.3.1
With a Seam 2.2.2 application using Resteasy 2.3.1, I noticed after deployment that my web application's classes were not unloaded.
After some investigations with Eclipse Memory Analyer I figured out that the ThreadLocalStack caused the reason why the classes could not be unloaded. I'll try to explain:
The ThreadLocalStack contains a ThreadLocal. The value of the thread local is actually put on the entry which is referred by the Thread itself. The thread will clean-up the entry only if the referrer (here the instance of ThreadLocalStack) has been finalized as it's kept within a WeakReference.
One of the instance of ThreadLocalStack is the static field contextualData of the ReasteasyProviderFactory class. So that class need to be unloaded to cause the un-referencing of the thread local instance.
Having the Resteasy jars deployed within the application along with Seam 2, the class is hold by my application's class loader. However, this class loader is still referenced by instances of objects stored into the ThreadLocalStack's ThreadLocal's object list. Hence, the garbage collector will never consider removing the reference between the Thread and the ThreadLocal's content because the referrer belong itself to the content.
The (ugly) work-around I did is to replace the ThreadLocal<ArrayList<T>> local field by
Collections.synchronizedMap(new WeakHashMap<Thread, List<T>>())
So, the thread itself won't keep a reference to the object, and so when the application is undeployed, no reference will be kept between the GC root and the application's class loader.
On the other hand, using Resteasy as a module make the ThreadLocalStack keeping a reference to the SeamResteasyProviderFactory and so a class loader leak. As it belongs to a MSC Service Thread, there are no easy way for me to remove it, so I'll keep with deploying Resteasy within the EAR; but I think the proper solution would be to unregister application's provider factory to the contextual data at undeploy.