"bstansberry(a)jboss.com" wrote : Ah, I'd missed your last post when I posted
mine. Sounds like you've nailed it.
Actually, I haven't. The hack I mentioned above solves the problem
for ClassLoader.loadClass() but there is some internal caching going on with
Class.forName() where I can't intercept the behaviour fix the problem.
I added some debug to the BeanMetaDataDeployer
| public void deploy(DeploymentUnit unit, BeanMetaData deployment) throws
DeploymentException
| {
| try
| {
| String bean = deployment.getBean();
| ClassLoader tcl = Thread.currentThread().getContextClassLoader();
| Class<?> fromClassLoader = tcl.loadClass(bean);
| Class<?> fromClassForName = Class.forName(bean, false, tcl);
| BeanInfo beanInfo = configurator.getBeanInfo(deployment);
| Class<?> fromBeanInfo = beanInfo.getClassInfo().getType();
|
| System.out.println("========> tcl=" + tcl + "
fromClassLoader=" + printClass(fromClassLoader) + " fromClassForName=" +
printClass(fromClassForName)+ " fromBeanInfo=" + printClass(fromBeanInfo)
|
which produces the following output on a redeploy
| 2008-02-05 21:27:25,189 INFO [STDOUT] ========>
tcl=BaseClassLoader@73a5d3{vfsfile:/home/ejort/jboss-head/build/output/jboss-5.0.0.Beta4/server/all/conf/jboss-service
| .xml}
fromClassLoader=org.jboss.test.naming.restart.RestartNamingService.BaseClassLoader@26f7af{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
|
fromClassForName=org.jboss.test.naming.restart.RestartNamingService.BaseClassLoader@50567b{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
fro
|
mBeanInfo=org.jboss.test.naming.restart.RestartNamingService.BaseClassLoader@50567b{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
| 2008-02-05 21:27:25,191 TRACE [org.jboss.classloader.spi.base.BaseClassLoader]
BaseClassLoader@50567b{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-
|
@26f7af is the correct version of the classloader
@50567b is the old (undeployed) version of the classloader
The Class.forName() invocation aboves never hits the classloader
(I've checked this by looking at the TRACE logging)
so it is obviously using some cache inside the JDK.
This problem will obviously be fixed when the TCL and BeanMetaData classloader
is set to the deployment classloader with the new code.
e.g. I can simulate this with
| public void deploy(DeploymentUnit unit, BeanMetaData deployment) throws
DeploymentException
| {
| ClassLoader old = Thread.currentThread().getContextClassLoader();
| Thread.currentThread().setContextClassLoader(unit.getClassLoader());
| try
| {
| try
| {
| String bean = deployment.getBean();
| ClassLoader tcl = Thread.currentThread().getContextClassLoader();
| Class<?> fromClassLoader = tcl.loadClass(bean);
| Class<?> fromClassForName = Class.forName(bean, false, tcl);
| BeanInfo beanInfo = configurator.getBeanInfo(deployment);
| Class<?> fromBeanInfo = beanInfo.getClassInfo().getType();
|
| System.out.println("========> tcl=" + tcl + "
fromClassLoader=" + printClass(fromClassLoader) + " fromClassForName=" +
printClass(fromClassForName)+ " fromBeanInfo=" + printClass(fromBeanInfo));
| }
| catch (Throwable t)
| {
| throw DeploymentException.rethrowAsDeploymentException("Unexpected
error", t);
| }
| ...
| }
| finally
| {
| Thread.currentThread().setContextClassLoader(old);
| }
| }
|
And the test passes with the following output on redeploy
| 21:40:29,591 INFO [STDOUT] ========>
tcl=BaseClassLoader@f800e1{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
fromClassLoader=org.jboss.test.naming.restart.RestartNamingService.BaseClassLoader@f800e1{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
fromClassForName=org.jboss.test.naming.restart.RestartNamingService.BaseClassLoader@f800e1{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
fromBeanInfo=org.jboss.test.naming.restart.RestartNamingService.BaseClassLoader@f800e1{vfsfile:/home/ejort/jboss-head/testsuite/output/lib/naming-restart.sar}
|
This is because the initiating classloader has changed so it avoids the
Class.forName() caching problem.
But this is still going to be an issue for usage of Class.forName() from
classloaders that don't get redeployed but have initiated classloading from
redeployed classloaders.
This must also have been issue with the old UnifiedClassLoader as well?
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4126757#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...