Static and ThreadLocal problem in vaadin

Hi all,

      In my vaadin application i have many forms which will be loaded  right side when i click the tree menu in the left side . I checked that if any user edit the form 
      but doesn't save it , then i shows dialog " please save or exit". If user clicks the  exit button , i allow him to go to another menu . I have done this by using static 
     variable . I found from forum static variables should not be used because it is not shared nicely to all users. So implement threadlocal pattern .Although it is not 
     working properly. When one user edit a form, if another user access the same or any form,then he  will be notified by "please save or exit" dialog.

    This is my following code. I implement the listener to Applicaiton class.

     [code]

    public class BWLogin extends Application implements HttpServletRequestListener
    {
       private static ThreadLocal<BWLogin> threadLocal = new ThreadLocal<BWLogin>(); 
      // These variables are used by other form by using setter and getter methods.
       private  int save_flg = 0;
       private int nameExitFlag = 0;
       private int ejeflg = 0 ;
       private int exit_flg = 0 ;
       private int stopflg = 0 ;
       private int threadFlag = 0;
    
    @Override
public void init()
    {   
        setInstance(this);
        MyApp myApp = new MyApp();
        setMainWindow(myApp);
    }
    @Override
public Window getWindow(String name)
    {
        w = super.getWindow(name);
        if (w == null) 
        {
           w = new MyApp();
            w.setName(name);
            addWindow(w);
            w.open(new ExternalResource(w.getURL()));
        }
        return w;
    }

public static BWLogin getInstance()
{
return threadLocal.get();
}

// Set the current application instance
public static void setInstance(BWLogin application)
{
threadLocal.set(application);
}

@Override
public void onRequestStart(HttpServletRequest request, HttpServletResponse response)
{
BWLogin.setInstance(this);

}

@Override
public void onRequestEnd(HttpServletRequest request, HttpServletResponse response)
{
threadLocal.remove();
}

/**
 * @return the save_flg
 */
public static int getSave_flg()    
{
   return threadLocal.get().save_flg;
}

/**
 * @param save_flg the save_flg to set
 */
public static void setSave_flg(int save_flg)
{
    threadLocal.get().save_flg = save_flg;
}

/**
 * @return the nameExitFlag
 */
public static int getNameExitFlag() 
{
    return threadLocal.get().nameExitFlag;
}
/**
 * @param nameExitFlag the nameExitFlag to set
 */
public static void setNameExitFlag(int nameExitFlag) 
{
    threadLocal.get().nameExitFlag = nameExitFlag;
}

/**
 * @return the ejeflg
 */
public static int getEjeflg()
{
   return threadLocal.get().ejeflg; 
}

/**
 * @param ejeflg the ejeflg to set
 */
public static void setEjeflg(int ejeflg) 
{
    threadLocal.get().ejeflg = ejeflg;
}

/**
 * @return the exit_flg
 */
public static int getExit_flg() 
{
    return threadLocal.get().exit_flg;
}

/**
 * @param exit_flg the exit_flg to set
 */
public static void setExit_flg(int exit_flg)
{
     threadLocal.get().exit_flg = exit_flg;
}

/**
 * @return the stopflg
 */
public static int getStopflg() 
{
    return threadLocal.get().stopflg;
}

/**
 * @param stopflg the stopflg to set
 */
public  static void setStopflg(int stopflg) 
{
    threadLocal.get().stopflg = stopflg;
}

/**
 * @return the threadFlag
 */
public static int getThreadFlag() 
{
    return threadLocal.get().threadFlag;
}

/**
 * @param threadFlag the threadFlag to set
 */
public static void setThreadFlag(int threadFlag) 
{
    threadLocal.get().threadFlag = threadFlag;
}

public class MyApp extends Window implements Button.ClickListener,FieldEvents.FocusListener
{
public MyApp()
{
setCaption(“B&W Web Client v2.0”);
setTheme(“reindeer”);
setContent(vl);
vl.addComponent(buildMainLayout());
}
}
}

[/code]

