With the new version 7 of the Vaadin Framework, some central aspects of writing Vaadin web applications have been thoroughly reworked.
One of these aspects is the way an HTTP session is represented and managed by the framework. While in older Vaadin versions each web session was represented by an instance of the somewhat misleadingly named class
com.vaadin.Application, this concept has been completely remodeled for Vaadin 7.
As a consequence of this, developers have to take into consideration two different variable scopes one of which has been newly introduced with this redesign. In this article, we want to take a closer look at these scopes, how to work with them and how to avoid common mistakes when making use of them.
How it was in times of old
Before we investigate the two variable scopes of Vaadin 7, we’ll first take a look at how things were done in previous versions of Vaadin.
A Vaadin application was then initialized by a sub-class of
com.vaadin.Application. An instance of this class had session scope; that is, every variable defined in that class lived in the user’s HTTP session. As a consequence of that, each new browser tab or window that was opened in a session shared the same
Application instance, and hence the same variables. Without proper handling, this resulted in out-of-sync errors when the same
Application instance was accessed and its variables altered from more than one browser tab. That is why you had to make appropriate provisions in your code, which could become quite cumbersome, if you wanted to support multi-tabbed browsing.
The ThreadLocal pattern
When you wanted to access specific session-scoped variables in old Vaadin versions, you usually made use of the now outdated ThreadLocal pattern. Using this pattern, you could access such variables with static accessor methods. Each session variable you wanted to access with a static method had to be stored in a ThreadLocal instance. You had to take care that this instance was accordingly set and unset for each request to your application.
With Vaadin 7, a developer doesn’t have to bother any longer with ThreadLocals or session data synchronization.
Multi-tabbed browsing with Vaadin 7
The organization and management of an HTTP session has been redesigned in Vaadin 7 from the ground up. One of the most important benefits of that is that multi-tabbed browsing is now supported by the framework out-of-the-box. You don’t have to take care of that yourself anymore.
This has been achieved by redesigning the mechanism of how a Vaadin application is initialized. Class
Application has been replaced by class
com.vaadin.ui.UI in Vaadin 7. One of the differences between these two classes is that class
UI does not represent the whole HTTP session but only a distinct fraction of the session. This section of the session memory represents the data of the currently open browser window. If a second browser tab or window is opened from a session, a new
UI instance is created, its
init() method called and by that a new copy of the
UI object’s variables initialized. Through this mechanism, each browser tab has its own set of data which will not be shared with any other currently open tab or window. With that, out-of-sync errors are a thing of the past with Vaadin 7.
Variable scopes and variable access
Developers of Vaadin applications have to adjust their approach to handle session data and need to take into consideration the new semantics introduced with class
UI. Instead of having to manage only one session-related variable scope (the session itself) you now can make use of two scopes. The second scope that is now available is defined by the individual instances of class
UI.
When you visit a Vaadin application with your browser, a new session is created along with a
UI instance that initializes and manages the contents of your browser window. Now if you open a second tab or browser window from the same session, the Vaadin servlet will create another
UI instance and put that into the session. You now have two distinct
UI instances in one session each of which manages the current state of the respective browser tab. When you interact with the application from both browser tabs you will not experience any synchronization issues since each
UI instance maintains its own set of variables so they won’t interfere with each other.
This behavior is the reason why developers should reconsider how they handle their session data. In older Vaadin versions it was enough to define a variable in your own subclass of
Application to add this variable to the session scope. Since class
Application represented the session itself, each variable defined in its subclass was automatically session-scoped.
The same does not apply to class
UI. Defining a variable in a subclass of
UI puts it into
UI-scope. This means in effect that for each new browser tab that is opened from a session a copy of all
UI-scoped variables is created. This may not be what you desire in every case.
If you want to have a real session-scoped variable that is not duplicated in memory for every new browser tab, you have to put that variable as a session attribute to the session using the methods of class
com.vaadin.server.VaadinSession. Another option would be to have a session-scoped JavaBean that is managed for you by some container such as Spring.
Thread-safe access to the session attributes
When you want to access your session attributes through class
VaadinSession you have to take into account that there might be more than one thread that accesses this data at the same time. Therefore, you have to work with session attributes in a thread-safe way. To do that, class
VaadinSession provides a lock mechanism allowing you to lock the session while accessing the session data.
The following code shows the pattern to be used when putting a data value into session scope:
try { VaadinSession.getCurrent().getLockInstance().lock(); VaadinSession.getCurrent().setAttribute(SESSION_SCOPED_VALUE_ID, "some value"); } finally { VaadinSession.getCurrent().getLockInstance().unlock(); }
You lock the session, alter the session data, and release the lock when you’re finished. You should always release the lock in a
finally block in order to avoid deadlocks.
What about the ThreadLocal pattern?
The ThreadLocal pattern as used in older Vaadin versions is now obsolete for Vaadin 7 as the framework already implements that pattern internally. You as a developer can make use of that implementation indirectly without having to manage an own instance of ThreadLocal.
The current references to the
UI instance and the
com.vaadin.server.VaadinSession instance are managed as ThreadLocals by the framework. You can always access a valid instance through the static methods
UI.getCurrent() and
VaadinSession.getCurrent().
If you also want to access the variables of your own subclass of
UI in a static way you can use the following pattern to create a
getCurrent() method that is narrowed to your UI class:
public class MyApplicationUI extends UI { // ... public static MyApplicationUI getCurrent() { return (MyApplicationUI) UI.getCurrent(); } }
You can then statically access your own
UI subclass as follows:
MyApplicationUI.getCurrent().getMyUIScopedVariable();
By that, managing ThreadLocal variables isn’t necessary any longer. Statically accessing session-scoped variables through the
VaadinSession can be achieved in a similar way.
Conclusion
We’ve seen that there are now two variable scopes available in a Vaadin application: the familiar session scope and the new
UI scope. Session-scoped variables are accessed through class
VaadinSession, while each value that is maintained in your
UI subclass has
UI scope. Since both
VaadinSession and
UI are managed by the framework through a ThreadLocal variable, you don’t need to manage your own set of ThreadLocals anymore.
As a rule of thumb, you should not place any variables into
UI scope which only exist once per session. Such a variable might be the currently logged-in user and her set of user roles or a shopping cart object keeping track of the articles the user is about to order. Keeping these things in
UI scope means an unnecessary duplication of the data for each new browser tab and hence a waste of memory.
In constrast, in
UI scope you should only hold data that has a direct relation to the data of the current
UI, i.e. browser tab or window. This could be the currently displayed UI components or JavaBeans containing form data the user has entered.
Demo application
There is a demo application available that demonstrates the difference between the two scopes of a Vaadin 7 HTTP session. It also shows the pattern how to access scoped variables in a static way. You can download the code from GitHub.
In that demo, you can edit a session-scoped and a
UI-scoped variable. When you open a new browser tab to this application, you can see that the session-scoped value still exists only once while the
UI-scoped variable is duplicated for each new tab.
Thanks for the clarification ! I’m missing this clearance and simplicity of wording often in VAADIN documentation. Needless to say that the “Book of VAAADIN” is still not updated in this very important section.
Regards
Gerd
Thank you, the post was very interesting.
The only question I would have is: when having data in UI scope, how do you prevent that data to be lost when you refresh the page (F5)?
(Btw, there’s a typo in Conclusion! ;) )
Hi Juno,
thanks for your comment. To prevent UI-scoped data from being lost on a browser refresh, you can use the annotation @PreserveOnRefresh (see and for details). When you put this annotation on your UI class, a UI instance will “survive” a refresh.
Thanks for pointing out the typo, it’s fixed now :)