Session collisions ?

Hi
We’re in the middle of testing a new prototype application built on Vaadin and have run into a problem that we don’t understand at all at the moment…
The application are built purely using Vaadin, 6.3.4 at the moment, deployed to a tomcat 5.5.26 running Java 1.5.0_14-b03.

Running as a single user is no problem at all but when having multiple users we are experiencing problems, we have implemented the “application instance pattern” described at http://vaadin.com/wiki/-/wiki/Main/Authenticating%20Vaadin-based%20applications and pretty much “worked by the book”.

The users experience that the application suddenly gets “unconnected”, the GUI still “works” in the meaning that combo boxes responds and even some buttons seems to be sending data to the server session but the context is lost, for example when trying to read data from the users client, combo boxes etc doesn’t reflect the data being shown in the application.

After adding httpsessionid (using getContext().getHttpSession().getId()) to the log it seems that we have an problem in different users using the same session…

It seems like more than one client / user gets the same sessionId… and we can’t understand this…

Hi,

Never seen this happen before, so I’m just trying to understand what could possibly be happening here…

Are you sure there is no static variables holding data or references to components?

In Vaadin a new application instance is created for every user session. This means everything in that instance is for that user. Especially that means that you should never store application instances in a static variable or you might experience stuff being shared among users/sessions. Same goes for components / data.

If you haven’t experience any out-of-sync or invalid security key errors the client vs server is in sync and all this is happening at a different level.

On the other hand, you say the HttpSession is somehow gets reused among the users. This would suggest there is something going on at the server level. You are using a bit older Tomcat, but still shouldn’t happen.

I would guess this is the problem:

private static ThreadLocal<SMSApp> currentApplication = //.....

Even with multiple users, the same thread could be used based on the thread pool settings and so the SMSApp object will be overwritten by the last Application object created. Instead, I would just use ‘this’ where needed. The instance of the Application will be specific to the the HttpSession of the user. From a quick glance at the code, I can’t tell why the thread local field is really used – I guess as a simple way to statically obtain the application object from a listener. I think it would be a lot simpler to just pass the application object into the listener, perhaps as a field in its constructor.

I don’t know if Vaadin allows multiple threads to hit the same application object at the same time (I kind of doubt it), but if so that’s a different problem than the above code is trying to solve.

Cheers,
Bobby

With the ThreadLocal pattern, one does need to be very careful to always reset the value at the end of transaction/request - most/all servers will reuse the same threads for other requests. I, too, believe that is the issue here - maybe the example is not reseting it correctly in some cases, or maybe you are missing something from the example.

The reason to use this pattern with Vaadin is typically to be able to find the application instance also from outside the application itself and components already attached to its windows. Passing the application as a parameter would sometimes result in long chains of calls having an extra parameter, and sometimes it would be hard to obtain the application instance to pass in the first place.

If using background threads with Vaadin, all code touching the UI-related classes (including Vaadin data sources etc.) must synchronize such access to the application instance.

Hi Henri,

I just want to make sure I’m understanding this pattern. Does this simplified example show what you’re talking about?

public class MyApp extends Application implements .... {
    static ThreadLocal<MyApp> currentApp = ....

    public void init() {
        /* other initialization code */

        // myListener is some instance of MyListener
        Component c = ....
        c.addListener(myListener);
    }

    /* code to set/clear currentApp field */   

    public MyApp getCurrentApp() {
        return currentApp.get();
    }
}

// imaginary generic listener
public class MyListener extends .... implements .... {
    public void actionMethod() {
        MyApp app = MyApp.getCurrentApp();
        app.doSomething();
    }
}

Thanks,
Bobby