Weird problem with LocalThread

Hi. I have made simple application like in this tutorial https://vaadin.com/book/-/page/advanced.global.html

I try to store user data in the threadlocal instance with static setter. I occur the problem with NPE. Instance of threadlocal returns null when i try to set the string.

    public static void setUserData(String userData) {
        instance.get().userData = userData;   //here 
    }

I dont know why this happens but, when i press the button few times, it succesfully set the string into the instance. I have added second button which gets stored string from instance, and the same happens. Throwed NPE, but after few clicks it succesfully set gained string into the label.
It is running on Glassfish 3.1.2.Am i doing something wrong or i didnt understand this right. I would like to use vaadin with Ejb3.1, thats why application has ejb annotiation and gets started with this servlet. Any ideas would be appreciated.

public class AppData
       implements TransactionListener, Serializable {
    private ResourceBundle bundle;
    private Locale locale;   // Current locale
    private String userData; // Trivial data model for the user
    
    private Application app; // For distinguishing between apps

    private static ThreadLocal<AppData> instance =
        new ThreadLocal<AppData>();
    
    public AppData(Application app) {
        this.app = app;

        // It's usable from now on in the current request
        instance.set(this);
    }

    @Override
    public void transactionStart(Application application,
                                 Object transactionData) {
        // Set this data instance of this application
        // as the one active in the current thread. 
        if (this.app == application)
            instance.set(this);
    }

    @Override
    public void transactionEnd(Application application,
                               Object transactionData) {
        // Clear the reference to avoid potential problems
        if (this.app == application)
            instance.set(null);
    }

    public static void initLocale(Locale locale,
                                  String bundleName) {
        instance.get().locale = locale;
        instance.get().bundle =
            ResourceBundle.getBundle(bundleName, locale);
    }
    
    public static Locale getLocale() {
        return instance.get().locale;
    }

    public static String getMessage(String msgId) {
        return instance.get().bundle.getString(msgId);
    }

    public static String getUserData() {
        return instance.get().userData;
    }

    public static void setUserData(String userData) {
        instance.get().userData = userData;
    }
}
@Stateful
public class MyApplication extends Application {
    TextField field = new TextField();

    @Override
    public void init() {
        Window mainWindow = new Window("Tls");
        AppData session = new AppData(this);
        getContext().addTransactionListener(session);
        final Label label = new Label();
        Button butt = new Button();
        butt.addListener(new Button.ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                AppData.setUserData((String)field.getValue());
            }
        });
        Button butt2 = new Button();
        butt2.addListener(new Button.ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                label.setValue(AppData.getUserData());
            }
        });
        
        mainWindow.addComponent(field);
        mainWindow.addComponent(label);
        mainWindow.addComponent(butt);
        mainWindow.addComponent(butt2);
        setMainWindow(mainWindow);
    }
}
}

Servlet [code]
@WebServlet(urlPatterns = “/*”)
public class MyApplicationServlet extends AbstractApplicationServlet {

@Override
protected Application getNewApplication(HttpServletRequest request) throws ServletException {
    try {
        InitialContext ic = new InitialContext();
        return (Application) ic.lookup("java:module/MyApplication");
    } catch (NamingException e) {
        throw new ServletException("Could not access application", e);
    }
}

@Override
protected Class<? extends Application> getApplicationClass() throws ClassNotFoundException {
   return MyApplication.class;
}

}
[/code]

Best regards.

I have found the solution. Old topic on the forum

https://vaadin.com/forum/-/message_boards/view_message/131360

had to remove if section from transactionStart method.

Just curious: why are you making your application object a stateful session bean? Since Vaadin applications already store state information in the session, I don’t see the point of it. Also, it makes things more complicated IMO that you’re having 2 different systems (EE container and Vaadin servlet) involved in the lifecycle of your app object.

Cheers,
Bobby