"flavia.rainone(a)jboss.com" wrote : I'll continue investigating. Once I have
all this sorted out, I'll commit the full version of those tests.
The cause of the failure is that the cleanup of classpools is not being performed. At the
moment RegisterModuleCallback.removeModule is invoked, the classloader in the module is
already null:
logger.debug("Removing module " + module);
| ClassLoader classLoader = ClassLoading.getClassLoaderForModule(module);
| ClassPoolRepository.getInstance().unregisterClassLoader(classLoader);
| domainRegistry.cleanupLoader(classLoader);
| registeredModules.remove(module);
| unregisteredModules.remove(module);
I can use the maps in domainRegistry in order to get to the classloader and
"fix" this. However, those maps use WeakReference and I can never be sure
whether the class loader is gc'ed at the moment I try to use those maps. If it is
gc'ed, the associated ClassPool won't be cleaned up.
To workaround this scenario, I can see three options here:
1. replace the CL weak reference by a hard reference. That will garantee that we can do
the right cleanup. This has a downside because weak references are safe against memory
leaks. But we will always get rid of the hard reference on removeModule, and this method
must always be called or otherwise the classpools won't work.
2. add checks in strategic points of the code. Those checks will look for the classpools
associated with a null CL, performing a clean up of those (there is already a method for
doing this in ScopedClassPoolRepository). IMO, this has the disadvantage that we are
trying to cover ourselves from a ClassPool cleanup that failed, when in reality we should
be fixing the cleanup itself instead of trying to cover the failure in other points of the
code.
3. create an extra map in DomainRegistry that maps Modules to ClassPools. The downside of
this option is that it kind of breaks the current design, because we use:
ClassPool javassist.scopedpool.ScopedClassPoolRepository.registerClassLoader(ClassLoader
cl) to create a ClassPool, and we use:
void javassist.scopedpool.ScopedClassPoolRepository.unregisterClassLoader(ClassLoader cl)
to clean it up. So we would have to create an unregister method that receives the module
as a paramter and add this method to org.jboss.classpool.spi.ClassPoolRepository (subclass
of ScopedCPRepository).
Which way should I go? My vote is for the first option.
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4265288#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...