2015-03-21 22 views
6

Ich versuche, eine Verbindung zu einem gesicherten WebSocket mit Jetty (oder einer anderen Bibliothek) herzustellen.Verbinden mit einem gesicherten Websocket

Das Problem ist, ich bekomme einen Fehler "Kein vertrauenswürdiges Zertifikat gefunden". Ich verwende ein selbstsigniertes Zertifikat, das mit keytool erstellt wurde. Was könnte getan werden?

import java.net.URI; 
import java.util.concurrent.Future; 

import org.eclipse.jetty.util.resource.Resource; 
import org.eclipse.jetty.util.ssl.SslContextFactory; 
import org.eclipse.jetty.websocket.api.Session; 
import org.eclipse.jetty.websocket.api.WebSocketAdapter; 
import org.eclipse.jetty.websocket.client.WebSocketClient; 

public class Socket extends WebSocketAdapter{ 

    public static void main(String[] args) { 
     String url = "wss://qa.sockets.stackexchange.com/"; //or "wss://echo.websocket.org" 
     // making sure the the jvm find keystore 
     String JAVASEC="C:/Program Files/Java/jdk1.8.0_25/jre/lib/security/"; 
     System.setProperty("javax.net.ssl.keyStore", JAVASEC+"keystore.jks"); 
     System.setProperty("javax.net.ssl.trustStore", JAVASEC+"cacerts.jks"); 
     System.setProperty("javax.net.ssl.keyStorePassword", "changeit"); 

     System.out.println(System.getProperty("javax.net.ssl.trustStore")); 
     SslContextFactory sslContextFactory = new SslContextFactory(); 
     Resource keyStoreResource = Resource.newResource(Socket.class.getResource("/keystore.jks"));//generated with keytool 
     sslContextFactory.setKeyStoreResource(keyStoreResource); 
     sslContextFactory.setKeyStorePassword("password"); 
     sslContextFactory.setKeyManagerPassword("password"); 
     WebSocketClient client = new WebSocketClient(sslContextFactory); 
     try{ 
      client.start(); 
      Socket socket = new Socket(); 
      Future<Session> fut = client.connect(socket,URI.create(url)); 
      Session session = fut.get(); 
      session.getRemote().sendString("Hello"); 
     } 
     catch (Throwable t){ 
      t.printStackTrace(System.err); 
     } 
    } 


    @Override 
    public void onWebSocketConnect(Session sess){ 
     super.onWebSocketConnect(sess); 
     System.out.println("Socket Connected: " + sess); 
    } 

    @Override 
    public void onWebSocketText(String message){ 
     super.onWebSocketText(message); 
     System.out.println("Received TEXT message: " + message); 
    } 

    @Override 
    public void onWebSocketClose(int statusCode, String reason){ 
     super.onWebSocketClose(statusCode,reason); 
     System.out.println("Socket Closed: [" + statusCode + "] " + reason); 
    } 

    @Override 
    public void onWebSocketError(Throwable cause){ 
     super.onWebSocketError(cause); 
     cause.printStackTrace(System.err); 
    } 
} 

Hier ist ein Versuch, mit Tyrus websocket Client, ich habe keine SSL-Fehler, aber es druckt nichts:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.URI; 
import java.net.URISyntaxException; 

import javax.websocket.ClientEndpointConfig; 
import javax.websocket.CloseReason; 
import javax.websocket.DeploymentException; 
import javax.websocket.Endpoint; 
import javax.websocket.EndpointConfig; 
import javax.websocket.MessageHandler; 
import javax.websocket.Session; 

import org.glassfish.grizzly.ssl.SSLContextConfigurator; 
import org.glassfish.grizzly.ssl.SSLEngineConfigurator; 
import org.glassfish.tyrus.client.ClientManager; 
import org.glassfish.tyrus.container.grizzly.GrizzlyEngine; 

public class ClientWebSocketEndpoint extends Endpoint { 

