Vaadin UIs are closed when:
- the user closes the browser window and three heartbeats are missed,
- the user goes quiet and the idle session is closed after timeout,
- the user initiaties an explicit UI close (I provide a button for that).
In any of these circumstances, I am getting the following stack trace a small fraction of the time - maybe one in 20 UI closings. The rest are closed without error. So I suspect a race condition between Vaadin’s push, Tomcat and Atmosphere is taking place at UI closing time. The stack trace indicates:
- Vaadin calls a disconnect method in AtmospherePushConnection
- Tomcat/atmosphere tries to write a close message to websocket
- websocket has already closed so the error is thrown.
Something is being done in the wrong order. Any ideas about how UI closing can always be done cleanly?
Java 8, Tomcat 8.0.30, Vaadin 7.6.0, manual push using websocket, Ubuntu 14.04
java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: Unable to write the complete message as the WebSocket connection has been closed
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:282)
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:584)
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:488)
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:455)
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:449)
at org.atmosphere.container.version.JSR356WebSocket.close(JSR356WebSocket.java:142)
at org.atmosphere.cpr.AtmosphereResourceImpl.close(AtmosphereResourceImpl.java:860)
at com.vaadin.server.communication.AtmospherePushConnection.disconnect(AtmospherePushConnection.java:312)
at com.vaadin.ui.UI.setPushConnection(UI.java:1591)
at com.vaadin.ui.UI.setSession(UI.java:473)
at com.vaadin.server.VaadinSession.removeUI(VaadinSession.java:869)
at com.vaadin.server.VaadinService$1$1.run(VaadinService.java:481)
at com.vaadin.ui.UI.accessSynchronously(UI.java:1381)
at com.vaadin.server.VaadinService$1.run(VaadinService.java:469)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at com.vaadin.server.VaadinService.runPendingAccessTasks(VaadinService.java:1835)
at com.vaadin.server.VaadinSession.unlock(VaadinSession.java:989)
at com.vaadin.server.VaadinService.requestEnd(VaadinService.java:1356)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1423)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2437)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.concurrent.ExecutionException: java.io.IOException: Unable to write the complete message as the WebSocket connection has been closed
at org.apache.tomcat.websocket.FutureToSendHandler.get(FutureToSendHandler.java:102)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:275)
... 41 more
Caused by: java.io.IOException: Unable to write the complete message as the WebSocket connection has been closed
at org.apache.tomcat.websocket.WsSession.registerFuture(WsSession.java:658)
at org.apache.tomcat.websocket.FutureToSendHandler.get(FutureToSendHandler.java:92)
... 42 more