From add00c9dd8750c4e97508ac0ab6fbe84f9d0b82a Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 25 May 2020 13:57:41 +1000 Subject: [PATCH] Issue #4903 - check endpoint class is default constructable Signed-off-by: Lachlan Roberts --- .../jsr356/server/ServerContainer.java | 6 ++-- .../jsr356/server/PrivateEndpointTest.java | 32 +++++++++++++++++-- 2 files changed, 32 insertions(+), 6 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 6365d92be710..f0cca5e66af9 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 @@ -18,7 +18,6 @@ package org.eclipse.jetty.websocket.jsr356.server; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; @@ -35,6 +34,7 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.common.events.EventDriverFactory; +import org.eclipse.jetty.websocket.common.util.ReflectUtils; import org.eclipse.jetty.websocket.jsr356.ClientContainer; import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; @@ -138,8 +138,8 @@ public void addEndpoint(Class endpointClass) throws DeploymentException private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException { - if (!Modifier.isPublic(metadata.getEndpointClass().getModifiers())) - throw new DeploymentException("Class modifier must be public"); + 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); 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 79d7b7716646..33e7b349590c 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 @@ -94,6 +94,21 @@ public void onMessage(String message) } } + @SuppressWarnings("InnerClassMayBeStatic") + public class ServerSocketNonStatic extends Endpoint implements MessageHandler.Whole + { + @Override + public void onOpen(Session session, EndpointConfig config) + { + session.addMessageHandler(this); + } + + @Override + public void onMessage(String message) + { + } + } + @ServerEndpoint("/annotated") private static class AnnotatedServerSocket { @@ -120,7 +135,18 @@ public void testEndpoint() assertThat(error.getCause(), instanceOf(DeploymentException.class)); DeploymentException deploymentException = (DeploymentException)error.getCause(); - assertThat(deploymentException.getMessage(), containsString("Class modifier must be public")); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor for the Endpoint class")); + } + + @Test + public void testInnerEndpoint() + { + RuntimeException error = assertThrows(RuntimeException.class, () -> + start(container -> container.addEndpoint(ServerEndpointConfig.Builder.create(ServerSocketNonStatic.class, "/").build()))); + + assertThat(error.getCause(), instanceOf(DeploymentException.class)); + DeploymentException deploymentException = (DeploymentException)error.getCause(); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor for the Endpoint class")); } @Test @@ -131,7 +157,7 @@ public void testAnnotatedEndpoint() assertThat(error.getCause(), instanceOf(DeploymentException.class)); DeploymentException deploymentException = (DeploymentException)error.getCause(); - assertThat(deploymentException.getMessage(), containsString("Class modifier must be public")); + assertThat(deploymentException.getMessage(), containsString("Cannot access default constructor for the Endpoint class")); } @Test @@ -144,4 +170,4 @@ public void testAnnotatedMethod() DeploymentException deploymentException = (DeploymentException)error.getCause(); assertThat(deploymentException.getMessage(), containsString("Method modifier must be public")); } -} +} \ No newline at end of file