问题
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>
回答1:
In web.xml you also need to specify the <listener-class>
.
<listener>
<listener-class>
com.kyrogaming.AppServletContextListener
</listener-class>
</listener>
回答2:
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:
1) Declare it in the deployment descriptor (web.xml):
<listener>
<listener-class>
com.kyrogaming.AppServletContextListener
</listener-class>
</listener>
2) or annotate its class with @WebListener (see "Note about annotations" below)
3) 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
) will always be scanned, so annotated classes will always be found. However, 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, "Annotations and pluggability".
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.
回答3:
Using metadata-complete="false" in web.xml fixed this issue for me.
<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"
metadata-complete="false">
回答4:
For the record, I'm adding yet another possible (and rather vicious) cause of ServletContextListener
not being invoked.
This can happen when you have a java.lang.LinkageError
, that is when you forgot to add <scope>provided</scope>
to your javax.servlet-api
dependency.
In such a case the listener instance is created but only the static part is executed, not the contextInitialized
and contextDestroyed
methods.
You shall discover only when you invoke some servlet, as the linkage error is not raised during listener instantiation.
来源:https://stackoverflow.com/questions/18367514/servletcontextlistener-not-being-invoked