    public static void main(String[] a) throws IOException{ 

     ClientManager client = ClientManager.createClient(); 

     //System.getProperties().put("javax.net.debug", "all"); 
     final SSLContextConfigurator defaultConfig = new SSLContextConfigurator(); 

     defaultConfig.retrieve(System.getProperties()); 
      // or setup SSLContextConfigurator using its API. 

     SSLEngineConfigurator sslEngineConfigurator = 
      new SSLEngineConfigurator(defaultConfig, true, false, false); 
     client.getProperties().put(GrizzlyEngine.SSL_ENGINE_CONFIGURATOR, 
      sslEngineConfigurator); 
     Session session = null; 
     final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build(); 

     try { 
      session = client.connectToServer(ClientWebSocketEndpoint.class, cec, new URI("wss://qa.sockets.stackexchange.com/"));// or "wss://echo.websocket.org" 

     } catch (DeploymentException | URISyntaxException e) { 
      e.printStackTrace(); 
     } finally { 
      if (session != null && session.isOpen()) 
       session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "Bye")); 

     } 

     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     br.readLine(); 
    } 

    @Override 
    public void onOpen(Session session, EndpointConfig config) { 
     session.addMessageHandler(new MessageHandler.Whole<String>() { 

      @Override 
      public void onMessage(String message) { 
       System.out.println("Received message: "+message); 
      } 
     }); 
     try { 
      session.getBasicRemote().sendText("1-questions-active"); 
      session.getBasicRemote().sendText("155-questions-active"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 

Im Vergleich mit diesem einfachen Code in JS/Knoten

var WebSocket = require('ws') 
    , ws = new WebSocket('wss://qa.sockets.stackexchange.com/');//"wss://echo.websocket.org" 

ws.on('message', function(message) { 
    console.log('received: %s', message); 
}); 
ws.on('open', function() { 
    ws.send('155-questions-active'); 
    ws.send('1-questions-active'); 
}); 
arbeitet

Ich würde mich freuen, einen funktionierenden Websocket-Client in Java zu kennen.

+0

mögliches Duplikat von [Java wird angewiesen, selbstsigniertes SSL-Zertifikat zu akzeptieren] (http://stackoverflow.com/questions/2893819/telling-java-to-accept-self-signed-ssl-certificate) – tinker

+0

@tinker I habe es gerade ausprobiert, bin mit einem browser zu https://qa.sockets.stackexchange.com/ gegangen, habe das zertifikat exportiert, und es in cacerts 'keytool -import ...' importiert und diesen Code nochmal ausgeführt, hab den gleicher Fehler "Kein vertrauenswürdiges Zertifikat gefunden" – caub

+0

Haben Sie es mit einem Trust Store und dem richtigen Passwort ausgeführt? Stellen Sie sicher, dass Ihre JVM den richtigen Trust Store verwendet – tinker

Antwort

12

Es gibt eine viel einfachere Art und Weise, keine Notwendigkeit zu Chaos mit Truststores oder benutzerdefinierten X509TrustManagers oder SSLContexts angepasst.

Verwenden Sie einfach, was SslContextFactory mit schon kommt ...

package jetty.websocket; 

import java.net.URI; 
import java.util.concurrent.Future; 

import org.eclipse.jetty.util.log.Log; 
import org.eclipse.jetty.util.log.Logger; 
import org.eclipse.jetty.util.ssl.SslContextFactory; 
import org.eclipse.jetty.websocket.api.Session; 
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; 
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; 
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; 
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; 
import org.eclipse.jetty.websocket.api.annotations.WebSocket; 
import org.eclipse.jetty.websocket.client.WebSocketClient; 

@WebSocket 
public class SecureClientSocket 
{ 
    private static final Logger LOG = Log.getLogger(SecureClientSocket.class); 

    public static void main(String[] args) 
    { 
     String url = "wss://qa.sockets.stackexchange.com/"; 

     SslContextFactory sslContextFactory = new SslContextFactory(); 
     sslContextFactory.setTrustAll(true); // The magic 

     WebSocketClient client = new WebSocketClient(sslContextFactory); 
     try 
     { 
      client.start(); 
      SecureClientSocket socket = new SecureClientSocket(); 
      Future<Session> fut = client.connect(socket,URI.create(url)); 
      Session session = fut.get(); 
      session.getRemote().sendString("Hello"); 
      session.getRemote().sendString("155-questions-active"); 
     } 
     catch (Throwable t) 
     { 
      LOG.warn(t); 
     } 
    } 

    @OnWebSocketConnect 
    public void onConnect(Session sess) 
    { 
     LOG.info("onConnect({})",sess); 
    } 

    @OnWebSocketClose 
    public void onClose(int statusCode, String reason) 
    { 
     LOG.info("onClose({}, {})", statusCode, reason); 
    } 

    @OnWebSocketError 
    public void onError(Throwable cause) 
    { 
     LOG.warn(cause); 
    } 

    @OnWebSocketMessage 
    public void onMessage(String msg) 
    { 
     LOG.info("onMessage() - {}", msg); 
    } 
} 

Welche Ergebnisse wie diese haben ...

2015-03-26 06:46:34.893:INFO::main: Logging initialized @62ms 
2015-03-26 06:46:35.700:INFO:jw.SecureClientSocket:[email protected]: onConnect(WebSocketSession[websocket=JettyAnnotatedEventDriver[[email protected]],behavior=CLIENT,[email protected]{IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=null],g=Generator[CLIENT,validating],[email protected][ExtensionStack,s=START,c=0,len=0,f=null,[email protected][behavior=CLIENT,maxTextMessageSize=65536,maxTextMessageBufferSize=32768,maxBinaryMessageSize=65536,maxBinaryMessageBufferSize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]},[email protected][batching=true],incoming=JettyAnnotatedEventDriver[[email protected]],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]]) 
2015-03-26 06:46:39.464:INFO:jw.SecureClientSocket:[email protected]: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"math.stackexchange.com\",\"id\":1207542,\"titleEncodedFancy\":\"Do we have this type of integral expression of Bessel function of the first kind?\",\"bodySummary\":\"Let $z=\\\\lambda+i\\\\mu$ with $\\\\mu&gt;0$. Then for any $r&gt;0$, $k=1,2,3, \\\\cdots$. Do we have the following identity\\n$$\\n\\\\int_{r}^{\\\\infty}{\\\\frac{t}{\\\\sqrt{t^2-r^2}}(\\\\frac{1}{t}\\\\frac{d}{dt})^k ...\",\"tags\":[\"analysis\",\"reference-request\",\"special-functions\"],\"lastActivityDate\":1427377599,\"url\":\"http://math.stackexchange.com/questions/1207542/do-we-have-this-type-of-integral-expression-of-bessel-function-of-the-first-kind\",\"ownerUrl\":\"http://math.stackexchange.com/users/37742/sun\",\"ownerDisplayName\":\"sun\",\"apiSiteParameter\":\"math\"}"} 
2015-03-26 06:46:41.469:INFO:jw.SecureClientSocket:[email protected]: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"drupal.stackexchange.com\",\"id\":152924,\"titleEncodedFancy\":\"Features can export everything?\",\"bodySummary\":\"Built all blocks, menu, taxonomies, view etc in Drupal CMS on localhost machine, but I need to export everything to the live server. Is it possible to use features or just export sql?\\n\",\"tags\":[\"theming\"],\"lastActivityDate\":1427377601,\"url\":\"http://drupal.stackexchange.com/questions/152924/features-can-export-everything\",\"ownerUrl\":\"http://drupal.stackexchange.com/users/34551/joe\",\"ownerDisplayName\":\"joe\",\"apiSiteParameter\":\"drupal\"}"} 
2015-03-26 06:46:44.034:INFO:jw.SecureClientSocket:[email protected]: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"wordpress.stackexchange.com\",\"id\":182350,\"titleEncodedFancy\":\"Create page from plugin, but have it completely hidden\",\"bodySummary\":\"I need to have a plugin create a page that is publicly accessible, but does NOT show up in the admin section anywhere, and cannot be deleted or modified.\\n\\nI thought maybe figuring out a way to have a ...\",\"tags\":[\"plugins\",\"pages\"],\"lastActivityDate\":1427377603,\"url\":\"http://wordpress.stackexchange.com/questions/182350/create-page-from-plugin-but-have-it-completely-hidden\",\"ownerUrl\":\"http://wordpress.stackexchange.com/users/45132/joel-worsham\",\"ownerDisplayName\":\"Joel Worsham\",\"apiSiteParameter\":\"wordpress\"}"} 
+0

