0

I'm using Dropwizard for a REST server and dropwizard-websocket-jee7-bundle to enable websockets.
For the websocket server I used this example.
Testing the websocket server standalone works fine, but in combination with Dropwizard, when a client tries to connect (to ws://localhost:port/actions) it gets a 500 Internal Server Error (Error log below).
I'm guessing there is some bad or missing configuration, but I can't figure our where.

ServerExample:

package com.example; import static org.eclipse.jetty.servlets.CrossOriginFilter.ALLOWED_HEADERS_PARAM; import static org.eclipse.jetty.servlets.CrossOriginFilter.ALLOWED_METHODS_PARAM; import static org.eclipse.jetty.servlets.CrossOriginFilter.ALLOWED_ORIGINS_PARAM; import static org.eclipse.jetty.servlets.CrossOriginFilter.ALLOW_CREDENTIALS_PARAM; import java.util.EnumSet; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import org.eclipse.jetty.servlets.CrossOriginFilter; import com.example.health.SearchHealthCheck; import com.example.resources.TestFind; import be.tomcools.dropwizard.websocket.WebsocketBundle; import io.dropwizard.Application; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import com.example.websocket.DeviceWebSocketServer; public class ServerExample extends Application<ServerExampleConfiguration> { private WebsocketBundle websocket = new WebsocketBundle(); public static void main(String[] args) throws Exception { new ServerExample().run(args); } @Override public String getName() { return "com.example"; } @Override public void initialize(Bootstrap<ServerExampleConfiguration> bootstrap) { super.initialize(bootstrap); bootstrap.addBundle(websocket); } @Override public void run(ServerExampleConfiguration configuration, Environment environment) throws Exception { System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); FilterRegistration.Dynamic filter = environment.servlets().addFilter("CORSFilter", CrossOriginFilter.class); filter.setInitParameter(ALLOWED_METHODS_PARAM, "OPTIONS,POST,GET"); filter.setInitParameter(ALLOWED_ORIGINS_PARAM, "*"); filter.setInitParameter(ALLOWED_HEADERS_PARAM, "Origin,Content-Type,Accept,X-Requested-With"); filter.setInitParameter(ALLOW_CREDENTIALS_PARAM, "true"); filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); environment.jersey().register(new TestFind()); environment.healthChecks().register("search", new SearchHealthCheck()); //Annotated endpoint websocket.addEndpoint(DeviceWebSocketServer.class); } } 

DeviceWebSocketServer:

package com.example.websocket; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import java.io.StringReader; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; import com.example.model.Device; import java.util.logging.Level; import java.util.logging.Logger; @ApplicationScoped @ServerEndpoint("/actions") public class DeviceWebSocketServer { @Inject private DeviceSessionHandler sessionHandler; @OnOpen public void open(Session session) { sessionHandler.addSession(session); } @OnClose public void close(Session session) { sessionHandler.removeSession(session); } @OnError public void onError(Throwable error) { Logger.getLogger(DeviceWebSocketServer.class.getName()).log(Level.SEVERE, null, error); } @OnMessage public void handleMessage(String message, Session session) { try (JsonReader reader = Json.createReader(new StringReader(message))) { JsonObject jsonMessage = reader.readObject(); if ("add".equals(jsonMessage.getString("action"))) { Device device = new Device(); device.setName(jsonMessage.getString("name")); device.setDescription(jsonMessage.getString("description")); device.setType(jsonMessage.getString("type")); device.setStatus("Off"); sessionHandler.addDevice(device); } if ("remove".equals(jsonMessage.getString("action"))) { int id = (int) jsonMessage.getInt("id"); sessionHandler.removeDevice(id); } if ("toggle".equals(jsonMessage.getString("action"))) { int id = (int) jsonMessage.getInt("id"); sessionHandler.toggleDevice(id); } } } } 

DeviceSessionHandler:

package com.example.websocket; import javax.enterprise.context.ApplicationScoped; import javax.json.JsonObject; import javax.json.spi.JsonProvider; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.websocket.Session; import com.example.model.Device; @ApplicationScoped public class DeviceSessionHandler { private int deviceId = 0; private final Set<Session> sessions = new HashSet<>(); private final Set<Device> devices = new HashSet<>(); public void addSession(Session session) { sessions.add(session); for (Device device : devices) { JsonObject addMessage = createAddMessage(device); sendToSession(session, addMessage); } } public void removeSession(Session session) { sessions.remove(session); } public List<Device> getDevices() { return new ArrayList<>(devices); } public void addDevice(Device device) { device.setId(deviceId); devices.add(device); deviceId++; JsonObject addMessage = createAddMessage(device); sendToAllConnectedSessions(addMessage); } public void removeDevice(int id) { Device device = getDeviceById(id); if (device != null) { devices.remove(device); JsonProvider provider = JsonProvider.provider(); JsonObject removeMessage = provider.createObjectBuilder() .add("action", "remove") .add("id", id) .build(); sendToAllConnectedSessions(removeMessage); } } public void toggleDevice(int id) { JsonProvider provider = JsonProvider.provider(); Device device = getDeviceById(id); if (device != null) { if ("On".equals(device.getStatus())) { device.setStatus("Off"); } else { device.setStatus("On"); } JsonObject updateDevMessage = provider.createObjectBuilder() .add("action", "toggle") .add("id", device.getId()) .add("status", device.getStatus()) .build(); sendToAllConnectedSessions(updateDevMessage); } } private Device getDeviceById(int id) { for (Device device : devices) { if (device.getId() == id) { return device; } } return null; } private JsonObject createAddMessage(Device device) { JsonProvider provider = JsonProvider.provider(); JsonObject addMessage = provider.createObjectBuilder() .add("action", "add") .add("id", device.getId()) .add("name", device.getName()) .add("type", device.getType()) .add("status", device.getStatus()) .add("description", device.getDescription()) .build(); return addMessage; } private void sendToAllConnectedSessions(JsonObject message) { for (Session session : sessions) { sendToSession(session, message); } } private void sendToSession(Session session, JsonObject message) { try { session.getBasicRemote().sendText(message.toString()); } catch (IOException ex) { sessions.remove(session); Logger.getLogger(DeviceSessionHandler.class.getName()).log(Level.SEVERE, null, ex); } } } 

Dependencies:

<dependencies> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.7</version> </dependency> <dependency> <groupId>org.apache.jena</groupId> <artifactId>jena-arq</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-core</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.8</version> </dependency> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> <version>1.1</version> </dependency><dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>be.tomcools</groupId> <artifactId>dropwizard-websocket-jee7-bundle</artifactId> <version>1.1.0</version> </dependency> </dependencies> 

Error Log:

WARN [2017-08-31 16:55:46,863] org.eclipse.jetty.servlet.ServletHandler: Error for /actions ! java.lang.NoSuchMethodError: org.eclipse.jetty.io.AbstractConnection.<init>(Lorg/eclipse/jetty/io/EndPoint;Ljava/util/concurrent/Executor;Z)V ! at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.<init>(AbstractWebSocketConnection.java:225) ! at org.eclipse.jetty.websocket.server.WebSocketServerConnection.<init>(WebSocketServerConnection.java:41) ! at org.eclipse.jetty.websocket.server.WebSocketServerFactory.upgrade(WebSocketServerFactory.java:520) ! at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:186) ! at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206) ! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) ! at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:34) ! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) ! at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:50) ! at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:44) ! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) ! at org.eclipse.jetty.servlets.CrossOriginFilter.handle(CrossOriginFilter.java:308) ! at org.eclipse.jetty.servlets.CrossOriginFilter.doFilter(CrossOriginFilter.java:262) ! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) ! at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) ! at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174) ! at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) ! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106) ! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) ! at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:240) ! at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:51) ! at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:459) ! at io.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.java:68) ! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:56) ! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:169) ! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) ! at org.eclipse.jetty.server.Server.handle(Server.java:524) ! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319) ! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253) ! at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) ! at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) ! at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) ! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) ! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) ! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) ! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) ! at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) ! at java.lang.Thread.run(Thread.java:745) 0:0:0:0:0:0:0:1 - - [31/ago/2017:16:55:46 +0000] "GET /actions HTTP/1.1" 500 245 "-" "-" 47 

Edited: Added dependencies list.

5
  • How did you compile and build your project? Commented Sep 1, 2017 at 3:57
  • I built using maven package Commented Sep 1, 2017 at 8:21
  • mostly a chance of a dependency missed or conflicting in dependency tree Commented Sep 1, 2017 at 8:23
  • Added the dependencies list to the question. I has using 2 json deserializers because I was lazy to change the websocket example code. Will check out if the error comes from there and report in a bit. Commented Sep 1, 2017 at 9:07
  • I think the error comes from a conflict with jetty and jsr-356 but that should not happen has the dropwizard bundle in use is for specific use of jsr-356... Again, I don't understand enough to pinpoint the exact cause. Any help in what steps I should take next is appreciated. Commented Sep 1, 2017 at 13:46

1 Answer 1

0

Downgraded the dropwizard version I was using to the last reported version in the bundle (0.9.1) and this error is gone (although i have a null pointer exception now. will open a new question about that error).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.