Sunday, August 2, 2015

Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource


Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]

I encountered this error when, i was doing a sample web application, using Annotations fully. Below is the sample snippet, which triggered the above issue. Once i registered the AppConfig to the AnnotationConfigWebApplicationContext, i added context.refresh, to fully process the class, which results in the above exception, when i removed the context.refresh, everything seems to be fine, but when i add it back, i am getting the same exception, so what triggers the issue?

public class AppInitializer implements WebApplicationInitializer{
 
 private static final String MAPPING_URL = "/";

 public void onStartup(ServletContext servletContext) throws ServletException {
  AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
  context.register(AppConfig.class); 
  servletContext.addListener(new ContextLoaderListener(context));
  context.refresh();
  ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new CustomDispatcherServlet(context));
  dispatcher.setLoadOnStartup(1);
  dispatcher.addMapping(MAPPING_URL);  
 } 
 
}

As per DispatcherServlet Constructor as specified here

  • If the given context does not already have a parent, the root application context will be set as the parent.
  • If the given context has not already been assigned an id, one will be assigned to it
  • ServletContext and ServletConfig objects will be delegated to the application context
  • FrameworkServlet.postProcessWebApplicationContext(org.springframework.web.context.ConfigurableWebApplicationContext) will be called
  • Any ApplicationContextInitializers specified through the "contextInitializerClasses" init-param or through the
  • FrameworkServlet.setContextInitializers(org.springframework.context.ApplicationContextInitializer...) property will be applied.
  • refresh() will be called if the context implements ConfigurableApplicationContext

If the context has already been refreshed, none of the above will occur, under the assumption that the user has performed these actions (or not) per their specific needs.

So for the DispatcherServlet, you modify the code as below

AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
context.register(WebConfig .class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new CustomDispatcherServlet(webContext));

Sample Code of the WebConfig class as shown below.

@Configuration
@Configuration
@EnableWebMvc
@ComponentScan("com.practice")
public class WebConfig extends WebMvcConfigurerAdapter{

@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver =
new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);

}

Happy Programming...!!!