Ich werde dein code testen. Vielen Dank dafür! –

2

Nun, ich habe versucht, mit Ihrem Code zu replizieren Problem ohne Erfolg (Holen Sie sich das Zertifikat, importieren Sie es mit dem Befehl keytool und führen Sie den Code aus). meine Ausgabe ist so.

2015-03-22 23:03:16.192:INFO::main: Logging initialized @503ms 
Socket Connected:WebSocketSession[websocket=JettyListenerEventDriver[com.ivan.Main],behavior=CLIENT,connection=WebSocketClient[email protected]{IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=null],g=Generator[CLIENT,validating],[email protected][ExtensionStack,s=START,c=0,len=0,f=null,[email protected][behavior=CLIENT,maxTextMessageSize=65536,maxTextMessageBufferSize=32768,maxBinaryMessageSize=65536,maxBinaryMessageBufferSize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]},[email protected][batching=true],incoming=JettyListenerEventDriver[com.ivan.Main],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]] 
Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"cogsci.stackexchange.com\",\"id\":9404,\"titleEncodedFancy\":\"What&#39;s the difference between repetition suppression and habituation?\",\"bodySummary\":\"Neural repetition suppression seems to be describing behavioral habituation on a neuronal level. What's the difference between these two terms?\\n\",\"tags\":[\"cognitive-neuroscience\",\"terminology\",\"conditioning\",\"perceptual-learning\"],\"lastActivityDate\":1427036607,\"url\":\"http://cogsci.stackexchange.com/questions/9404/whats-the-difference-between-repetition-suppression-and-habituation\",\"ownerUrl\":\"http://cogsci.stackexchange.com/users/7569/recursive-farts\",\"ownerDisplayName\":\"RECURSIVE FARTS\",\"apiSiteParameter\":\"cogsci\"}"} 
Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"mathematica.stackexchange.com\",\"id\":77933,\"titleEncodedFancy\":\"FunctionDomain doesn&#39;t work with If\",\"bodySummary\":\"When I call FunctionDomain for function defined by formule with If, for example \\n\\nf[x_]:=If[x&lt;0, x, x^3], \\n\\nI get \\\"Unable to find the domain with the available methods\\\". What should I do to get a ...\",\"tags\":[\"functions\"],\"lastActivityDate\":1427036609,\"url\":\"http://mathematica.stackexchange.com/questions/77933/functiondomain-doesnt-work-with-if\",\"ownerUrl\":\"http://mathematica.stackexchange.com/users/27150/adolzi\",\"ownerDisplayName\":\"adolzi\",\"apiSiteParameter\":\"mathematica\"}"} 
Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"serverfault.com\",\"id\":677390,\"titleEncodedFancy\":\"Smart Array E200i battery on 350ML did not fix the warning message (battery failure)\",\"bodySummary\":\"I have got this warning message on the System Management in a Proliant server 350ML G5.\\n\\nDegraded Accelerator\\nName Value\\nStatus: Temporarily Disabled\\nError Code: Cache Disabled Low Batteries\\nSerial ...\",\"tags\":[\"hp-proliant\",\"hp-smart-array\"],\"lastActivityDate\":1427036609,\"url\":\"http://serverfault.com/questions/677390/smart-array-e200i-battery-on-350ml-did-not-fix-the-warning-message-battery-fail\",\"ownerUrl\":\"http://serverfault.com/users/164557/dlopezgonzalez\",\"ownerDisplayName\":\"dlopezgonzalez\",\"apiSiteParameter\":\"serverfault\"}"} 
Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"askubuntu.com\",\"id\":599889,\"titleEncodedFancy\":\"Is downgrading back to 14.04 from 14.10 possible?\",\"bodySummary\":\"I am using Ubuntu 14.10 alongside Windows 7 and I want to degrade to 14.04. I made a bootable pendrive using Universal USB Installer and seems like the pendrive is working fine. On the Installer Boot ...\",\"tags\":[\"14.04\",\"boot\",\"upgrade\",\"downgrade\"],\"lastActivityDate\":1427036610,\"url\":\"http://askubuntu.com/questions/599889/is-downgrading-back-to-14-04-from-14-10-possible\",\"ownerUrl\":\"http://askubuntu.com/users/374332/pkj\",\"ownerDisplayName\":\"pkj\",\"apiSiteParameter\":\"askubuntu\"}"} 
Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"superuser.com\",\"id\":814765,\"titleEncodedFancy\":\"External Harddrive Shutting Off and On Every So Often While Listening to Music\",\"bodySummary\":\"I am always listening to music on my PC (always via VLC Player) and every so often - maybe once every 2 songs, sometimes more frequently- the music stops playing (VLC's buffer/progress bar stops ...\",\"tags\":[\"hard-drive\",\"power\",\"external\"],\"lastActivityDate\":1427036610,\"url\":\"http://superuser.com/questions/814765/external-harddrive-shutting-off-and-on-every-so-often-while-listening-to-music\",\"ownerUrl\":\"http://superuser.com/users/338547/supercookie47\",\"ownerDisplayName\":\"SuperCookie47\",\"apiSiteParameter\":\"superuser\"}"} 
Received TEXT message: {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"math.stackexchange.com\",\"id\":1200778,\"titleEncodedFancy\":\"Continuity of a piecewise function at a specific point\",\"bodySummary\":\"I am having trouble proving the following function is not continuous at $x = 0$ using a formal definition of continuity.\\n\\n$\\nf(x) = \\\\left\\\\{\\n \\\\begin{array}{lr}\\n \\\\sin(\\\\frac{1}{x}) &amp; : x \\\\neq 0\\\\\\\\\\n ...\",\"tags\":[\"real-analysis\",\"functions\",\"continuity\",\"epsilon-delta\"],\"lastActivityDate\":1427036612,\"url\":\"http://math.stackexchange.com/questions/1200778/continuity-of-a-piecewise-function-at-a-specific-point\",\"ownerUrl\":\"http://math.stackexchange.com/users/222744/george\",\"ownerDisplayName\":\"George\",\"apiSiteParameter\":\"math\"}"} 

