Completablefuture with Vaadin

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.

  @Override
    protected void init(VaadinRequest vaadinRequest) {

        final Button clickMeButton = new Button("Click me", event -> {
            doTask()
                .thenAccept(onDone())
                .handle(handleException());
        });

        setContent(clickMeButton);
    }

    private CompletableFuture<Void> doTask() {
        return CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    private Consumer<Void> onDone() {
        return aVoid -> UI.getCurrent().access(() -> Notification.show("Task id done"));
    }

    private BiFunction<Void, Throwable, Object> handleException() {
        return (aVoid, throwable) -> {
            Logger.getAnonymousLogger().log(Level.SEVERE, "", throwable);
            return aVoid;
        };
    }

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

    private CompletableFuture<Void> doTask() {
        return CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, [b]
Executors.newSingleThreadExecutor()
[/b]);
    }

And you will never get previous Exception because Future always getting a fresh Thread

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.

Hope this works, tell us the result.

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)

I’ve tried to do this.access - it works. So if i need an actual UI i can get it from attached Component ?

P.S. I don’t want to use @PreserveOnRefresh

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.

Every 5 mins

Hi Zhilin,

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.