Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetty WebSocketClientSelectorManager - Connection Failed java.io.IOException: Cannot init SSL

I apologize up front for all of the code but I'm confused about why this same code seemingly worked before but is not now.

I have a simple jetty WebSockets client and I get the error in the title. The funny thing about this is I have an HTML file with javascript to exercise the same SSL server and it works fine.

Internet searches haven't turned up much as it relates to this error.

According to the jetty source code, there is no SSL context:

        if ("wss".equalsIgnoreCase(scheme))
        {
            // Encrypted "wss://"
            SslContextFactory sslContextFactory = getSslContextFactory();
            if (sslContextFactory != null)
            {
                SSLEngine engine = newSSLEngine(sslContextFactory,channel);
                SslConnection sslConnection = new SslConnection(bufferPool,getExecutor(),endPoint,engine);
                sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
                EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();

                Connection connection = newUpgradeConnection(channel,sslEndPoint,connectPromise);
                sslEndPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
                sslEndPoint.setConnection(connection);
                return sslConnection;
            }
            else
            {
                throw new IOException("Cannot init SSL");
            }
        }
        else
        {
            // Standard "ws://"
            endPoint.setIdleTimeout(connectPromise.getDriver().getPolicy().getIdleTimeout());
            return newUpgradeConnection(channel,endPoint,connectPromise);
        }

Here is the traceback from the execution run:

20:32:15.560 [main] INFO  c.d.e.w.EspClientMain - client connected, waiting for close
20:32:15.626 [WebSocketClient@841038702-14] DEBUG o.e.j.i.SelectorManager - Queued change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Connect@7703d828
20:32:15.627 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Selector loop woken up from select, 0/0 selected
20:32:15.628 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Running change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Connect@7703d828
20:32:15.629 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Selector loop waiting on select
20:32:15.630 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Selector loop woken up from select, 1/1 selected
20:32:15.636 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.w.c.i.WebSocketClientSelectorManager - newEndPoint(java.nio.channels.SocketChannel[connected local=/10.214.156.230:39311 remote=node.dj2.dfdev.biz/10.214.156.230:8443], org.eclipse.jetty.io.SelectorManager$ManagedSelector@36971840 keys=1 selected=1, sun.nio.ch.SelectionKeyImpl@2c21a48f)
20:32:15.648 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.AbstractEndPoint - onOpen SelectChannelEndPoint@2029c7d5{node.dj2.dfdev.biz/10.214.156.230:8443<->39311,Open,in,out,-,-,300000,null}{io=0,kio=0,kro=8}
20:32:15.648 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.IdleTimeout - SelectChannelEndPoint@2029c7d5{node.dj2.dfdev.biz/10.214.156.230:8443<->39311,Open,in,out,-,-,300000,null}{io=0,kio=0,kro=8} idle timeout check, elapsed: 6 ms, remaining: 299994 ms
20:32:15.649 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.w.c.i.WebSocketClientSelectorManager - newConnection(java.nio.channels.SocketChannel[connected local=/10.214.156.230:39311 remote=node.dj2.dfdev.biz/10.214.156.230:8443],SelectChannelEndPoint@2029c7d5{node.dj2.dfdev.biz/10.214.156.230:8443<->39311,Open,in,out,-,-,300000,null}{io=0,kio=0,kro=8},FutureCallback@7b93372{false,false,null})
20:32:15.654 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] INFO  c.d.e.w.EspClientMain$EspClient - unexpected websockets exception: {}
java.io.IOException: Cannot init SSL
    at org.eclipse.jetty.websocket.client.io.WebSocketClientSelectorManager.newConnection(WebSocketClientSelectorManager.java:96) ~[datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.createEndPoint(SelectorManager.java:735) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.processConnect(SelectorManager.java:676) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.processKey(SelectorManager.java:640) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.select(SelectorManager.java:607) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.run(SelectorManager.java:545) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.util.thread.NonBlockingThread.run(NonBlockingThread.java:52) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:540) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_71]

My source that creates the connection is pretty simple and seems to follow the examples:

