Closed
Description
Prashant Deva opened SPR-14721 and commented
To reproduce:
Keep the websocket client running and shutdown the server.
Here is the setup and stop code -
class MyWS {
void setup() throws ExecutionException, InterruptedException
{
WebSocketContainer webSocketContainer = new MyContainerProvider().create();
List<Transport> transports = new ArrayList<Transport>(1);
transports.add(new WebSocketTransport(new StandardWebSocketClient(webSocketContainer)));
SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.setMessageCodec(new StringMessageCodec());
stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new StringMessageConverter());
stompClient.start();
stompClient.connect(WS_URL, new MyStompSessionHandler());
}
void stop()
{
StompSession stompSession = this.stompSession;
if(stompSession!=null)
{
try
{
if(stompSession.isConnected())
{
stompSession.disconnect();
Log.trace("Disconnecting from websocket");
}
} catch (Exception e)
{
Log.debug("error disconnecting", e);
}
this.stompSession = null;
}
}
private class MyStompSessionHandler extends StompSessionHandlerAdapter
{
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders)
{
MyWS.this.stompSession = session;
}
@Override
public void handleFrame(StompHeaders headers, Object payload)
{
super.handleFrame(headers, payload);
}
@Override
public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception)
{
Log.debug("Exception in realtime socket", exception);
}
@Override
public void handleTransportError(StompSession session, Throwable exception)
{
MyWS.this.stop();
}
}
}
Here is the exception:
2016-09-15 09:48:25,909 [Grizzly(1)] DEBUG - error disconnecting
java.com.chronon.apm.libs.org.springframework.messaging.MessageDeliveryException: nested exception is java.lang.IllegalStateException: WebSocketClientSockJsSession[id='1f1aafad087b4cc78047f42b47b2ea3f, url=http://127.0.0.1:8082/wsgame] is not open, current state=CLOSED
at java.com.chronon.apm.libs.org.springframework.messaging.simp.stomp.DefaultStompSession.execute(DefaultStompSession.java:277)
at java.com.chronon.apm.libs.org.springframework.messaging.simp.stomp.DefaultStompSession.disconnect(DefaultStompSession.java:326)
at java.com.chronon.apm.realtime.SpringWS.stop(SpringWS.java:88)
at java.com.chronon.apm.realtime.SpringWS$MyStompSessionHandler.handleTransportError(SpringWS.java:190)
at java.com.chronon.apm.libs.org.springframework.messaging.simp.stomp.DefaultStompSession.handleFailure(DefaultStompSession.java:444)
at java.com.chronon.apm.libs.org.springframework.messaging.simp.stomp.DefaultStompSession.afterConnectionClosed(DefaultStompSession.java:459)
at java.com.chronon.apm.libs.org.springframework.web.socket.messaging.WebSocketStompClient$WebSocketTcpConnectionHandlerAdapter.afterConnectionClosed(WebSocketStompClient.java:354)
at java.com.chronon.apm.libs.org.springframework.web.socket.sockjs.client.AbstractClientSockJsSession.afterTransportClosed(AbstractClientSockJsSession.java:321)
at java.com.chronon.apm.libs.org.springframework.web.socket.sockjs.client.WebSocketTransport$ClientSockJsWebSocketHandler.afterConnectionClosed(WebSocketTransport.java:172)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.onClose(StandardWebSocketHandlerAdapter.java:141)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusEndpointWrapper.onClose(TyrusEndpointWrapper.java:1259)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusWebSocket.onClose(TyrusWebSocket.java:130)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.ProtocolHandler.close(ProtocolHandler.java:469)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusWebSocket.close(TyrusWebSocket.java:264)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusWebSocket.close(TyrusWebSocket.java:274)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusRemoteEndpoint.close(TyrusRemoteEndpoint.java:495)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusSession.close(TyrusSession.java:233)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.standard.StandardWebSocketSession.closeInternal(StandardWebSocketSession.java:217)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.AbstractWebSocketSession.close(AbstractWebSocketSession.java:139)
at java.com.chronon.apm.libs.org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.tryCloseWithError(ExceptionWebSocketHandlerDecorator.java:94)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:113)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:42)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:81)
at java.com.chronon.apm.libs.org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:78)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusSession.notifyMessageHandlers(TyrusSession.java:576)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusEndpointWrapper.onMessage(TyrusEndpointWrapper.java:879)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.TyrusWebSocket.onMessage(TyrusWebSocket.java:216)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.frame.TextFrame.respond(TextFrame.java:139)
at java.com.chronon.apm.libs.org.glassfish.tyrus.core.ProtocolHandler.process(ProtocolHandler.java:807)
at java.com.chronon.apm.libs.org.glassfish.tyrus.client.TyrusClientEngine$TyrusReadHandler.handle(TyrusClientEngine.java:747)
at java.com.chronon.apm.libs.org.glassfish.tyrus.container.grizzly.client.GrizzlyClientFilter$ProcessTask.execute(GrizzlyClientFilter.java:476)
at java.com.chronon.apm.libs.org.glassfish.tyrus.container.grizzly.client.TaskProcessor.processTask(TaskProcessor.java:114)
at java.com.chronon.apm.libs.org.glassfish.tyrus.container.grizzly.client.TaskProcessor.processTask(TaskProcessor.java:91)
at java.com.chronon.apm.libs.org.glassfish.tyrus.container.grizzly.client.GrizzlyClientFilter.handleRead(GrizzlyClientFilter.java:272)
at java.com.chronon.apm.libs.org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at java.com.chronon.apm.libs.org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at java.com.chronon.apm.libs.org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at java.com.chronon.apm.libs.org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at java.com.chronon.apm.libs.org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at java.com.chronon.apm.libs.org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at java.com.chronon.apm.libs.org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526)
at java.com.chronon.apm.libs.org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at java.com.chronon.apm.libs.org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at java.com.chronon.apm.libs.org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at java.com.chronon.apm.libs.org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at java.com.chronon.apm.libs.org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at java.com.chronon.apm.libs.org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: WebSocketClientSockJsSession[id='1f1aafad087b4cc78047f42b47b2ea3f, url=http://127.0.0.1:8082/wsgame] is not open, current state=CLOSED
at java.com.chronon.apm.libs.org.springframework.util.Assert.state(Assert.java:392)
at java.com.chronon.apm.libs.org.springframework.web.socket.sockjs.client.AbstractClientSockJsSession.sendMessage(AbstractClientSockJsSession.java:139)
at java.com.chronon.apm.libs.org.springframework.web.socket.messaging.WebSocketStompClient$WebSocketTcpConnectionHandlerAdapter.send(WebSocketStompClient.java:383)
at java.com.chronon.apm.libs.org.springframework.messaging.simp.stomp.DefaultStompSession.execute(DefaultStompSession.java:274)
... 47 more
The exception is thrown on this line:
stompSession.disconnect();
However, as you can see I check to see if the session is connected using the isConnected() call.
The code should not throw an exception if isConnected() was checked before calling disconnect()
Affects: 4.2.6
Issue Links:
- exception during websocket server shutdown [SPR-14716] #19281 exception during websocket server shutdown
Referenced from: commits 62b02c2, 99c7917, 81f6c22
Backported to: 4.2.8