From 9bfc168329462d60daca38a6984d277daac929f7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 10 Jun 2020 11:01:30 -0500 Subject: [PATCH 1/4] Issue #4903 - Improved behavior for Custom ServerEndpointConfig.Configurator Signed-off-by: Joakim Erdfelt --- .../server/ContainerDefaultConfigurator.java | 2 +- .../jsr356/server/ServerContainer.java | 40 +++++++++-- .../jsr356/server/PrivateEndpointTest.java | 66 +++++++++++++++++-- 3 files changed, 99 insertions(+), 9 deletions(-) diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java index 0fc08fe2622d..561834550c05 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ContainerDefaultConfigurator.java @@ -68,7 +68,7 @@ public T getEndpointInstance(Class endpointClass) throws InstantiationExc { // Since this is started via a ServiceLoader, this class has no Scope or context // that can be used to obtain a ObjectFactory from. - return endpointClass.getDeclaredConstructor().newInstance(); + return endpointClass.getConstructor().newInstance(); } catch (Exception e) { diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index 4e79073c34f3..33058862c89f 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -121,8 +121,22 @@ public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpoin @Override public void addEndpoint(Class endpointClass) throws DeploymentException { + if (endpointClass == null) + { + throw new DeploymentException("Unable to deploy null endpoint class"); + } + if (isStarted() || isStarting()) { + if (!ReflectUtils.isDefaultConstructable(endpointClass)) + { + throw new DeploymentException("Cannot access default constructor for the class: " + endpointClass.getName()); + } + + if (LOG.isDebugEnabled()) + { + LOG.debug("addEndpoint({})", endpointClass); + } ServerEndpointMetadata metadata = getServerEndpointMetadata(endpointClass, null); addEndpoint(metadata); } @@ -136,11 +150,8 @@ public void addEndpoint(Class endpointClass) throws DeploymentException } } - private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException + private void addEndpoint(ServerEndpointMetadata metadata) { - if (!ReflectUtils.isDefaultConstructable(metadata.getEndpointClass())) - throw new DeploymentException("Cannot access default constructor for the Endpoint class"); - JsrCreator creator = new JsrCreator(this, metadata, this.configuration.getFactory().getExtensionFactory()); this.configuration.addMapping("uri-template|" + metadata.getPath(), creator); } @@ -148,8 +159,29 @@ private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentExcep @Override public void addEndpoint(ServerEndpointConfig config) throws DeploymentException { + if (config == null) + { + throw new DeploymentException("Unable to deploy null ServerEndpointConfig"); + } + + Class endpointClass = config.getEndpointClass(); + if (endpointClass == null) + { + throw new DeploymentException("Unable to deploy null endpoint class from ServerEndpointConfig: " + config.getClass().getName()); + } + if (isStarted() || isStarting()) { + ServerEndpointConfig.Configurator configurator = config.getConfigurator(); + // only validate constructor and class modifiers on non-custom configurators + if (configurator instanceof ContainerDefaultConfigurator) + { + if (!ReflectUtils.isDefaultConstructable(endpointClass)) + { + throw new DeploymentException("Cannot access default constructor for the class: " + endpointClass.getName()); + } + } + if (LOG.isDebugEnabled()) { LOG.debug("addEndpoint({}) path={} endpoint={}", config, config.getPath(), config.getEndpointClass()); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java index 33e7b349590c..b2e5ae6140db 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java @@ -33,6 +33,7 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.websocket.api.util.WSURI; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -41,6 +42,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; public class PrivateEndpointTest @@ -94,6 +96,26 @@ public void onMessage(String message) } } + public static class CustomEndpoint extends Endpoint implements MessageHandler.Whole + { + public CustomEndpoint(String id) + { + // This is a valid no-default-constructor implementation, and can be added via a custom + // ServerEndpointConfig.Configurator + } + + @Override + public void onOpen(Session session, EndpointConfig config) + { + session.addMessageHandler(this); + } + + @Override + public void onMessage(String message) + { + } + } + @SuppressWarnings("InnerClassMayBeStatic") public class ServerSocketNonStatic extends Endpoint implements MessageHandler.Whole { @@ -131,11 +153,47 @@ private void onMessage(String message) public void testEndpoint() { RuntimeException error = assertThrows(RuntimeException.class, () -> - start(container -> container.addEndpoint(ServerEndpointConfig.Builder.create(ServerSocket.class, "/").build()))); + { + ServerEndpointConfig config = ServerEndpointConfig.Builder.create(ServerSocket.class, "/").build(); + start(container -> container.addEndpoint(config)); + }); + + assertThat(error.getCause(), instanceOf(DeploymentException.class)); + DeploymentException deploymentException = (DeploymentException)error.getCause(); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor")); + } + + @Test + public void testCustomEndpoint() throws Exception + { + ServerEndpointConfig config = ServerEndpointConfig.Builder.create(CustomEndpoint.class, "/") + .configurator(new ServerEndpointConfig.Configurator() + { + @SuppressWarnings("unchecked") + @Override + public T getEndpointInstance(Class endpointClass) + { + return (T)new CustomEndpoint("server"); + } + }).build(); + start(container -> container.addEndpoint(config)); + + Session session = client.connectToServer(new CustomEndpoint("client"), WSURI.toWebsocket(server.getURI().resolve("/"))); + assertNotNull(session); + } + + @Test + public void testCustomEndpointNoConfigurator() + { + RuntimeException error = assertThrows(RuntimeException.class, () -> + { + ServerEndpointConfig config = ServerEndpointConfig.Builder.create(CustomEndpoint.class, "/").build(); + start(container -> container.addEndpoint(config)); + }); assertThat(error.getCause(), instanceOf(DeploymentException.class)); DeploymentException deploymentException = (DeploymentException)error.getCause(); - assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor for the Endpoint class")); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor")); } @Test @@ -146,7 +204,7 @@ public void testInnerEndpoint() assertThat(error.getCause(), instanceOf(DeploymentException.class)); DeploymentException deploymentException = (DeploymentException)error.getCause(); - assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor for the Endpoint class")); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor")); } @Test @@ -157,7 +215,7 @@ public void testAnnotatedEndpoint() assertThat(error.getCause(), instanceOf(DeploymentException.class)); DeploymentException deploymentException = (DeploymentException)error.getCause(); - assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor for the Endpoint class")); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor")); } @Test From b22e30679694b75234703e4b6d4f2abeb1704e6d Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 10 Jun 2020 17:03:26 -0500 Subject: [PATCH 2/4] Issue #4903 - Improved behavior for Custom ServerEndpointConfig.Configurator Signed-off-by: Joakim Erdfelt --- .../jsr356/server/ServerContainer.java | 8 +++++- .../jsr356/server/PrivateEndpointTest.java | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index 33058862c89f..b65698be0aa5 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -173,8 +173,14 @@ public void addEndpoint(ServerEndpointConfig config) throws DeploymentException if (isStarted() || isStarting()) { ServerEndpointConfig.Configurator configurator = config.getConfigurator(); + + if (configurator == null) + { + throw new DeploymentException("Unable to deploy with null ServerEndpointConfig.Configurator"); + } + // only validate constructor and class modifiers on non-custom configurators - if (configurator instanceof ContainerDefaultConfigurator) + if (configurator.getClass() == ContainerDefaultConfigurator.class) { if (!ReflectUtils.isDefaultConstructable(endpointClass)) { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java index b2e5ae6140db..55555d320eed 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java @@ -96,6 +96,14 @@ public void onMessage(String message) } } + private class CustomPrivateEndpoint extends Endpoint + { + @Override + public void onOpen(Session session, EndpointConfig config) + { + } + } + public static class CustomEndpoint extends Endpoint implements MessageHandler.Whole { public CustomEndpoint(String id) @@ -182,6 +190,25 @@ public T getEndpointInstance(Class endpointClass) assertNotNull(session); } + @Test + public void testCustomPrivateEndpoint() throws Exception + { + ServerEndpointConfig config = ServerEndpointConfig.Builder.create(CustomPrivateEndpoint.class, "/") + .configurator(new ServerEndpointConfig.Configurator() + { + @SuppressWarnings("unchecked") + @Override + public T getEndpointInstance(Class endpointClass) + { + return (T)new CustomPrivateEndpoint(); + } + }).build(); + start(container -> container.addEndpoint(config)); + + Session session = client.connectToServer(new CustomEndpoint("client"), WSURI.toWebsocket(server.getURI().resolve("/"))); + assertNotNull(session); + } + @Test public void testCustomEndpointNoConfigurator() { From f41f601e1971691f4f4f27d6f9c9faf99749a4c3 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 11 Jun 2020 09:58:49 +1000 Subject: [PATCH 3/4] Issue #4903 - fix validation on custom Configurator annotated endpoint Signed-off-by: Lachlan Roberts --- .../server/AnnotatedServerEndpointConfig.java | 2 +- .../jsr356/server/ServerContainer.java | 61 ++++++++++--------- ...EndpointTest.java => AddEndpointTest.java} | 58 +++++++++++++++++- .../server/samples/BasicOpenCloseSocket.java | 2 + 4 files changed, 89 insertions(+), 34 deletions(-) rename jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/{PrivateEndpointTest.java => AddEndpointTest.java} (78%) diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java index 306e0a9390ae..2d23b87d5a27 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointConfig.java @@ -129,7 +129,7 @@ else if (anno.configurator() == ServerEndpointConfig.Configurator.class) { try { - resolvedConfigurator = anno.configurator().getDeclaredConstructor().newInstance(); + resolvedConfigurator = anno.configurator().getConstructor().newInstance(); } catch (Exception e) { diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index b65698be0aa5..8ddf395038cc 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -118,26 +118,51 @@ public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpoin return new EndpointInstance(endpoint, cec, metadata); } - @Override - public void addEndpoint(Class endpointClass) throws DeploymentException + private void validateEndpointConfig(ServerEndpointConfig config) throws DeploymentException { + if (config == null) + { + throw new DeploymentException("Unable to deploy null ServerEndpointConfig"); + } + + ServerEndpointConfig.Configurator configurator = config.getConfigurator(); + if (configurator == null) + { + throw new DeploymentException("Unable to deploy with null ServerEndpointConfig.Configurator"); + } + + Class endpointClass = config.getEndpointClass(); if (endpointClass == null) { - throw new DeploymentException("Unable to deploy null endpoint class"); + throw new DeploymentException("Unable to deploy null endpoint class from ServerEndpointConfig: " + config.getClass().getName()); } - if (isStarted() || isStarting()) + if (configurator.getClass() == ContainerDefaultConfigurator.class) { if (!ReflectUtils.isDefaultConstructable(endpointClass)) { throw new DeploymentException("Cannot access default constructor for the class: " + endpointClass.getName()); } + } + } + @Override + public void addEndpoint(Class endpointClass) throws DeploymentException + { + if (endpointClass == null) + { + throw new DeploymentException("Unable to deploy null endpoint class"); + } + + if (isStarted() || isStarting()) + { if (LOG.isDebugEnabled()) { LOG.debug("addEndpoint({})", endpointClass); } + ServerEndpointMetadata metadata = getServerEndpointMetadata(endpointClass, null); + validateEndpointConfig(metadata.getConfig()); addEndpoint(metadata); } else @@ -159,39 +184,15 @@ private void addEndpoint(ServerEndpointMetadata metadata) @Override public void addEndpoint(ServerEndpointConfig config) throws DeploymentException { - if (config == null) - { - throw new DeploymentException("Unable to deploy null ServerEndpointConfig"); - } - - Class endpointClass = config.getEndpointClass(); - if (endpointClass == null) - { - throw new DeploymentException("Unable to deploy null endpoint class from ServerEndpointConfig: " + config.getClass().getName()); - } - if (isStarted() || isStarting()) { - ServerEndpointConfig.Configurator configurator = config.getConfigurator(); - - if (configurator == null) - { - throw new DeploymentException("Unable to deploy with null ServerEndpointConfig.Configurator"); - } - - // only validate constructor and class modifiers on non-custom configurators - if (configurator.getClass() == ContainerDefaultConfigurator.class) - { - if (!ReflectUtils.isDefaultConstructable(endpointClass)) - { - throw new DeploymentException("Cannot access default constructor for the class: " + endpointClass.getName()); - } - } + validateEndpointConfig(config); if (LOG.isDebugEnabled()) { LOG.debug("addEndpoint({}) path={} endpoint={}", config, config.getPath(), config.getEndpointClass()); } + ServerEndpointMetadata metadata = getServerEndpointMetadata(config.getEndpointClass(), config); addEndpoint(metadata); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AddEndpointTest.java similarity index 78% rename from jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java rename to jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AddEndpointTest.java index 55555d320eed..bd8492ffdd32 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PrivateEndpointTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AddEndpointTest.java @@ -18,12 +18,15 @@ package org.eclipse.jetty.websocket.jsr356.server; +import java.util.concurrent.TimeUnit; +import javax.websocket.CloseReason; import javax.websocket.ContainerProvider; import javax.websocket.DeploymentException; import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.OnMessage; +import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.WebSocketContainer; import javax.websocket.server.ServerEndpoint; @@ -35,6 +38,8 @@ import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.websocket.api.util.WSURI; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; +import org.eclipse.jetty.websocket.jsr356.server.samples.BasicOpenCloseSocket; +import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -44,8 +49,9 @@ import static org.hamcrest.Matchers.instanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class PrivateEndpointTest +public class AddEndpointTest { private Server server; private WebSocketContainer client; @@ -96,6 +102,7 @@ public void onMessage(String message) } } + @SuppressWarnings("InnerClassMayBeStatic") private class CustomPrivateEndpoint extends Endpoint { @Override @@ -104,6 +111,30 @@ public void onOpen(Session session, EndpointConfig config) } } + @SuppressWarnings("InnerClassMayBeStatic") + @ServerEndpoint(value = "/", configurator = CustomAnnotatedEndpointConfigurator.class) + public static class CustomAnnotatedEndpoint + { + public CustomAnnotatedEndpoint(String id) + { + } + + @OnOpen + public void onOpen(Session session, EndpointConfig config) + { + } + } + + public static class CustomAnnotatedEndpointConfigurator extends ServerEndpointConfig.Configurator + { + @SuppressWarnings("unchecked") + @Override + public T getEndpointInstance(Class endpointClass) + { + return (T)new CustomAnnotatedEndpoint("server"); + } + } + public static class CustomEndpoint extends Endpoint implements MessageHandler.Whole { public CustomEndpoint(String id) @@ -186,8 +217,12 @@ public T getEndpointInstance(Class endpointClass) }).build(); start(container -> container.addEndpoint(config)); - Session session = client.connectToServer(new CustomEndpoint("client"), WSURI.toWebsocket(server.getURI().resolve("/"))); + BasicOpenCloseSocket clientEndpoint = new BasicOpenCloseSocket(); + Session session = client.connectToServer(clientEndpoint, WSURI.toWebsocket(server.getURI().resolve("/"))); assertNotNull(session); + session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), Matchers.is(CloseReason.CloseCodes.NORMAL_CLOSURE)); } @Test @@ -205,8 +240,25 @@ public T getEndpointInstance(Class endpointClass) }).build(); start(container -> container.addEndpoint(config)); - Session session = client.connectToServer(new CustomEndpoint("client"), WSURI.toWebsocket(server.getURI().resolve("/"))); + BasicOpenCloseSocket clientEndpoint = new BasicOpenCloseSocket(); + Session session = client.connectToServer(clientEndpoint, WSURI.toWebsocket(server.getURI().resolve("/"))); + assertNotNull(session); + session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), Matchers.is(CloseReason.CloseCodes.NORMAL_CLOSURE)); + } + + @Test + public void testCustomAnnotatedEndpoint() throws Exception + { + start(container -> container.addEndpoint(CustomAnnotatedEndpoint.class)); + + BasicOpenCloseSocket clientEndpoint = new BasicOpenCloseSocket(); + Session session = client.connectToServer(clientEndpoint, WSURI.toWebsocket(server.getURI().resolve("/"))); assertNotNull(session); + session.close(); + assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientEndpoint.closeReason.getCloseCode(), Matchers.is(CloseReason.CloseCodes.NORMAL_CLOSURE)); } @Test diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/BasicOpenCloseSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/BasicOpenCloseSocket.java index c156bc39b21f..fb5bce5f3b0a 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/BasicOpenCloseSocket.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/BasicOpenCloseSocket.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.websocket.jsr356.server.samples; +import javax.websocket.ClientEndpoint; import javax.websocket.CloseReason; import javax.websocket.OnClose; import javax.websocket.OnOpen; @@ -26,6 +27,7 @@ import org.eclipse.jetty.websocket.jsr356.server.TrackingSocket; @ServerEndpoint(value = "/basic") +@ClientEndpoint public class BasicOpenCloseSocket extends TrackingSocket { @OnOpen From 66ef0ebc03b77d6c11eabaf119bc4b3d3fc7242f Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 11 Jun 2020 19:20:49 +1000 Subject: [PATCH 4/4] Issue #4903 - do ServerEndpointConfig validation check before started Signed-off-by: Lachlan Roberts --- .../eclipse/jetty/websocket/jsr356/server/ServerContainer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java index 8ddf395038cc..678febf2273d 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java +++ b/jetty-websocket/javax-websocket-server-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/server/ServerContainer.java @@ -184,10 +184,9 @@ private void addEndpoint(ServerEndpointMetadata metadata) @Override public void addEndpoint(ServerEndpointConfig config) throws DeploymentException { + validateEndpointConfig(config); if (isStarted() || isStarting()) { - validateEndpointConfig(config); - if (LOG.isDebugEnabled()) { LOG.debug("addEndpoint({}) path={} endpoint={}", config, config.getPath(), config.getEndpointClass());