Apache Tomcat Maven Plugin
  1. Apache Tomcat Maven Plugin
  2. MTOMCAT-186

Closing executable JAR does not call ServletContextListener.contextDestroyed()

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.0
    • Fix Version/s: 2.1
    • Component/s: tomcat7
    • Labels:
      None
    • Environment:
      Java 7, maven 3.0.3

      Description

      Executable JAR created by tomcat7-maven-plugin:exec-war-only does not call ServletContextListener.contextDestroyed() callback method when Java process is killed or when Ctrl + C is pressed. There is no way to cleanly shutdown web application.

      The same application (attached) deployed on standalone Tomcat works just fine. Hitting Ctrl + C correctly undeploys and shuts down application.

      Build attached application and run java -jar target/standalone.jar. Ctrl + C kills the process immediately. On the other hand {standalone.war}} deployed to normal Tomcat under /webapps shuts down correctly and we can see log statement from contextDestroyed().

      1. listener.zip
        29 kB
        Tomasz Nurkiewicz

        Activity

        Hide
        Tomasz Nurkiewicz added a comment -

        Thank you for the fix, I confirm, 2.1 works as expected. It's actually a Spring application that shuts down gracefully.

        Show
        Tomasz Nurkiewicz added a comment - Thank you for the fix, I confirm, 2.1 works as expected. It's actually a Spring application that shuts down gracefully.
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        Thanks Konstantin Kolinko for the advice.
        It's now implemented see http://svn.apache.org/r1440948
        SNAPSHOT deployed.

        Show
        Olivier Lamy (*$^¨%`£) added a comment - Thanks Konstantin Kolinko for the advice. It's now implemented see http://svn.apache.org/r1440948 SNAPSHOT deployed.
        Hide
        Hudson added a comment -

        Integrated in TomcatMavenPlugin-mvn3.x #231 (See https://builds.apache.org/job/TomcatMavenPlugin-mvn3.x/231/)
        MTOMCAT-186 Closing executable JAR does not call ServletContextListener.contextDestroyed() (Revision 1440948)

        Result = SUCCESS
        olamy : http://svn.apache.org/viewvc/?view=rev&rev=1440948
        Files :

        • /tomcat/maven-plugin/trunk/pom.xml
        • /tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java
        Show
        Hudson added a comment - Integrated in TomcatMavenPlugin-mvn3.x #231 (See https://builds.apache.org/job/TomcatMavenPlugin-mvn3.x/231/ ) MTOMCAT-186 Closing executable JAR does not call ServletContextListener.contextDestroyed() (Revision 1440948) Result = SUCCESS olamy : http://svn.apache.org/viewvc/?view=rev&rev=1440948 Files : /tomcat/maven-plugin/trunk/pom.xml /tomcat/maven-plugin/trunk/tomcat7-war-runner/src/main/java/org/apache/tomcat/maven/runner/Tomcat7Runner.java
        Hide
        Konstantin Kolinko added a comment -

        The shutdown hook used by o.a.c.startup.Catalina is Catalina$CatalinaShutdownHook. Maybe it could be generalized, or a similar class should be added to be used with o.a.c.startup.Tomcat.

        If someone is going to create a copy of the shutdown hook class, maybe I should explain one implementation detail:

        Note that the logging subsystem installs its own shutdown hook as well. When JVM shuts down, it starts all hooks in parallel without any order, so there is a risk that some log messages will be lost as the logging system will be shut down too early.

        This issue is already solved in Catalina$CatalinaShutdownHook, but the solution works only when Tomcat's JULI ClassLoaderLogManager is used. It does not work with plain java.util.logging.LogManager which I think is used when running a JAR file.

        I see that Tomcat7Runner.installLogger() may install "org.slf4j.bridge.SLF4JBridgeHandler". I do not know how to deal with that one either.

        The solution works like the following:

        First, it should be noted that the following 3 hooks are installed:
        a) java.util.logging.LogManager$Cleaner
        b) org.apache.juli.ClassLoaderLogManager$Cleaner
        c) org.apache.catalina.startup.Catalina$CatalinaShutdownHook

        To ensure that the logging subsystem is shutdown by CatalinaShutdownHook only, the following is used:

        1. "a)" is dealt with in ClassLoaderLogManager.reset() where it ignores a call from LogManager$Cleaner
        2. "b)" is dealt with in Catalina.start() where it calls ClassLoaderLogManager.setUseShutdownHook(false) after installing its own shutdown hook
        3. Catalina$CatalinaShutdownHook.run() calls ClassLoaderLogManager.shutdown()

        http://svn.apache.org/viewvc?view=revision&revision=910974
        http://svn.apache.org/viewvc?view=revision&revision=918885

        Show
        Konstantin Kolinko added a comment - The shutdown hook used by o.a.c.startup.Catalina is Catalina$CatalinaShutdownHook. Maybe it could be generalized, or a similar class should be added to be used with o.a.c.startup.Tomcat. If someone is going to create a copy of the shutdown hook class, maybe I should explain one implementation detail: Note that the logging subsystem installs its own shutdown hook as well. When JVM shuts down, it starts all hooks in parallel without any order, so there is a risk that some log messages will be lost as the logging system will be shut down too early. This issue is already solved in Catalina$CatalinaShutdownHook, but the solution works only when Tomcat's JULI ClassLoaderLogManager is used. It does not work with plain java.util.logging.LogManager which I think is used when running a JAR file. I see that Tomcat7Runner.installLogger() may install "org.slf4j.bridge.SLF4JBridgeHandler". I do not know how to deal with that one either. The solution works like the following: First, it should be noted that the following 3 hooks are installed: a) java.util.logging.LogManager$Cleaner b) org.apache.juli.ClassLoaderLogManager$Cleaner c) org.apache.catalina.startup.Catalina$CatalinaShutdownHook To ensure that the logging subsystem is shutdown by CatalinaShutdownHook only, the following is used: 1. "a)" is dealt with in ClassLoaderLogManager.reset() where it ignores a call from LogManager$Cleaner 2. "b)" is dealt with in Catalina.start() where it calls ClassLoaderLogManager.setUseShutdownHook(false) after installing its own shutdown hook 3. Catalina$CatalinaShutdownHook.run() calls ClassLoaderLogManager.shutdown() http://svn.apache.org/viewvc?view=revision&revision=910974 http://svn.apache.org/viewvc?view=revision&revision=918885

          People

          • Assignee:
            Olivier Lamy (*$^¨%`£)
            Reporter:
            Tomasz Nurkiewicz
          • Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development