Добрый день. Версия Jmix 1.5.3. Столкнулись с проблемой доступа к атрибутам пользовательской сессии при вызове компонентов из BackgroundTask. При обращении они просто выбрасывают ошибку. Если вызывать через UI поток то все работает.
Содержание ошибки:
org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'core_SessionData': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:383) ~[spring-beans-5.3.28.jar:5.3.28]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.28.jar:5.3.28]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.28.jar:5.3.28]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) ~[spring-beans-5.3.28.jar:5.3.28]
at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.getObject(DefaultListableBeanFactory.java:1990) ~[spring-beans-5.3.28.jar:5.3.28]
...
at io.jmix.ui.executor.LocalizedTaskWrapper.run(LocalizedTaskWrapper.java:56) ~[jmix-ui-1.5.3.jar:na]
at io.jmix.ui.executor.impl.WebBackgroundWorker$WebTaskExecutor.call(WebBackgroundWorker.java:206) ~[jmix-ui-1.5.3.jar:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at io.jmix.ui.executor.impl.WebBackgroundWorker$WebTaskExecutor.lambda$startExecution$1(WebBackgroundWorker.java:385) ~[jmix-ui-1.5.3.jar:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-5.3.28.jar:5.3.28]
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:55) ~[spring-web-5.3.28.jar:5.3.28]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371) ~[spring-beans-5.3.28.jar:5.3.28]
... 14 common frames omitted
Воспроизводится на чистой версии.
Пример экрана, при нажатия на кнопку
@Autowired
private Dialogs dialogs;
@Autowired
private Notifications notifications;
@Autowired
private ClientChecker clientChecker;
@Subscribe("btn")
public void onClick(Button.ClickEvent event) {
BackgroundTask<Integer, Boolean> task = new BackgroundTask<>(1, TimeUnit.MINUTES, this) {
@Override
public Boolean run(TaskLifeCycle<Integer> cycle) {
return clientChecker.check();
}
@Override
public void done(Boolean res) {
notifications.create(Notifications.NotificationType.HUMANIZED)
.withCaption(res ? "Accepted" : "Failed")
.show();
}
};
dialogs.createBackgroundWorkDialog(this, task)
.withCancelAllowed(false)
.build()
.show();
}
Пример компонента где происходит чтение/запись атрибутов
@Component
public class ClientChecker {
@Autowired
private ObjectProvider<SessionData> sessionDataProvider;
public boolean check() {
sessionDataProvider.getObject().setAttribute("clientCode", "123");
return true;
}
}