Search code examples
tomcatservletcontextlistener

Why does Tomcat serve "bonus" context with a path which has the same name with the deployed web app?


I deployed a web application in tomcat with eclipse. Because of a long web application name(for example, ServletContextListenerTester), I want to access it by abbreviated path(ContextListenerTester), and my configuration is as follows:

    <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log." suffix=".txt"/>
          <Context docBase="ServletContextListenerTester" path="/ContextListenerTester" reloadable="true" source="org.eclipse.jst.jee.server:ServletContextListenerTester"/>
    </Host>

Everything works well, except the ServletContextListener.contextInitialized() is called two times. My implemented ServletContextListener code is as follow:

public class InitialListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("****************************");
        System.out.println("ServletContext is initilizing...");
        System.out.println("****************************");
    }

   public void contextDestroyed(ServletContextEvent arg0) {
       // TODO Auto-generated method stub
   }
}

I can see the "abnormal" console output(two times of "ServletContext is initilizing...", namely the contextInitialized function is called two times).

And more interestingly, the web app can be accessed by both the full app name(http://localhost/ServletContextListenerTester/) and its abbreviated name(http://localhost/ContextListenerTester/) specified by Context's path.

Maybe the "bonus" context with full app name can explain why ServletContextListener.contextInitialized() is called two times.

I want to know why the "bonus" context exists.

Thanks for your attention!


Solution

  • Tomcat is doing this double deployment because you have asked it to do so:

    1. Tomcat deploys your web application on /ContextListenerTester given your <Context> from server.xml according to your configuration 1. Tomcat auto-deploys your web application from webapps/ServletContextListenerTester because your <Host> has autoDeploy="true" set.

    If you don't want double-deployment, don't ask for it.

    If you want your web application to be found at /ContextListenerTester, then name your WAR File (or exploded WAR directory) ContextListenerTester (instead of ServletContextListenerTester) and remove the <Context> from your server.xml.

    You should no longer be putting <Context> into server.xml at all: there are much better ways to do it.