Cannot access state in VaadinSession or UI without locking the session on invoking UI.access()

Hi, i’m using Vaadin 24 and i followed example from https://vaadin.com/docs/latest/advanced/server-push (last 3 code blocks).
Unfortunately it isn’t working for me. I add my code, but it’s almost the same as in the official example, I just replaced Consumer with BiConsumer, and I also use my custom MessageList and MessageListItem classes.

@Override
 protected void onAttach(AttachEvent attachEvent) {
     UI ui = attachEvent.getUI();
     broadcasterRegistration = Broadcaster.register((newMessage, conversationId) -> {
             ui.access(() -> messageList.addItems(List.of(newMessage)));
     });
 }

 @Override
 protected void onDetach(DetachEvent detachEvent) {
     broadcasterRegistration.remove();
     broadcasterRegistration = null;
 }```
```java
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Broadcaster {
 static Executor executor = Executors.newSingleThreadExecutor();

 static LinkedList<BiConsumer<MessageListItem, String>> listeners = new LinkedList<>();

 public static synchronized Registration register(BiConsumer<MessageListItem, String> listener) {
     listeners.add(listener);

     return () -> {
         synchronized (Broadcaster.class) {
             listeners.remove(listener);
         }
     };
 }

 public static synchronized void broadcast(MessageListItem item, String conversationId) {
     for (BiConsumer<MessageListItem, String> listener : listeners) {
         executor.execute(() -> listener.accept(item, conversationId));
     }
 }
}```
```java
@SpringBootApplication
@Push
public class CasualtalkchatApplication implements AppShellConfigurator {

 public static void main(String[] args) {
     SpringApplication.run(CasualtalkchatApplication.class, args);
 }
}```

So when you use UI.access() it works? Then you’re all right, because this is the right behaviour. Vaadin synchronizes data on the session level, meaning that only one Thread can work with any UI belonging to the VaadinSession or the session itself at a time, and UI.access is the way to do this outside of UI-handling threads.

UI.access() throws exception like in the title, do you mean this is the right behaviour? Mbe i don’t understand properly how it should work…

I expected broadcaster adds a message on every users’ UI

d I also use my custom MessageList and MessageListItem classes.
Are these components or data classes? If components your code will not work
ui.access(() → messageList.addItems(List.of(newMessage)));
You can’t use the same component instances in all session, you need to create new component instances

These are components and that was the problem, I move creating MessageListItem to UI.access() and now everything works as I expected. Thanks!

Did you stack trace pointed to this MessageListItem creation line? This surely can be an issue. Glad you managed to make it work.