Also ich denke, wenn man eine laufende Web-Socket-Client in Java wollen, nehme ich Sie einfach alle Zertifikat wie die Verbindung akzeptieren konnte, dass @tinker Sie hat gab.

Der Code sollte so sein. vielleicht könntest du es versuchen und sehen, was an deiner Stelle passiert.

import java.net.URI; 
import java.security.cert.X509Certificate; 
import java.util.concurrent.Future; 

import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

import org.eclipse.jetty.util.ssl.SslContextFactory; 
import org.eclipse.jetty.websocket.api.Session; 
import org.eclipse.jetty.websocket.api.WebSocketAdapter; 
import org.eclipse.jetty.websocket.client.WebSocketClient; 

public class Main extends WebSocketAdapter { 

    public static void main(String[] args) { 
    String url = "wss://qa.sockets.stackexchange.com/"; // or 
          // "wss://echo.websocket.org" 
SslContextFactory sslContextFactory = new SslContextFactory(); 
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { 
    public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
    return new X509Certificate[0]; 
    } 

    public void checkClientTrusted(
     java.security.cert.X509Certificate[] certs, String authType) { 
    } 

    public void checkServerTrusted(
     java.security.cert.X509Certificate[] certs, String authType) { 
    } 
} }; 
try { 
    SSLContext sc = SSLContext.getInstance("SSL"); 
    sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
    sslContextFactory.setSslContext(sc); 
    WebSocketClient client = new WebSocketClient(sslContextFactory); 

    client.start(); 
    Future<Session> fut = client.connect(new Main(), URI.create(url)); 
    Session session = fut.get(); 
    session.getRemote().sendString("Hello"); 
    session.getRemote().sendString("155-questions-active"); 
} catch (Throwable t) { 
    t.printStackTrace(System.err); 
} 
} 

