diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java index 8c43b62da24..bc2414c4233 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java @@ -173,30 +173,40 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont } @Override - public Session connectToServer(Class endpointClass, ClientEndpointConfig config, URI path) throws DeploymentException, IOException + public Session connectToServer(final Class endpointClass, final ClientEndpointConfig config, URI path) throws DeploymentException, IOException { - ConfiguredEndpoint instance = newConfiguredEndpoint(endpointClass, config); + ClientEndpointConfig clientEndpointConfig = config; + if (clientEndpointConfig == null) + { + clientEndpointConfig = new EmptyClientEndpointConfig(); + } + ConfiguredEndpoint instance = newConfiguredEndpoint(endpointClass, clientEndpointConfig); return connect(instance, path); } @Override - public Session connectToServer(Class annotatedEndpointClass, URI path) throws DeploymentException, IOException + public Session connectToServer(final Class annotatedEndpointClass, final URI path) throws DeploymentException, IOException { - ConfiguredEndpoint instance = newConfiguredEndpoint(annotatedEndpointClass, null); + ConfiguredEndpoint instance = newConfiguredEndpoint(annotatedEndpointClass, new EmptyClientEndpointConfig()); return connect(instance, path); } @Override - public Session connectToServer(Endpoint endpoint, ClientEndpointConfig config, URI path) throws DeploymentException, IOException + public Session connectToServer(final Endpoint endpoint, final ClientEndpointConfig config, final URI path) throws DeploymentException, IOException { - ConfiguredEndpoint instance = newConfiguredEndpoint(endpoint, config); + ClientEndpointConfig clientEndpointConfig = config; + if (clientEndpointConfig == null) + { + clientEndpointConfig = new EmptyClientEndpointConfig(); + } + ConfiguredEndpoint instance = newConfiguredEndpoint(endpoint, clientEndpointConfig); return connect(instance, path); } @Override public Session connectToServer(Object endpoint, URI path) throws DeploymentException, IOException { - ConfiguredEndpoint instance = newConfiguredEndpoint(endpoint, null); + ConfiguredEndpoint instance = newConfiguredEndpoint(endpoint, new EmptyClientEndpointConfig()); return connect(instance, path); } diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java index 496ba58f6e6..43d2bce26ad 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java @@ -162,27 +162,14 @@ public class JettyClientContainerProvider extends ContainerProvider if (useServerContainer && contextHandler != null) { - try - { - // Attempt to use the ServerContainer attribute. - Method methodGetServletContext = contextHandler.getClass().getMethod("getServletContext"); - Object objServletContext = methodGetServletContext.invoke(contextHandler); - if (objServletContext != null) - { - Method methodGetAttribute = objServletContext.getClass().getMethod("getAttribute", String.class); - Object objServerContainer = methodGetAttribute.invoke(objServletContext, "javax.websocket.server.ServerContainer"); - if (objServerContainer != null && objServerContainer instanceof WebSocketContainer) - { - webSocketContainer = (WebSocketContainer) objServerContainer; - } - } - - } - catch (Throwable ignore) - { - LOG.ignore(ignore); - // continue, without server container - } + SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy()); + QueuedThreadPool threadPool= new QueuedThreadPool(); + String name = "Jsr356Client@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + containerScope.setExecutor(threadPool); + containerScope.addBean(threadPool); + INSTANCE = new ClientContainer(containerScope); } if (useSingleton && INSTANCE != null) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index 41ebfc116f2..6c5cfc2e460 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -251,7 +251,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont private WebSocketClient(SslContextFactory sslContextFactory, Executor executor, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory) { this.httpClient = new HttpClient(sslContextFactory); - this.httpClient.setExecutor(executor); + this.httpClient.setExecutor(getExecutor(executor)); this.httpClient.setByteBufferPool(bufferPool); addBean(this.httpClient); @@ -262,7 +262,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont this.eventDriverFactory = new EventDriverFactory(containerScope); this.sessionFactory = new WebSocketSessionFactory(containerScope); } - + /** * Create WebSocketClient based on pre-existing Container Scope, to allow sharing of * internal features like Executor, ByteBufferPool, SSLContextFactory, etc. @@ -276,36 +276,30 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont */ public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory) { - this(scope, eventDriverFactory, sessionFactory, null); - } - - /** - * Create WebSocketClient based on pre-existing Container Scope, to allow sharing of - * internal features like Executor, ByteBufferPool, SSLContextFactory, etc. - * - * @param scope - * the Container Scope - * @param eventDriverFactory - * the EventDriver Factory to use - * @param sessionFactory - * the SessionFactory to use - */ - public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory, HttpClient httpClient) - { - this.containerPolicy = WebSocketPolicy.newClientPolicy(); - this.sslContextFactory = sslContextFactory; - this.objectFactory = objectFactory; - this.extensionRegistry = new WebSocketExtensionFactory(this); - this.masker = new RandomMasker(); - - setExecutor(executor); - setBufferPool(bufferPool); + WebSocketContainerScope clientScope; + if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT) + { + clientScope = scope; + } + else + { + // We need to wrap the scope + clientScope = new DelegatedContainerScope(WebSocketPolicy.newClientPolicy(), scope); + } - if(sslContextFactory!=null) - addBean(sslContextFactory); - addBean(this.executor); - addBean(this.sslContextFactory); - addBean(this.bufferPool); + this.containerScope = clientScope; + SslContextFactory sslContextFactory = scope.getSslContextFactory(); + if(sslContextFactory == null) + { + sslContextFactory = new SslContextFactory(); + } + this.httpClient = new HttpClient(sslContextFactory); + this.httpClient.setExecutor(getExecutor(scope.getExecutor())); + addBean(this.httpClient); + + this.extensionRegistry = new WebSocketExtensionFactory(containerScope); + + this.sessionFactory = sessionFactory; } public Future connect(Object websocket, URI toUri) throws IOException @@ -457,6 +451,21 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont return httpClient.getExecutor(); } + // Internal getExecutor for defaulting to internal executor if not provided + private Executor getExecutor(final Executor executor) + { + if (executor == null) + { + QueuedThreadPool threadPool = new QueuedThreadPool(); + String name = "WebSocketClient@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + return threadPool; + } + + return executor; + } + public ExtensionFactory getExtensionFactory() { return extensionRegistry; diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DelayedStartClientTest.java b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/DelayedStartClientTest.java similarity index 90% rename from jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DelayedStartClientTest.java rename to jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/DelayedStartClientTest.java index af004bf2b07..d907ccea94e 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DelayedStartClientTest.java +++ b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/DelayedStartClientTest.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.websocket.jsr356; +package org.eclipse.jetty.websocket.tests.client.jsr356; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; @@ -34,10 +34,8 @@ import java.util.concurrent.Executor; import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.junit.After; +import org.eclipse.jetty.websocket.jsr356.JettyClientContainerProvider; +import org.junit.Before; import org.junit.Test; public class DelayedStartClientTest @@ -59,6 +57,7 @@ public class DelayedStartClientTest List threadNames = getThreadNames((ContainerLifeCycle)container); assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@")))); assertThat("Threads", threadNames, not(hasItem(containsString("HttpClient@")))); + assertThat("Threads", threadNames, not(hasItem(containsString("Jsr356Client@")))); } public static List getThreadNames(ContainerLifeCycle... containers) diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java similarity index 94% rename from jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java rename to jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java index ac43e595d7d..a5fd6f9a8a0 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java +++ b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.websocket.jsr356.server; +package org.eclipse.jetty.websocket.tests.server.jsr356; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; @@ -59,6 +59,8 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.websocket.api.util.WSURI; import org.eclipse.jetty.websocket.jsr356.ClientContainer; +import org.eclipse.jetty.websocket.jsr356.JettyClientContainerProvider; +import org.eclipse.jetty.websocket.jsr356.server.ServerContainer; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.junit.Test; @@ -177,9 +179,8 @@ public class DelayedStartClientOnServerTest { if (threadName.startsWith("HttpClient@") && !threadName.endsWith("-scheduler")) { - throw new AssertionError("Found non-scheduler HttpClient thread in <" + - threadNames.stream().collect(Collectors.joining("[", ", ", "]")) - + ">"); + throw new AssertionError("Found non-scheduler HttpClient thread in " + + threadNames.stream().collect(Collectors.joining(", ", "[", "]"))); } } } @@ -223,6 +224,7 @@ public class DelayedStartClientOnServerTest assertNoHttpClientPoolThreads(threadNames); assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@")))); assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketClient@")))); + assertThat("Threads", threadNames, not(hasItem(containsString("Jsr356Client@")))); } finally { @@ -299,6 +301,7 @@ public class DelayedStartClientOnServerTest assertNoHttpClientPoolThreads(threadNames); assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@")))); assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketClient@")))); + assertThat("Threads", threadNames, not(hasItem(containsString("Jsr356Client@")))); } finally { @@ -324,6 +327,7 @@ public class DelayedStartClientOnServerTest List threadNames = getThreadNames((ContainerLifeCycle)container, server); assertNoHttpClientPoolThreads(threadNames); assertThat("Threads", threadNames, not(hasItem(containsString("WebSocketContainer@")))); + assertThat("Threads", threadNames, not(hasItem(containsString("Jsr356Client@")))); } finally {