2017-08-31 82 views
0

我使用Dropwizard一個REST服務器和dropwizard-的WebSocket-jee7束,使WebSockets的。
對於WebSocket的服務器我用this example
測試websocket服務器獨立工作正常,但與Dropwizard結合使用時,當客戶端嘗試連接(到ws:// localhost:port/actions)時,它會得到500內部服務器錯誤(下面的錯誤日誌)。
我猜有一些損壞或丟失的配置,但我不明白我們在哪裏。的NoSuchMethodError使用dropwizard的WebSocket jee7捆綁服務器

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> 
    <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> 

錯誤日誌:

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 

編輯:新增的依賴列表。

+0

你是怎麼編譯和構建你的項目? – nullpointer

+0

我建立了使用maven包 – wmw301

+0

大多依賴的機會,錯過或依賴關係樹 – nullpointer

回答

0

降級我用的是dropwizard版本的軟件包(0.9.1)的最後一次報告版本,這個錯誤已經一去不復返了(雖然我現在有一個空指針異常。將打開有關錯誤的新問題)。