// Run forever and recover lost server connections
while (true) {
  WebSocketClient client = new WebSocketClient();
  EspClient socket = new EspClient();
  try {
    logger.info("starting client");
    client.start();
    logger.info("client started");
    URI espServerURI = new URI(espURI);
    logger.info("requesting WebSockets upgrade");
    ClientUpgradeRequest request = new ClientUpgradeRequest();
    logger.info("WebSockets upgrade complete, connecting");
    client.connect(socket, espServerURI, request);
    logger.info("client connected, waiting for close");

    try {
      socket.awaitClose();
    } catch (InterruptedException e) {
      logger.error("sleep interrupted ...", e);
    }
  } catch (Throwable t) {
    logger.error("could not connect to {}: {}", espURI, t);
    try {
      Thread.sleep((long)(10 * DateTimeConstants.MILLIS_PER_SECOND));
    } catch (Exception e) {
      logger.error("sleep interrupted ...", e);
    }
  } finally {
    try {
      logger.error("unexpected ESP Server termination.  Retrying connection: {}", espURI);
      client.stop();
      Thread.sleep((long)(10 * DateTimeConstants.MILLIS_PER_SECOND));
    } catch (Exception e) {
      logger.error("exception stopping the ESP client: {}", e);
    }
  }
}

The client class is garden variety:

      /**
       * The Emerge ESP WebSockets Client
       */
      public static class EspClient extends WebSocketAdapter {
    private Logger logger = LoggerFactory.getLogger(EspClient.class);
    private final String pingMessage = "I am still here";
    private final ByteBuffer pingBuffer = ByteBuffer.wrap(pingMessage.getBytes());

    private final CountDownLatch closeLatch;

    // Setup the JMS queues
    private static AbstractApplicationContext context =
        new ClassPathXmlApplicationContext("applicationContext.xml");
    private static JmsConnector jmsEspConnection =
        (JmsConnector) context.getBean("JmsEspMessageBean");

    /**
     * Setup the synchronization
     */
    public EspClient() {
      this.closeLatch = new CountDownLatch(1);
    }

    /**
     * Synchronizes on the countdown latch.
     */
    public void awaitClose() throws InterruptedException {
      this.closeLatch.await();
    }

    @Override
    public void onWebSocketClose(int statusCode, String reason) {
      logger.error("ESP Server session closed: {}, {}", statusCode, reason);
      espSession = null;
      this.closeLatch.countDown();
    }

    @Override
    public void onWebSocketConnect(Session session) {
      logger.info("Connected: {}", session);
      espSession = session;
      readAndSendMessage();
    }

    @Override
    public void onWebSocketError(Throwable cause) {
      logger.info("unexpected websockets exception: {}", cause);
      espSession = null;
    }

    @Override
    public void onWebSocketBinary(byte[] payload, int offset, int len) {
      logger.info("unexpected binary message received");
    }

    @Override
    public void onWebSocketText(String message) {
      if (message != null) {
        logger.info("received ESP Server response: {}", message);
      }
    }
    /**
     * Reads a message from the ESP queue and sends it to the ESP server.
     */
    private void readAndSendMessage() {
      while (espSession != null) {
        String message = jmsEspConnection.receiveTextMessage((long)(4 * DateTimeConstants.MILLIS_PER_MINUTE));
        if (message != null) {
          logger.info("read message: {}", message);
          sendMessage(message);
        } else {
          logger.info("no message available, sending keepalive message");
          try {
            espSession.getRemote().sendPing(pingBuffer);
          } catch (IOException e) {
            logger.error("error sending keepalive message to ESP Server: {}", e);
          }
        }
      }
      logger.error("ESP Server connection lost");
    }

    /**
     * Sends a message to the ESP server.
     */
    private void sendMessage(String message) {
      if (espSession != null) {
        try {
          espSession.getRemote().sendString(message);
        } catch (Exception e) {
          logger.error("error sending sensor message to ESP Server: {}", e);
          espSession = null;
        }
      }
    }
  }
like image 539
John Edwards Avatar asked Dec 08 '22 03:12

John Edwards


1 Answers

You need to provide an SslContextFactory in your constructor.

aka:

SslContextFactory ssl = new SslContextFactory();
// Configure ssl for your client here, such as
// what ciphers and protocols are available,
// what client certificates to use,
// what CA's you want to validate against,
// what your blacklist behavior is,
// your truststore location and access,
// your keystore location and access,
// caching, CRL, OCSP, renegotiation, etc ...

WebSocketClient client = new WebSocketClient(ssl);
like image 170
Joakim Erdfelt Avatar answered Dec 31 '22 15:12

Joakim Erdfelt