ThreadLocals are to save data for one user, and not to share to all users. Static variables are shared between everything running within the server. You might be interested in some sort of Event bus to notify all the view’s when some data has been updated. For example the Blackboard add-on in the Directory is one implementation of this, and there is very many others in the Java world if you google a bit.

I think you can solve your issue by simply removing every static method and threadlocal wrapper and just use basic fields. For instance:

public class BWLogin extends Application implements HttpServletRequestListener {

           private  int save_flg = 0;

    /**
     * @return the save_flg
     */
    public static int getSave_flg()    
    {
       return save_flg;
    }
 // etc

Every instance of BWLogin is only in one session, for one use, so you can just declare your fields and access them normally. I can’t tell what problem you’re trying to solve with all the threadlocal stuff. If it’s just a question of getting the application instance, then any component can do getWindow().getApplication() to get the enclosing app (as long as the component has been attached).

Can you try simplifying all this and see if you still have an issue. I’ve created lots of Vaadin apps, and have never used threadlocals or static fields except for constants or declaring static inner classes.

Cheers,
Bobby

Hi sir,
You said to change the code like this.
[code]

private int save_flg = 0;

/**
 * @return the save_flg
 */
public static int getSave_flg()    
{
   return save_flg;
}

[/code]

     But save_flg is not a static field  so it can not be used in static method . If i remove static methods then how the fields are retaining the last value assigned to that fields.
     Is  fileld declared in the Application class retain the value? .Which means field act as a static variable in application class.I can't understand .
     After changing the code like you said .

private  int save_flg = 0;

    /**
     * @return the save_flg
     */
    public  int getSave_flg()    
    {
       return save_flg;
    }
   public  void setSave_flg(int save_flg)
    {
        this.save_flg = save_flg;
    }

Sir, actually my need is last assigned value should be retained by that field.And i will use that value to check some validation.
And also i don’t need this to show up to another user.

Please give some solution.

Thank you sir.

Unless you’re doing something I’m not understanding yet, I don’t think you need any static methods at all. When you write your application class, it can simply have some private fields and getters/setters for those fields. When a user uses the application, an instance of your class is created and stored in the user’s http session. Other users have their own sessions with their own instances of the app, so each user sees his/her own data. Does that help?

Here’s a simple example in two classes:

public class SimpleApp extends Application {

    private Label label = new Label("Date");

    @Override
    public void init() {
        Window main = new Window("test");

        main.addComponent(label);
        main.addComponent(new Button("Click", new
            SimpleButtonListener(this)));

        setMainWindow(main);
    }

    Label getLabel() {
        return label;
    }
}
public class SimpleButtonListener implements Button.ClickListener {

    final private SimpleApp app;

    public SimpleButtonListener(SimpleApp app) {
        this.app = app;
    }

    @Override
    public void buttonClick(Button.ClickEvent event) {
        Label label = app.getLabel();
        label.setValue(new Date());
    }
}

Each ‘label’ object is stored in one instance of SimpleApp, kept in the user’s session. You don’t have to worry about other users seeing this info since they have their own instances. I may be misunderstanding your question, but conceivably you’re thinking of the Java code as being interpreted like PHP code? If not, sorry. If so, you should understand that Java doesn’t work that way. You define a class, but then instances of that class are created that actually store info and do work.

Vaadin does the work of making sure each http session has its own version of the data. Once you start throwing static methods and fields into the mix, you could end up breaking what Vaadin is doing for you.

Cheers,
Bobby

“Vaadin does the work of making sure each http session has its own version of the data. Once you start throwing static methods and fields into the mix, you could end up breaking what Vaadin is doing for you”

Maybe beginner’s question.
Is it true that if I declare a class or a variable as static, then it declares them as “application-wide” and hence accessible to all users? Because this is what I actually want to achieve - I am looking for a way to store/retrieve (in memory) some global application data, accessible from any user, so it cannot be UI or session scoped, it has to be global application scoped. Apparently there is nothing for that in Vaadin API, fix me if I am wrong.

Is it true for statics that it works exactly like that?