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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org