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 55422b66626..c36234851a1 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 @@ -19,6 +19,7 @@ package org.eclipse.jetty.websocket.jsr356.server; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -152,10 +153,56 @@ public class ServerContainer extends ClientContainer implements javax.websocket. private void addEndpointMapping(ServerEndpointConfig config) throws DeploymentException { + assertIsValidEndpoint(config); + JsrCreator creator = new JsrCreator(this, config, webSocketServerFactory.getExtensionFactory()); mappedCreator.addMapping(new UriTemplatePathSpec(config.getPath()), creator); } + private void assertIsValidEndpoint(ServerEndpointConfig config) throws DeploymentException + { + EndpointFunctions endpointFunctions = null; + try + { + // Test that endpoint can be instantiated + Object endpoint = config.getEndpointClass().newInstance(); + + // Establish an EndpointFunctions to test validity of Endpoint declaration + AvailableEncoders availableEncoders = new AvailableEncoders(config); + AvailableDecoders availableDecoders = new AvailableDecoders(config); + Map pathParameters = new HashMap<>(); + endpointFunctions = newJsrEndpointFunction(endpoint, availableEncoders, availableDecoders, pathParameters, config); + endpointFunctions.start(); // this should trigger an exception if endpoint is invalid. + } + catch (InstantiationException e) + { + throw new DeploymentException("Unable to instantiate new instance of endpoint: " + config.getEndpointClass().getName(), e); + } + catch (IllegalAccessException e) + { + throw new DeploymentException("Unable access endpoint: " + config.getEndpointClass().getName(), e); + } + catch (Exception e) + { + throw new DeploymentException("Unable add endpoint: " + config.getEndpointClass().getName(), e); + } + finally + { + if (endpointFunctions != null) + { + try + { + // Dispose of EndpointFunctions + endpointFunctions.stop(); + } + catch (Exception ignore) + { + // ignore + } + } + } + } + @Override public EndpointFunctions newJsrEndpointFunction(Object endpoint, AvailableEncoders availableEncoders, diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DeploymentExceptionTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DeploymentExceptionTest.java index c138f8400c4..80c6dc4096c 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DeploymentExceptionTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DeploymentExceptionTest.java @@ -36,6 +36,7 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenIntSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.InvalidOpenSessionIntSocket; import org.eclipse.jetty.websocket.server.MappedWebSocketCreator; import org.eclipse.jetty.websocket.server.WebSocketServerFactory; +import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandlerWrapper; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -81,7 +82,7 @@ public class DeploymentExceptionTest @Test public void testDeploy_InvalidSignature() throws Exception { - MappedWebSocketCreator creator = new DummyCreator(); + MappedWebSocketCreator creator = new WebSocketUpgradeHandlerWrapper(); WebSocketServerFactory serverFactory = new WebSocketServerFactory(); Executor executor = new QueuedThreadPool(); ServerContainer container = new ServerContainer(creator, serverFactory, executor); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DummyCreator.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DummyCreator.java deleted file mode 100644 index eb927386578..00000000000 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DummyCreator.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.jsr356.server; - -import org.eclipse.jetty.http.pathmap.PathMappings; -import org.eclipse.jetty.http.pathmap.PathSpec; -import org.eclipse.jetty.websocket.server.MappedWebSocketCreator; -import org.eclipse.jetty.websocket.servlet.WebSocketCreator; - -public class DummyCreator implements MappedWebSocketCreator -{ - @Override - public void addMapping(PathSpec spec, WebSocketCreator creator) - { - /* do nothing */ - } - - @Override - public PathMappings getMappings() - { - return null; - } -}