Author: kkolinko
Date: Mon Jul 14 23:57:35 2014
New Revision: 1610562

URL: http://svn.apache.org/r1610562
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56717
Fix duplicate registration of MapperListener during repeated starts of embedded 
Tomcat.
Properly unregister it when Tomcat stops.

Added:
    tomcat/trunk/test/org/apache/catalina/mapper/TestMapperListener.java   
(with props)
Modified:
    tomcat/trunk/java/org/apache/catalina/mapper/MapperListener.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/mapper/MapperListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mapper/MapperListener.java?rev=1610562&r1=1610561&r2=1610562&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/mapper/MapperListener.java (original)
+++ tomcat/trunk/java/org/apache/catalina/mapper/MapperListener.java Mon Jul 14 
23:57:35 2014
@@ -116,6 +116,9 @@ public class MapperListener extends Life
     @Override
     public void stopInternal() throws LifecycleException {
         setState(LifecycleState.STOPPING);
+
+        Engine engine = (Engine) service.getContainer();
+        removeListeners(engine);
     }
 
 

Added: tomcat/trunk/test/org/apache/catalina/mapper/TestMapperListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/mapper/TestMapperListener.java?rev=1610562&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/mapper/TestMapperListener.java (added)
+++ tomcat/trunk/test/org/apache/catalina/mapper/TestMapperListener.java Mon 
Jul 14 23:57:35 2014
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.mapper;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.ContainerListener;
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.websocket.server.WsContextListener;
+
+public class TestMapperListener extends TomcatBaseTest {
+
+    @Test
+    public void testTomcatRestartListenerCount_Bug56717() throws IOException,
+            LifecycleException {
+        // The test runs Tomcat twice, tests that it has started successfully,
+        // and compares the counts of listeners registered on containers
+        // after the first and the second starts.
+        // Sample request is from TestTomcat#testSingleWebapp()
+
+        Tomcat tomcat = getTomcatInstance();
+
+        File appDir = new File(getBuildDirectory(), "webapps/examples");
+        // app dir is relative to server home
+        Context ctxt = tomcat.addWebapp(null, "/examples",
+                appDir.getAbsolutePath());
+        ctxt.addApplicationListener(WsContextListener.class.getName());
+        tomcat.start();
+
+        ByteChunk res;
+        String text;
+        res = getUrl("http://localhost:"; + getPort()
+                + "/examples/servlets/servlet/HelloWorldExample");
+        text = res.toString();
+        Assert.assertTrue(text, text.contains("<h1>Hello World!</h1>"));
+
+        List<ListenersInfo> listenersFirst = new ArrayList<>();
+        populateListenersInfo(listenersFirst, tomcat.getEngine());
+
+        tomcat.stop();
+        tomcat.start();
+
+        res = getUrl("http://localhost:"; + getPort()
+                + "/examples/servlets/servlet/HelloWorldExample");
+        text = res.toString();
+        Assert.assertTrue(text, text.contains("<h1>Hello World!</h1>"));
+
+        List<ListenersInfo> listenersSecond = new ArrayList<>();
+        populateListenersInfo(listenersSecond, tomcat.getEngine());
+
+        Assert.assertEquals(listenersFirst.size(), listenersSecond.size());
+        for (int i = 0, len = listenersFirst.size(); i < len; i++) {
+            ListenersInfo a = listenersFirst.get(i);
+            ListenersInfo b = listenersSecond.get(i);
+            boolean equal = a.container.getClass() == b.container.getClass()
+                    && a.containerListeners.length == 
b.containerListeners.length
+                    && a.lifecycleListeners.length == 
b.lifecycleListeners.length;
+            if (!equal) {
+                Assert.fail("The lists of listeners differ:\n" + a + "\n" + b);
+            }
+        }
+    }
+
+    private static class ListenersInfo {
+        public final Container container;
+        public final ContainerListener[] containerListeners;
+        public final LifecycleListener[] lifecycleListeners;
+
+        public ListenersInfo(Container container,
+                ContainerListener[] containerListeners,
+                LifecycleListener[] lifecycleListeners) {
+            this.container = container;
+            this.containerListeners = containerListeners;
+            this.lifecycleListeners = lifecycleListeners;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder buf = new StringBuilder();
+            buf.append("[container: \"").append(container)
+                    .append("\"\n containerListeners.length: ")
+                    .append(containerListeners.length)
+                    .append(", lifecycleListeners.length: ")
+                    .append(lifecycleListeners.length)
+                    .append("\n containerListeners: ")
+                    .append(Arrays.asList(containerListeners))
+                    .append("\n lifecycleListeners: ")
+                    .append(Arrays.asList(lifecycleListeners)).append("\n]");
+            return buf.toString();
+        }
+    }
+
+    private static void populateListenersInfo(List<ListenersInfo> list,
+            Container container) {
+        list.add(new ListenersInfo(container, container
+                .findContainerListeners(), 
container.findLifecycleListeners()));
+        for (Container child : container.findChildren()) {
+            populateListenersInfo(list, child);
+        }
+    }
+}

Propchange: tomcat/trunk/test/org/apache/catalina/mapper/TestMapperListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1610562&r1=1610561&r2=1610562&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Jul 14 23:57:35 2014
@@ -59,6 +59,11 @@
         <bug>56712</bug>: Fix session idle time calculations in
         <code>PersistenceManager</code>. (kkolinko)
       </fix>
+      <fix>
+        <bug>56717</bug>: Fix duplicate registration of
+        <code>MapperListener</code> during repeated starts of embedded Tomcat.
+        (kkolinko)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to