I am trying to migration an old project of mine from Spring 3.0.3.RELEASE to 4.0.9.RELEASE. I changed the pom.xml dependency to the 4.0.9, from that moment i am facing the problem. DispatcherServlet is not able to find the beans in the application context.
Following are my files
web.xml
<context-param>
<param-name>bootstrapConfig</param-name>
<param-value>
/com/core/choreographer/bootstrap/bootstrap-config.xml
</param-value>
</context-param>
<listener>
<listener-class>
com.core.bootstrap.BootstrapManager
</listener-class>
</listener>
<listener>
<listener-class>com.spring.http.SpringHttpContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>http-remoting</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:com/remote/springhttp-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>http-remoting</servlet-name>
<url-pattern>/remoting/*</url-pattern>
</servlet-mapping>
The bootstrap-config.xml has all the beans to be inserted into the spring context. It is read by the BootstrapManager is child of ServletContextListener and inserted into the spring context. As follows.
public class BootstrapManager implements ServletContextListener
{
public void contextInitialized( ServletContextEvent ctxEvt )
{
URL cfgURL = "location to the xml file" ;
ServletContext context = ctxEvt.getServletContext() ;
bootstrap.initialize( cfgURL ) ;
}
}
public class Bootstrap
{
public void initialize( final URL cfgURL ) throws BootstrapException
{
XMLConfiguration config = new XMLConfiguration() ;
URL dtdURL = ReflectionUtil.getResource( Bootstrap.class, "bootstrap-config.dtd" ) ;
// register it at the configuration
config.registerEntityId( "-//Bootstrap//DTD 1.0//EN", dtdURL ) ;
config.setValidating( true ) ;
config.setURL( cfgURL ) ;
config.load() ;
initBootstrapElements( config ) ;
}
private void initBootstrapElements( final XMLConfiguration config ) throws BootstrapException
{
HierarchicalConfiguration cfg = null ;
int numElements = config.getList( "bootstrap-element[@class]" ).size() ;
for( int i = 0 ; i < numElements ; i++ )
{
cfg = config.configurationAt( "bootstrap-element(" + i + ")" ) ;
initElement( cfg ) ;
}
}
public void initElement( final HierarchicalConfiguration config ) throws BootstrapException
{
String className = null ;
String propName = null ;
Object propVal = null ;
HierarchicalConfiguration propCfg = null ;
BootstrapElement element = null ;
className = config.getString( "[@class]" ) ;
element = (BootstrapElement) ReflectionUtil.createInstance( className.trim() ) ;
beanWrapper.setWrappedInstance( element ) ;
int numProps = config.getList( "property[@name]" ).size() ;
for( int i = 0 ; i < numProps ; i++ )
{
propCfg = config.configurationAt( "property(" + i + ")" ) ;
propName = propCfg.getString( "[@name]" ) ;
propVal = propCfg.getProperty( "[@value]" ) ;
if( propVal == null )
{
propVal = propCfg.getList( "value" ) ;
}
beanWrapper.setPropertyValue( propName, propVal ) ;
}
element.initialize() ;//This called the below new ClassPathXmlApplicationContext(
}
}
ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext( (String []) cfgLocations.toArray( new String [ 0 ] ) ) ;
Then I have a ContextLoaderListener
public class SpringHttpContextLoaderListener extends ContextLoaderListener {
private ContextLoader loader;
protected ContextLoader createContextLoader() {
loader = new SpringHttpContextLoader();
return loader;
}
public ContextLoader getContextLoader(){
return loader;
}
}
This is the ContextLoader
public class SpringHttpContextLoader extends ContextLoader {
protected ApplicationContext loadParentContext(ServletContext servletContext)
throws BeansException {
SpringObjectFactory fact = BaseSpringObjectFactory.getInstance();
return fact.getApplicationContext();
}
}
This all worked perfectly while in Spring 3.0.3. As I tried to replace all the Jar to 4.0.9. the Beans defined in the springhttp-servlet.xml cannot find the beans defined in the bootstrap-config.xml.
Any suggestion is highly appreciated. I am stuck from last 2-3 weeks in this.
I found the problem it was with the SpringHttpContextLoaderListener
. It was overridding a method createContextLoader
and getContextLoader
which was deprecated in Spring version 3 so was removed in Spring version 4. Due to this the Custom Context was not loaded as the parent context.
public class SpringHttpContextLoaderListener extends ContextLoaderListener {
private ContextLoader loader;
protected ContextLoader createContextLoader() {
loader = new SpringHttpContextLoader();
return loader;
}
public ContextLoader getContextLoader(){
return loader;
}
}
Solution
Override loadParentContext
of class ContextLoader
in the class SpringHttpContextLoaderListener
protected ApplicationContext loadParentContext(ServletContext servletContext)
throws BeansException {
SpringObjectFactory fact = BaseSpringObjectFactory.getInstance();
return fact.getApplicationContext();
}
This will set the custom created Context as the parent and will be available to all the child context