67

I am using jsf and spring together in web application. I have configured datasource and session factory in one configuration class which uses annotations like @Configuration, @ComponentScan etc. I don't have any applicationContext.xml file in my project as I am handling every entry of context xml in Configuration class. The test case works successfully but when I deploy my web application, it gives me error

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

Now if I give listener class in web.xml,

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

it gives me error,

/WEB-INF/applicationContext.xml not found

As per the document of ContextLoaderListener, it's true that if I don't give contextConfigLocation param in web.xml explicitly, it will search for the default spring context file named applicationContext.xml in web.xml. Now, what should I do if I don't want to use spring context file and do all the configuration with annotations? How should I register listener class ContextLoaderListener so that without use of xml file and using annotations only, I be able to run my web application with spring and jsf?

0

2 Answers 2

134

In web.xml you need to bootstrap the context with AnnotationConfigWebApplicationContext:

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            org.package.YouConfigurationAnnotatedClass
        </param-value>
    </init-param>
</servlet>

And don't forget to use @EnableWebMvc for your MVC annotations to kick in.

further reading:

EDIT as a "comments follow up" => to be Turing Complete:

Yes of course you need a listener. Although the above completely answers the question "How to register Spring @Configuration annotated class instead of applicationContext.xml file in web.xml", here is an example from Spring official documentation that layouts the full web.xml:

<web-app>
  <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
       instead of the default XmlWebApplicationContext -->
  <context-param>
      <param-name>contextClass</param-name>
      <param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
  </context-param>

  <!-- Configuration locations must consist of one or more comma- or space-delimited
       fully-qualified @Configuration classes. Fully-qualified packages may also be
       specified for component-scanning -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.acme.AppConfig</param-value>
  </context-param>

  <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- Declare a Spring MVC DispatcherServlet as usual -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
           instead of the default XmlWebApplicationContext -->
      <init-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </init-param>
      <!-- Again, config locations must consist of one or more comma- or space-delimited
           and fully-qualified @Configuration classes -->
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.acme.web.MvcConfig</param-value>
      </init-param>
  </servlet>

  <!-- map all requests for /app/* to the dispatcher servlet -->
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/app/*</url-pattern>
  </servlet-mapping>
</web-app>
6
  • Hi, I am not using Spring MVC here, only JSF and Spring 3.1 RC1. Though I wrote this servlet in my web.xml but still got same error "no ContextLoaderListener registered". I then did entry for listener class of spring and then got other error of applicationContext.xml not found. I hope I am making my point clear. Commented Nov 10, 2011 at 8:08
  • Hey, I got it worked when I added these 2 params as context params and spring listener class in web.xml. Thanks, your answer helped me to find out my answer. I am editing your answer to add my solution. You please approve it (as I don't have edit privileges) so that I can mark your answer as final. Commented Nov 10, 2011 at 9:36
  • I never received you edit request, but I updated my answer with an example of a full web.xml form the Spring official documentation.
    – tolitius
    Commented Nov 10, 2011 at 14:35
  • In my web application config i had to have <load-on-startup>1</load-on-startup> in dispatcher servlet. Without this dispatcher have not be loaded
    – marioosh
    Commented Sep 27, 2015 at 17:47
  • @tolitius, thanks for this comment <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext -->in your answer as it helped me understand the point Commented Jun 7, 2016 at 15:10
10

Bumping up an old question here, but with recent versions of Spring (v3.0+) now you can get rid of web.xml altogether, provided you are deploying your app on a web container that supports Servlet 3.0+.

One can implement Spring's WebApplicationInitializer interface to do the same configurations that one would do in web.xml. This implementation class will be automatically detected by Spring 3.0+ app running on Servlet 3.0+ containers.

If the set up is rather simple, you could instead use another class provided by Spring as shown below. All one does here is to set the @Configuration classes and list out the servlet mappings. Keeps the setup extremely simple.

public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] {AppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {
                 "*.html"
                ,"*.json"
                ,"*.do"};
    }
}
3
  • 2
    If you do try to get rid of web.xml be sure you're using a container that supports Servlet 3.0 like Tomcat 7.0.57. P.S. Steve, nice work with the leading commas! Commented Jan 27, 2015 at 16:25
  • That's true. I'll throw that in the answer. Thanks
    – Angad
    Commented Jan 27, 2015 at 16:26
  • I need web.xml to configure resources in was9
    – dextermini
    Commented Feb 6 at 18:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.