|
From: Juergen H. <ju...@in...> - 2006-05-29 15:01:51
|
Thanks for pointing this out!
I have addressed this through the introduction of a BeanClassLoaderAware
interface, which passes the current bean ClassLoader into the
setBeanClassLoader method (if desired). This is mainly intended for use
within the framework itself, for beans that need to pick up application
classes by name but might reside in a shared class loader themselves (so
getClass().getClassLoader() wouldn't be right either).
All affected classes within Spring itself leverage this new
BeanClassLoaderAware mechanism now. If you find any further issues here,
please let us know!
Juergen
-----Original Message-----
From: spr...@li...
[mailto:spr...@li...] On Behalf Of
Rich Giuli
Sent: Thursday, May 18, 2006 12:25 AM
To: spr...@li...
Subject: [Springframework-developer] ApplicationContext custom classloader
problems
Hi all,
org.springframework.core.io.DefaultResourceLoader has the method
"setClassLoader" to set the class loader used to load resources. I have a
FileSystemXmlApplicationContext and I set the class loader on it before the
context refreshes.
The problem is that certain default beans always use the thread context
class loader even when they are specified in the XML file loaded with my
FileSystemXmlApplicationContext. For example, here are 2 bean declarations
which fail to use the class loader I specified:
<bean id="rexaService"
class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl"
value="http://localhost:8081/RexaRetrieval"/>
<property name="serviceInterface"
value="com.sri.iris.plugins.rexa.IDataRetrievalAgent"/>
</bean>
and
<bean
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"
autowire="no" dependency-check="none">
<property name="staticField"
value="com.sri.iris.store.pojo.IFormDefinitionPojo.SUMMARY_VIEW_IS"/>
</bean>
These fail if the class name given only resides in the custom class loader
and not the thread context class loader.
A workaround is to set the thread context class loader to the
DefaultResourceLoader's class loader using a BeanPostProcessor (the
"postProcessBeforeInitialization" method). For example:
public Object postProcessBeforeInitialization(Object bean, String
beanName) throws BeansException {
// XXX Make sure the ClassLoader of the ApplicationContext is
set as the thread context class loader...
boolean clSet = false;
if (applicationContext instanceof DefaultResourceLoader) {
ClassLoader cl =
((DefaultResourceLoader)applicationContext).getClassLoader();
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
clSet = true;
}
}
if (!clSet) {
Thread.currentThread().setContextClassLoader(bean.getClass().getClassLoader(
));
}
This workaround fixes the problem and the above bean definitions can find
classes in the custom class loader..
My main question is: should this be supported in Spring? It seems to be an
ambiguity because Spring allows the class laoder to be set, but then doesn't
set it to the thread context class loader before initializing beans.
Thanks,
Rich
|