Singleton classes for sessions / context

Hello there!

First of all let me say that you’ve made a really good job! Gorgeous tool.

To the point:
I’m newer in web app development so maybe my question it’s not necessarily related to Vaadin itself.

I’ve created a Vaadin Application where I define three different classes as singleton. This approach works fine in desktop environments and I’m able to access to the singletons anywhere in my code. On the other hand this singletons are placed in a common jar used for many applications w/o problems.

But now, once I created them under init() application’ method I can use in my first created window (login) but after I set the new window I loose these singletons. I loose them even if I reload/refresh the application using F5. So all my calls to TheSingleton.getInstance().anyMethod() raises an Invalid Pointer Exception.

The code (I write it w/o having the code in front of me so I write it w/o syntax checking):

public class MyApplication extends Application
{

public void init() {

 UIHandler.initialize(some parameters);
 DataFacade.initialize(some parameters); 

 ....
 loginWindow = new LoginWindow();
 mainWindow = new Window();
 ...

}


}

public class UIHandler implements Serializable {
private static UIHandler instance;

 private UIHandler() {
     ....
 }

 public static void initialize(some parameters) {
     if (instance == null) {
          instance = new UIHandler();
     }
 }

 public static UIHandler getInstance() {
      ....
      return instance;
 }

}

The same apply to the other singleton classes. As you can see it’s a regular singleton pattern.

I’m using this pattern to allow my new vaadin application to use the same structure I’ve in a desktop application. My goal is to create a central UIController and handler that will be used to start the application under desktop or web based with vaadin. So I must centralize all the UI handling in a common point and inject classe dependencies depending on the scenario. Maybe it exists a better approach to it but it’s the one I just selected.

Regarding to the DataFacade to use singleton is to allow all my DAOControllers to connect with a DataProvider without taking care of which one is behind: iBatis, Spring, direct JDBC, dummy… So I create a DataFacade as singleton, configured on application startup and then I use the single instance anywhere in the code as a singleton data facade.

Now…
Once I run the application the first loginWindow it’s shown correctly and it uses, internally, all my singleton classes. After logging, my application calls setMainWindow(mainWindow); if it’s a valid user. But all the calls to UIHandler.getInstance() and DataFacade.getInstance() returns null!

Is it a problem with the singletons under web containers? Maybe loaded in different threads? Different VM? Is it better to put this kind of objects as properties in the session (for user) or context (for all app users)? Better to avoid the singleton pattern under web development?..
I’m so confused and I cant’ figure out how to solve it. I becoming crazy!! I’ve lost 5 days investigating but I’ve got nothing.

If you can give me any kind of help it’ll be really appreciated.

Thank you in advance.

There should be no problems using singletons in a web application if it runs in a normal servlet container, e.g. Tomcat/JBoss/… The statics are stored from request to request and the singletons should be correctly returned (not null). I suspect there is either a bug in your code or you are not restarting the application (add ?restartApplication to the url) after restarting the servlet container (the container serializes your application on shutdown and restores it on startup, so you might be running an old version and in that case the statics are probably not initialized).

You need to be careful though not to store any information related to the application state in static variables (or singletons) as they will be the same for all users and accessed simultaneously. Statics are good for caches etc but definitely not for storing login information or similar. If you do initialization in the init() method, also note that the initialization will then be done every time ANYBODY starts a new application, i.e. loads the page for the first time, logs out (close the application), etc.

Also if you are using Google App Engine or a similar multi server setup, statics and singletons won’t work as different servers will (might) handle the requests.

Hi Artur,

First of all thank you for your answer.

I agree with you about singleton using. It’s not used for managing static variables and so on but it’s used to centralize the Data access as a Facade, initialized in the Application startup (one of the singletons). In my case the facade initializes the database access using iBatis and I don’t want to read the iBatis xml map everytime I need to access data. This is the reason I use the DataFacade initialized during app startup.

My scenario is the one I describe now:

  • I’m using Tomcat 6.0.20 as a servlet container. I’m also using the vaadin-6.1.0.jar
  • I run my application from http://localhost:8080/MyApplication
    Once the application is loaded I create the singletons in the init() procedure
    I create two windows, LoginWindow and MainWindow.
    Then I execute setMainWindow(login) and it shows the login window w/o problems, using the singletons for some internal operations.
    Then, when I type ‘alex’ as username and ‘alex’ as password my LoginWindow uses the DataFacade singleton to locate my user/pwd in the database and it does it fine.
    Then, as a valid user, I execute the setMainWindow(MainWindow) to show me the new window for the registered user. (Something similar to the demos using ‘loadProtectedResources’ after user authentication).
    Now the MainWindow tries to access my DataFacade singleton to read some data from the Database… but the call to DataFacade.getInstance() returns null !

I’m not running the application twice nor running the application from two different webbrowsers nor something like this. Even I’m not stopping Tomcat nor similar. Only executing the app once and changing the mainWindow inside the application code… So it’s the same application running, the same user, the same browser, the same Tomcat instance…

Maybe it’s an stupid error in my code but I’m completely lost! I’ll try to simplify my code in order to attach it here but if you or somebody else could figure out how to handle this singleton structure I’ll appreciate all comments. Even I’ll post the structure in contrib when I get it running fine to show how to use different Data Access from Vaadin using a DataFacade. But before it must run fine! :slight_smile:

Thank you so much in advance

Here is a simple example of a singleton in an Application. The singleton contains a single integer value and is stored as long as the servlet container is running. Refreshing the browser, restarting the application etc will not affect the singleton.


public class MySingleton {

    private int value = 1;

    private static MySingleton instance = null;

    public static void init() {
        if (instance == null) {
            instance = new MySingleton();
        }
    }

    public static MySingleton get() {
        return instance;
    }

    @Override
    public String toString() {
        return "MySingleton, value: " + value;
    }

    public void increase() {
        value++;
    }
}

public class SingletonApplication extends Application {
    private ComponentContainer applicationMainLayout;
    private ComponentContainer loginLayout;

    @Override
    public void init() {
        MySingleton.init();

        loginLayout = createLoginLayout();
        applicationMainLayout = createApplicationMainLayout();

        setMainWindow(new Window("SingletonApplication", loginLayout));

    }

    private ComponentContainer createLoginLayout() {
        VerticalLayout layout = new VerticalLayout();
        Button loginButton = new Button("Click to login", new ClickListener() {

            public void buttonClick(ClickEvent event) {
                getMainWindow().setContent(applicationMainLayout);
                getMainWindow().showNotification(
                        "Login was clicked, singleton: " + MySingleton.get());
            }

        });

        layout.addComponent(loginButton);
        return layout;
    }

    private ComponentContainer createApplicationMainLayout() {
        VerticalLayout layout = new VerticalLayout();

        Button myButton = new Button("Click to increase singleton value",
                new ClickListener() {

                    public void buttonClick(ClickEvent event) {
                        MySingleton.get().increase();
                        getMainWindow().showNotification(
                                "Singleton: " + MySingleton.get());
                    }

                });

        Button logoutButton = new Button("Logout", new ClickListener() {

            public void buttonClick(ClickEvent event) {
                getMainWindow().setContent(loginLayout);
            }

        });
        layout.addComponent(myButton);
        layout.addComponent(logoutButton);

        return layout;
    }
}

Hi Artur,

It’s like the way I’ve done it. But in my case it works for first window accessing the singleton but not for the second window (BTW created at the same time in the application’ init() method).

I’ll give me another chance to discover what’s up. :slight_smile:

When I get it running with success I’ll let you know what was wrong…

Thank you again