@Override 
public void onWebSocketConnect(Session sess) { 
super.onWebSocketConnect(sess); 
System.out.println("Socket Connected: " + sess); 
} 

@Override 
public void onWebSocketText(String message) { 
super.onWebSocketText(message); 
System.out.println("Received TEXT message: " + message); 
} 

@Override 
public void onWebSocketClose(int statusCode, String reason) { 
super.onWebSocketClose(statusCode, reason); 
System.out.println("Socket Closed: [" + statusCode + "] " + reason); 
} 

@Override 
public void onWebSocketError(Throwable cause) { 
super.onWebSocketError(cause); 
cause.printStackTrace(System.err); 
} 
} 
+0

herzlichen glückwunsch, wie hast du herausgefunden? – caub

+0

gut, in meiner bisherigen erfahrung, ich habe diese art von problem in meinem job. trotzdem froh könnte helfen;) –

1

Hier ist mein Tyrus-Java-Client mit Stummel, die ich verwendet, um eine Verbindung zu meinem Jetty 9.3.6 Server HTTPS mit einem selbst signierten Zertifikat (angepasst von Tyrus websocket client, Abschnitt 8.1) ausgeführt wird:

  client = ClientManager.createClient(); 

      //System.getProperties().put("javax.net.debug", "all"); // Useful for debugging SSL interaction 
      // The keystore in the next two lines is the same keystore you used for running the server, 
      // likely in ${jetty.base}/etc/keystore 
      System.getProperties().put(SSLContextConfigurator.KEY_STORE_FILE, "/tmp/keystore"); 
      System.getProperties().put(SSLContextConfigurator.TRUST_STORE_FILE, "/tmp/keystore"); 
      // The following two passwords are what you used for your self-signed cert 
      System.getProperties().put(SSLContextConfigurator.KEY_STORE_PASSWORD, "HumanReadablePassword"); 
      System.getProperties().put(SSLContextConfigurator.TRUST_STORE_PASSWORD, "HumanReadablePassword"); 
      final SSLContextConfigurator defaultConfig = new SSLContextConfigurator(); 

      defaultConfig.retrieve(System.getProperties()); 
      // or setup SSLContextConfigurator using its API. 

      SSLEngineConfigurator sslEngineConfigurator = new SSLEngineConfigurator(defaultConfig, true, false, false); 
      client.getProperties().put(GrizzlyEngine.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator); 
      client.connectToServer(sillyWebSocketClient , ClientEndpointConfig.Builder.create().build(), 
            new URI("wss://localhost:8443/sillyWebSocketServer/echo")); 
      System.out.println ("Connected .... "); 

Wo SillyWebSocketClient sillyWebSocketClient erweitert javax.websocket.Endpoint.

ich eine Java 8/Gradle 2.7 Umgebung benutze und meine build.gradle sieht wie folgt aus:

apply plugin: 'java' 

repositories { 
    mavenCentral() 
} 

dependencies { 
     compile 'javax:javaee-api:7.0' 
     compile 'org.glassfish.grizzly:grizzly-core:2.3.23' 
     compile 'org.glassfish.tyrus:tyrus-container-grizzly:1.2.1' 
     compile 'org.glassfish.tyrus:tyrus-client:1.6' 
     compile 'javax.websocket:javax.websocket-client-api:1.1' 
} 

Hoffnung, das hilft.