You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/01/17 23:23:08 UTC

svn commit: r1434938 - in /tomcat/trunk: java/javax/websocket/ContainerProvider.java test/javax/websocket/ test/javax/websocket/TestContainerProvider.java

Author: markt
Date: Thu Jan 17 22:23:08 2013
New Revision: 1434938

URL: http://svn.apache.org/viewvc?rev=1434938&view=rev
Log:
WebSocket
Add the plumbing to obtain references to the WebSocketContainer
Includes a test case to make sure there are no mempry leaks

Added:
    tomcat/trunk/test/javax/websocket/
    tomcat/trunk/test/javax/websocket/TestContainerProvider.java   (with props)
Modified:
    tomcat/trunk/java/javax/websocket/ContainerProvider.java

Modified: tomcat/trunk/java/javax/websocket/ContainerProvider.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/websocket/ContainerProvider.java?rev=1434938&r1=1434937&r2=1434938&view=diff
==============================================================================
--- tomcat/trunk/java/javax/websocket/ContainerProvider.java (original)
+++ tomcat/trunk/java/javax/websocket/ContainerProvider.java Thu Jan 17 22:23:08 2013
@@ -16,17 +16,53 @@
  */
 package javax.websocket;
 
+import java.util.Map;
+import java.util.WeakHashMap;
+
 /**
  * Provides access to the implementation. This version of the API is hard-coded
  * to use the Apache Tomcat WebSocket implementation.
  */
 public class ContainerProvider {
 
+    // Needs to be a WeakHashMap to prevent memory leaks when a context is
+    // stopped
+    private static Map<ClassLoader,WebSocketContainer> classLoaderContainerMap =
+            new WeakHashMap<>();
+    private static Object classLoaderContainerMapLock = new Object();
+
+    private static final String DEFAULT_PROVIDER_CLASS_NAME =
+            "org.apache.tomcat.websocket.WsWebSocketContainer";
+
+    private static final Class<WebSocketContainer> clazz;
+
+    static {
+        try {
+            clazz = (Class<WebSocketContainer>) Class.forName(
+                    DEFAULT_PROVIDER_CLASS_NAME);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
     /**
-     * Obtain a reference to the ClientContainer used to create outgoing
-     * WebSocket connections.
+     * Obtain a reference to the per class loader ClientContainer used to create
+     * outgoing WebSocket connections.
      */
     public static WebSocketContainer getClientContainer() {
-        return null;
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        WebSocketContainer result = null;
+        synchronized (classLoaderContainerMapLock) {
+            result = classLoaderContainerMap.get(tccl);
+            if (result == null) {
+                try {
+                    result = clazz.newInstance();
+                } catch (InstantiationException | IllegalAccessException e) {
+                    throw new IllegalArgumentException(e);
+                }
+                classLoaderContainerMap.put(tccl, result);
+            }
+        }
+        return result;
     }
 }

Added: tomcat/trunk/test/javax/websocket/TestContainerProvider.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/javax/websocket/TestContainerProvider.java?rev=1434938&view=auto
==============================================================================
--- tomcat/trunk/test/javax/websocket/TestContainerProvider.java (added)
+++ tomcat/trunk/test/javax/websocket/TestContainerProvider.java Thu Jan 17 22:23:08 2013
@@ -0,0 +1,89 @@
+/*
+ * 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 javax.websocket;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Host;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+public class TestContainerProvider extends TomcatBaseTest {
+
+    /*
+     * Obtain a reference to the client container from a web app.
+     * Stop the web app.
+     * Make sure that there is no memory leak.
+     */
+    @Test
+    public void testGetClientContainer() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+
+        // Must have a real docBase - just use temp
+        StandardContext ctx = (StandardContext)
+            tomcat.addContext("", System.getProperty("java.io.tmpdir"));
+
+        // Map the test Servlet
+        GetClientContainerServlet ccServlet = new GetClientContainerServlet();
+        Tomcat.addServlet(ctx, "ccServlet", ccServlet);
+        ctx.addServletMapping("/", "ccServlet");
+
+        tomcat.start();
+
+        ByteChunk body = getUrl("http://localhost:" + getPort() + "/");
+
+        Assert.assertEquals("PASS", body.toString());
+
+        Host host = tomcat.getHost();
+        host.removeChild(ctx);
+
+        String[] leaks = ((StandardHost) host).findReloadedContextMemoryLeaks();
+
+        Assert.assertEquals(0, leaks.length);
+    }
+
+    private static class GetClientContainerServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+                throws ServletException, IOException {
+
+            WebSocketContainer wsc = ContainerProvider.getClientContainer();
+
+            resp.setContentType("text/plain");
+
+            if (wsc == null) {
+                resp.getWriter().print("FAIL");
+            } else {
+                resp.getWriter().print("PASS");
+            }
+        }
+    }
+}

Propchange: tomcat/trunk/test/javax/websocket/TestContainerProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native



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