No request is available when opening a view from @EventListener triggered by background task

Hi Jmix Team,

I want to open a dialog (CcrisprocessErrorScreen) from my main view (CcrisProcess) after a background task finishes. I am using an event (CcrisProgressEvent) to communicate back.

In the background task’s done() method, I publish the event:

uiEventPublisher..publishEventForCurrentUI(new CcrisProgressEvent(this, ...);

And I listen:

@EventListener
protected void onCcrisProgressEvent(CcrisProgressEvent event) {
    if (!event.getResult()) {
        userSession.setSynNaviContext(synNaviContext);
        viewBuilders.view(this, CcrisprocessErrorScreen.class)
                .withOpenMode(ViewOpenMode.DIALOG)
                .open();
    }
}

What happens
When the background task finishes and the event is published, I get the following stack trace:

java.lang.IllegalStateException: No request is available. This method can only be used with an active VaadinServletRequest
    at com.vaadin.flow.server.auth.AccessAnnotationChecker.hasAccess(...)
    at io.jmix.flowui.sys.UiAccessChecker.isViewPermitted(...)
    at ...

I expect that after the background task finishes, the event listener should be able to open the dialog in the main UI without throwing No request is available.

  • Is this the expected behavior because the background task is running outside of a Vaadin request context?
  • Is there an official Jmix-recommended pattern for opening a view from a background task completion handler?

Thank you.

Best Regard,
Chee Hao

Hi @chfoong

Is there a reason why you don’t use the done() method ?
https://docs.jmix.io/jmix/flow-ui/background-tasks.html#done

Best regards
Felix

Hi

yes. I used done() method to trigger the event.

    @Override
        public void done(Boolean result) {
            this.result = result;
            events.publishEventForCurrentUI(new CcrisProgressEvent(this, result, processCd, userSession.getUserId() + functionCode));
        }

but it always show this execption when using viewBuilders

java.lang.IllegalStateException: No request is available. This method can only be used with an active VaadinServletRequest
	at com.vaadin.flow.server.auth.AccessAnnotationChecker.hasAccess(AccessAnnotationChecker.java:92)
	at io.jmix.flowui.sys.UiAccessChecker.isViewPermitted(UiAccessChecker.java:81)
	at io.jmix.flowui.sys.UiAccessChecker.checkViewPermitted(UiAccessChecker.java:115)
	at io.jmix.tabbedmode.builder.AbstractViewBuilderProcessor.createView(AbstractViewBuilderProcessor.java:30)
	at io.jmix.tabbedmode.builder.ViewBuilderProcessor.build(ViewBuilderProcessor.java:24)
	at io.jmix.tabbedmode.builder.AbstractViewBuilder.build(AbstractViewBuilder.java:103)
	at io.jmix.tabbedmode.builder.AbstractViewBuilder.open(AbstractViewBuilder.java:109)
	at com.infopro.synergyloan.view.ccris.ccrisprocess.CcrisProcess.onCcrisProgressEvent(CcrisProcess.java:282)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at io.jmix.flowui.sys.event.UiEventListenerMethodAdapter.doInvoke(UiEventListenerMethodAdapter.java:229)
	at io.jmix.flowui.sys.event.UiEventListenerMethodAdapter.processEvent(UiEventListenerMethodAdapter.java:153)
	at io.jmix.flowui.sys.event.UiEventListenerMethodAdapter.onApplicationEvent(UiEventListenerMethodAdapter.java:112)
	at io.jmix.flowui.sys.event.UiEventsManager.invokeListener(UiEventsManager.java:160)
	at io.jmix.flowui.sys.event.UiEventsManager.publish(UiEventsManager.java:153)
	at io.jmix.flowui.UiEventPublisher.publish(UiEventPublisher.java:152)
	at io.jmix.flowui.UiEventPublisher.publishEventForCurrentUI(UiEventPublisher.java:137)
	at com.infopro.synergyloan.view.ccris.ccrisprocess.CcrisProcess$ValidateCcris.done(CcrisProcess.java:343)
	at com.infopro.synergyloan.view.ccris.ccrisprocess.CcrisProcess$ValidateCcris.done(CcrisProcess.java:317)
	at io.jmix.flowui.backgroundtask.LocalizedTaskWrapper.done(LocalizedTaskWrapper.java:158)
	at io.jmix.flowui.backgroundtask.impl.BackgroundWorkerImpl$TaskExecutorImpl.handleDone(BackgroundWorkerImpl.java:297)
	at io.jmix.flowui.backgroundtask.impl.BackgroundWorkerImpl$TaskExecutorImpl$1.lambda$done$f7fe4649$1(BackgroundWorkerImpl.java:194)
	at com.vaadin.flow.component.UI.accessSynchronously(UI.java:498)
	at com.vaadin.flow.component.UI$2.execute(UI.java:573)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at com.vaadin.flow.server.VaadinService.runPendingAccessTasks(VaadinService.java:2173)
	at com.vaadin.flow.server.VaadinSession.unlock(VaadinSession.java:755)
	at com.vaadin.flow.server.VaadinService.ensureAccessQueuePurged(VaadinService.java:2137)
	at com.vaadin.flow.server.VaadinService.accessSession(VaadinService.java:2104)
	at com.vaadin.flow.server.VaadinSession.access(VaadinSession.java:1059)
	at com.vaadin.flow.component.UI.access(UI.java:570)
	at com.vaadin.flow.component.UI.access(UI.java:553)
	at io.jmix.flowui.backgroundtask.impl.BackgroundWorkerImpl$TaskExecutorImpl$1.done(BackgroundWorkerImpl.java:193)
	at java.base/java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:434)
	at java.base/java.util.concurrent.FutureTask.set(FutureTask.java:285)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:325)
	at io.jmix.flowui.backgroundtask.impl.BackgroundWorkerImpl$TaskExecutorImpl.lambda$startExecution$0(BackgroundWorkerImpl.java:396)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)