I creating a Java EE 7 project using Eclipse Maven plugin. My problem is when I run the application the class that implements SerlvetContextListener does not get invoked. What is causing this problem?
@WebListener
public class ApplicationContextListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce)
{
Request request = new HttpRequest(sce);
new Thread (request).start();
HibernateUtil.getSessionFactory();
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<listener>com.kyrogaming.AppServletContextListener</listener>
<!-- Jersey Mapping -->
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.kyrogaming.webservices</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<!-- end Jersey Mapping -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
To summarize JNL's and Ted Goddard's answers:
For a ServletContextListener (or other listeners, such as a ServletContextAttributeListener or a ServletRequestAttributeListener) to be loaded by the servlet container, you need to tell the container about it. As described in the API docs, there are three ways to do this:
Declare it in the deployment descriptor (web.xml):
com.kyrogaming.AppServletContextListeneror annotate its class with @WebListener
(see "Note about annotations" below)
or register it programatically, via the methods in ServletContext, such as addListener().
Note about annotations
Method 1) and 3) will always work. For method 2) (annotations) to work, the servlet container must be configured to scan the classes in the classpath, to find the annotated listener classes.
The webapp's own classes (under WEB-INF/classes
) and libraries (JARs under WEB-INF/lib
) will not be scanned if the web.xml contains the attribute metadata-complete="true"
(the attribute defaults to false
). See the Java Servlet Specification Version 3.0, chapter 8.1, "Annotations and pluggability".
In a web application, classes using annotations will have their annotations processed only if they are located in the WEB-INF/classes directory, or if they are packaged in a jar file located in WEB-INF/lib within the application. The web application deployment descriptor contains a new “metadata-complete” attribute on the web-app element. The “metadata-complete” attribute defines whether the web descriptor is complete, or whether the class files of the jar file should be examined for annotations and web fragments at deployment time. If “metadata-complete” is set to "true", the deployment tool MUST ignore any servlet annotations present in the class files of the application and web fragments. If the metadata-complete attribute is not specified or is set to "false", the deployment tool must examine the class files of the application for annotations, and scan for web fragments.
So, to allow the container to find annotated classes in JARs, make sure the web.xml sets metadata-complete="false"
, or does not set it at all.
Note that setting this may delay the application startup; see for example What to do with annotations after setting metadata-complete="true" (which resolved slow Tomcat 7 start-up)? .
Unfortunately, that still does not explain why the ServletContextListener in the question is not loaded. Note that the web.xml in the question does not metadata-complete
, meaning it defaults to false
, thus classpath scanning is enabled. There is probably some other problem; this checklist hopefully helps in finding it.