Calling Window.setContent() from background thread

I have a background login process that attempts to setContent() on the main window when the login process returns from it’s work in a background thread. The problem is that the content’s attach() method is being called in the background thread too, and causes an exception because the Application object is not available (see stacktrace below). I would have thought Vaadin would somehow delay the call to attach() to a time where the Application object was available. How does one work around this??

java.lang.NullPointerException
at com.theice.vaadin.icemobile.MainTabSheet.attach(MainTabSheet.java:35)
at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:560)
at com.vaadin.ui.Panel.setContent(Panel.java:233)
at com.theice.vaadin.icemobile.App.initMainUI(App.java:239)
at com.theice.vaadin.icemobile.App.handleInitializationComplete(App.java:522)

–>> this line results in NPE
App.get().getLocale()

Umm… it’s pretty hard to say what’s going on just based on your description, but it seems like you’re using the ThreadLocal pattern, which seems fine. But as you mention the method attach(), that raises a red flag - most often, when people call or override the method, you’re doing something wrong.

Vaadin isn’t designed to be tolerant to multiple threads modifying stuff in one user’s session (clarification: Vaadin
is
multithreaded, but only by separating each user into a thread of its own). So, it’s the individual developers responsibility to not have any race conditions when using background threads that modify the UI.

All that I can say right now is to make sure that your “background login process” isn’t doing anything weird and wonky. Also, make sure that you’re making sure that a thread doesn’t cross-talk with another user’s request. For example, if you use some kind of transaction listeners, they might be listening to all transactions, instead of just the transactions linked to a certain application.

Basic debugging and tracing should clarify what your application is doing, and in what order.

Hi Henrik,

I can see that explicitly calling attach() means you’re working against Vaadin, not with it…

What’s wrong with overriding attach() though? In general in Java, there are some things you don’t want to do in a constructor, such as registering listeners (unsafe publication of an object). So in my Vaadin classes, I’ll set class-level fields in a constructor, but add child elements and listeners in the attach() method. Some things will only work there, such as setting the value on a Select object, so I prefer to do all UI-related work there since the object has already been constructed and added (can’t call getApplication() in a constructor).

Am I missing something about the attach() method? My only question before this was when I should or shouldn’t call super() during the method.

Thanks,
Bobby

I agree - explicitly calling attach() is something you should never need to do in application code, and rarely in add-ons, but overriding it to do additional processing is very often useful. You should always call the super() method there, at least unless you really understand what the super method is and isn’t doing for that particular case and are sure it won’t change.

Just a quick check: super.attach() will request a repaint, so should I do that
after
I’ve added any child components in my overridden attach() method? So far I haven’t seen any problems when I haven’t called the superclass method there, but maybe I’ve just blocked some problem from my memory. I’ll add the call there.

Mainly, I use attach() to avoid unsafe publication of a partially created object. More specifically, I never register a listener or pass any reference to
this
to another class during a constructor. I haven’t seen that be a problem in Vaadin specifically, but it’s good practice in Java, especially in any multi-threaded application.

Cheers,
Bobby

Requesting a repaint in Vaadin effectively just sets a flag that the component needs to be repainted at the end of the processing of the current request from the client. Therefore, it does not matter at what time it is done as long as it is done at least once for every component that does need to be repainted - and it is practically always done by the framework or the add-on used, you should not need to explicitly request a repaint from application code.