Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8180155

WebSocket secure connection get stuck after onOpen

    XMLWordPrintable

Details

    • b173
    • Verified

    Backports

      Description

        This looks to be broken by JDK-8179021.

        It can be reproduced with a simple connect, communicate round trip with wss scheme. Please refer the test below. Keystore will be attached.
        If comment out ssl context and use ws://xxx url, it works well.

        import static java.lang.System.out;

        import java.io.FileInputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.net.URI;
        import java.net.URISyntaxException;
        import java.nio.ByteBuffer;
        import java.nio.file.Path;
        import java.nio.file.Paths;
        import java.security.KeyStore;
        import java.util.concurrent.CompletionStage;
        import java.util.concurrent.ExecutionException;

        import javax.net.ssl.KeyManagerFactory;
        import javax.net.ssl.SSLContext;
        import javax.net.ssl.TrustManagerFactory;

        import jdk.incubator.http.HttpClient;
        import jdk.incubator.http.WebSocket;
        import jdk.incubator.http.WebSocket.Listener;
        import jdk.incubator.http.WebSocket.MessagePart;

        public class WSSTest {

            private static final String ALGORITHM = "SunX509";
            private static final char[] PASSWORD = "changeit".toCharArray();

            public static void main(String[] args) throws URISyntaxException, InterruptedException, ExecutionException, IOException {
                Listener l = new Listener() {

                    @Override
                    public CompletionStage<?> onClose(WebSocket arg0, int arg1,
                            String arg2) {
                        System.out.println("onClose");
                        return Listener.super.onClose(arg0, arg1, arg2);
                    }

                    @Override
                    public void onOpen(WebSocket arg0) {
                        System.out.println("onOpen");
                        Listener.super.onOpen(arg0);
                    }

                    @Override
                    public CompletionStage<?> onText(WebSocket arg0, CharSequence text,
                            MessagePart arg2) {
                        System.out.println("onText:" + text);
                        return Listener.super.onText(arg0, text, arg2);
                    }

                    @Override
                    public void onError(WebSocket webSocket, Throwable error) {
                        System.err.println("onError");
                        System.err.println(error);
                    }
                };

                URI uri = new URI(
                        "wss url"
                        );
                WebSocket ws;
                HttpClient client = HttpClient.newBuilder()
                        .sslContext(sslContext())
                        .build();
                ws = client.newWebSocketBuilder(uri, l).buildAsync().get();

                out.println(" connected ");
                ws.sendText("Hello!", true);
                ws.sendClose(WebSocket.NORMAL_CLOSURE, "Normal Close").get();
                out.println(" closed");
                ws.abort();
            }

            /** Gets a SSLContext for secure connections. */
            public static SSLContext sslContext() {
                SSLContext sslContext = null;
                Path keyPath = Paths.get(".", "keystore.jks");
                try (InputStream keyStoreIn = new FileInputStream(
                        keyPath.toFile())) {
                    KeyStore keyStore = KeyStore.getInstance("JKS");
                    keyStore.load(keyStoreIn, PASSWORD);

                    KeyManagerFactory km = KeyManagerFactory.getInstance(ALGORITHM);
                    km.init(keyStore, PASSWORD);

                    TrustManagerFactory tm = TrustManagerFactory
                            .getInstance(ALGORITHM);
                    tm.init(keyStore);

                    sslContext = SSLContext.getInstance("TLS");
                    sslContext.init(km.getKeyManagers(), tm.getTrustManagers(),
                            null);
                    System.out.println("SSLContext initialized");
                } catch (Exception e) {
                    System.err.println("Failed to get SSLContext");
                    throw new RuntimeException(e);
                }
                return sslContext;
            }
        }

        Please refer to the jstack output attached. It seems websocket is stuck at onOpen
        "HttpClient_worker" #14 daemon prio=5 os_prio=0 tid=0x0000000036d7c800 nid=0x1804 runnable [0x0000000037ece000]
           java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.SocketDispatcher.read0(java.base@9-ea/Native Method)
        at sun.nio.ch.SocketDispatcher.read(java.base@9-ea/SocketDispatcher.java:43)
        at sun.nio.ch.IOUtil.readIntoNativeBuffer(java.base@9-ea/IOUtil.java:223)
        at sun.nio.ch.IOUtil.read(java.base@9-ea/IOUtil.java:197)
        at sun.nio.ch.SocketChannelImpl.read(java.base@9-ea/SocketChannelImpl.java:382)
        - locked <0x00000006d1365a38> (a java.lang.Object)
        at jdk.incubator.http.SSLDelegate$EngineWrapper.recvAndUnwrap(jdk.incubator.httpclient@9-ea/SSLDelegate.java:280)
        - locked <0x00000006d136fa00> (a java.lang.Object)
        at jdk.incubator.http.SSLDelegate.recvData(jdk.incubator.httpclient@9-ea/SSLDelegate.java:362)
        at jdk.incubator.http.SSLConnection.readImpl(jdk.incubator.httpclient@9-ea/SSLConnection.java:179)
        at jdk.incubator.http.SSLConnection.readImpl(jdk.incubator.httpclient@9-ea/SSLConnection.java:166)
        at jdk.incubator.http.HttpConnection.read(jdk.incubator.httpclient@9-ea/HttpConnection.java:331)
        at jdk.incubator.http.RawChannelImpl.read(jdk.incubator.httpclient@9-ea/RawChannelImpl.java:114)
        at jdk.incubator.http.internal.websocket.Receiver.readData(jdk.incubator.httpclient@9-ea/Receiver.java:142)
        at jdk.incubator.http.internal.websocket.Receiver.pushOnce(jdk.incubator.httpclient@9-ea/Receiver.java:126)
        at jdk.incubator.http.internal.websocket.Receiver.pushContinuously(jdk.incubator.httpclient@9-ea/Receiver.java:121)
        at jdk.incubator.http.internal.websocket.Receiver$$Lambda$71/663162477.run(jdk.incubator.httpclient@9-ea/Unknown Source)
        at jdk.incubator.http.internal.websocket.CooperativeHandler.lambda$asyncOf$0(jdk.incubator.httpclient@9-ea/CooperativeHandler.java:204)
        at jdk.incubator.http.internal.websocket.CooperativeHandler$$Lambda$72/1892324013.accept(jdk.incubator.httpclient@9-ea/Unknown Source)
        at jdk.incubator.http.internal.websocket.CooperativeHandler.handle(jdk.incubator.httpclient@9-ea/CooperativeHandler.java:144)
        at jdk.incubator.http.internal.websocket.Receiver.request(jdk.incubator.httpclient@9-ea/Receiver.java:101)
        at jdk.incubator.http.internal.websocket.WebSocketImpl.request(jdk.incubator.httpclient@9-ea/WebSocketImpl.java:363)
        at jdk.incubator.http.WebSocket$Listener.onOpen(jdk.incubator.httpclient@9-ea/WebSocket.java:307)
        at jdk.incubator.http.internal.websocket.WebSocketImpl.signalOpen(jdk.incubator.httpclient@9-ea/WebSocketImpl.java:162)
        - locked <0x00000006d0c9edb8> (a java.lang.Object)
        at jdk.incubator.http.internal.websocket.WebSocketImpl.lambda$newInstanceAsync$0(jdk.incubator.httpclient@9-ea/WebSocketImpl.java:116)
        at jdk.incubator.http.internal.websocket.WebSocketImpl$$Lambda$28/682376643.apply(jdk.incubator.httpclient@9-ea/Unknown Source)
        at java.util.concurrent.CompletableFuture$UniApply.tryFire(java.base@9-ea/CompletableFuture.java:642)
        at java.util.concurrent.CompletableFuture.postComplete(java.base@9-ea/CompletableFuture.java:506)
        at java.util.concurrent.CompletableFuture.complete(java.base@9-ea/CompletableFuture.java:2073)
        at jdk.incubator.http.ResponseProcessors$NullProcessor.onComplete(jdk.incubator.httpclient@9-ea/ResponseProcessors.java:336)
        at jdk.incubator.http.BlockingPushPublisher.acceptData(jdk.incubator.httpclient@9-ea/BlockingPushPublisher.java:65)
        at jdk.incubator.http.AbstractPushPublisher.consume(jdk.incubator.httpclient@9-ea/AbstractPushPublisher.java:51)
        at jdk.incubator.http.AbstractPushPublisher$$Lambda$67/1278626421.accept(jdk.incubator.httpclient@9-ea/Unknown Source)
        at jdk.incubator.http.ResponseContent.pushBodyFixed(jdk.incubator.httpclient@9-ea/ResponseContent.java:290)
        at jdk.incubator.http.ResponseContent.pushBody(jdk.incubator.httpclient@9-ea/ResponseContent.java:112)
        at jdk.incubator.http.Http1Response.lambda$readBody$2(jdk.incubator.httpclient@9-ea/Http1Response.java:157)
        at jdk.incubator.http.Http1Response$$Lambda$65/808773358.run(jdk.incubator.httpclient@9-ea/Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@9-ea/ThreadPoolExecutor.java:1161)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@9-ea/ThreadPoolExecutor.java:635)
        at java.lang.Thread.run(java.base@9-ea/Thread.java:844)

        Attachments

          Issue Links

            Activity

              People

                prappo Pavel Rappo
                xiaofeya Xiaofeng Yang
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: