Hello. Trying to use Completablefuture with Vaadin and faced with an issue.
When trying to access from Completablefuture.thenAccept, I get an exception com.vaadin.ui.UIDetachedException. VaadinSession in UI is NULL.
If do execute Future with Executors.newFixedThreadPool(2), u will get com.vaadin.ui.UIDetachedException after two refresh of a page. If u will set 10, will get com.vaadin.ui.UIDetachedException after 10 refresh of a page.
So as i think that old threads cant be reused. Any idea ?
Can you show your code? Are you correctly using UI.access() method in your background threads?
When you refresh a page, if your UI is not annotated with @PreserveOnRefresh, it will be detached.
On first load all would be fine but if you will refresh a page and try again you will get
java.util.concurrent.CompletionException: com.vaadin.ui.UIDetachedException
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:659)
at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:632)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1624)
at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1610)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1689)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.vaadin.ui.UIDetachedException
at com.vaadin.ui.UI.access(UI.java:1434)
at hk.lear.MyUI.lambda$onDone$2(MyUI.java:57)
at hk.lear.MyUI$$Lambda$6/1880129221.accept(Unknown Source)
at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:656)
... 8 more
Then run Future with ExecutorService
And yes. After UI.access with over time getting this error
Oct 26, 2015 10:14:53 AM org.atmosphere.container.Jetty9WebSocketHandler onWebSocketError
SEVERE: {}
java.net.SocketTimeoutException: Timeout on Read
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onReadTimeout(AbstractWebSocketConnection.java:526)
at org.eclipse.jetty.io.AbstractConnection.onFillInterestedFailed(AbstractConnection.java:173)
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillInterestedFailed(AbstractWebSocketConnection.java:496)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback$1.run(AbstractConnection.java:582)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
So, you probably don’t have @PreserveOnRefresh, this makes Vaadin detach the UI on refresh and create a new one. When you execute the task after refresh, it will try to access the old UI, because it was set for the thread previously.
To solve the problem, remove UI.getCurrent() and just call this.access, or use @PreserveOnRefresh.
Actually, second thought, you can’t just use @PreserveOnRefresh, you have to use this.access.
If you just use preserve on refresh, then if the user opens two tabs, all notifications will be shown in the first one, regardless of in which UI the button was pressed.
Is it right to get UI from Vaadin Component ? for example Panel.getUI. Coz in average i invoking UI.access not from main UI.
And what about this error ?
Oct 26, 2015 10:14:53 AM org.atmosphere.container.Jetty9WebSocketHandler onWebSocketError
SEVERE: {}
java.net.SocketTimeoutException: Timeout on Read
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onReadTimeout(AbstractWebSocketConnection.java:526)
at org.eclipse.jetty.io.AbstractConnection.onFillInterestedFailed(AbstractConnection.java:173)
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillInterestedFailed(AbstractWebSocketConnection.java:496)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback$1.run(AbstractConnection.java:582)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
Yes, Component.getUI() should work correctly, if the component is attached.
Provide more details on how you get the SocketTimeoutException, I currently have no clue what causes it.
Dunno just using previous code and after execute UI.access with over time getting this exception.
Jetty 9.2.7v20150116. I think if you will create project with mine code with Jetty 9 you will get this error.
Do you have exmaple code for this case? Do you have tested your project with Vaadin 7.6.X? It shoukld have improvements for client server communication.