Vaadin’s Variable Scopes: VaadinSession and UI

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.

Short URL for this post: http://blog.oio.de/UoKGE
This entry was posted in Java Web Frameworks and tagged , , . Bookmark the permalink.

4 Responses to Vaadin’s Variable Scopes: VaadinSession and UI

  1. Gerd says:

    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

  2. Juno says:

    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! ;) )

  3. Pingback: Supporting IE10 on a Rich Internet Application with Vaadin – the Vaadin 7 migration « Trifork Blog / Trifork: Enterprise Java, Open Source, software solutions

Leave a Reply