Vaadin Spring Boot: «Невозможно получить доступ к состоянию в VaadinSession или пользовательском интерфейсе без блокировки сеанса», когда несколько пользователей получают доступ к пользовательскому интерфейсу - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть приложение vaadin flow (13) с пружинной загрузкой. У меня есть VerticalLayout, помеченный @UIScope с несколькими вложенными макетами. Вспомогательные макеты помечены @Scope("prototype") и созданы с помощью ctx.getBean(SubUI.class, ...). В зависимости от выбора и нажатия кнопки на родительском пользовательском интерфейсе (VerticalLayout), вложенные макеты могут быть добавлены или удалены.

Это все работает нормально, пока я использую только приложение (вот почему я нашел ошибку правильно Теперь, после доставки заявки моему клиенту для проверки приемлемости). Они протестированы с несколькими пользователями. Пока один пользователь работает с appliaction, все работает, но как только второй пользователь входит в пользовательский интерфейс (VerticalLayout), выдается следующее исключение:

java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Cannot access state in VaadinSession or UI without locking the session.
    at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:1.8.0_202]
    at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[na:1.8.0_202]
    ...

Я пробовал разные аннотации для моего родительского макета ( @UIScope, @Scope ("prototype"), @VaadinSessionScope), но не решает мою ошибку.

Я погуглил о проблеме и нашел несколько тем, но ни одна из них не помогла мне решить мою проблему. Я не совсем уверен, вызвана ли эта проблема областью действия моих интерфейсов / макетов или, возможно, привязкой данных. В моих вложенных макетах данные связаны с использованием Binder<MyEntity> binder = new Binder<>(MyEntity.class); и binder.forField(xxx).bind(MyEntity::getXY,MyEntity::setXY);.

Может кто-нибудь объяснить мне, в чем моя проблема? Я был бы очень рад, потому что мне нужно предоставить фиксированную версию для тестирования моих клиентов.

С уважением

1 Ответ

2 голосов
/ 12 февраля 2020

В вашем приложении есть логики c, которые пытаются изменить состояние пользовательского интерфейса, компоненты и т. Д. c. из фоновой темы. Это должно быть сделано под защитой блокировки. Поэтому вам нужно инкапсулировать логи c в вашем представлении, которые вызываются из фонового метода с помощью

getUI().ifPresent(ui -> ui.access(() -> {
    ...
}));
...