Static object on Tomcat

Discussions

Web tier: servlets, JSP, Web frameworks: Static object on Tomcat

  1. Static object on Tomcat (7 messages)

    I have a problem. I need to create an object that will remain on the Tomcat server and will be accessable to all other users.

    I have tried creating an object that is static within a servlet, that works for individual sessions, but when 2 users are concurrently using the application, they can not see each other's object.

    Any help is greatly appreciated.

    Threaded Messages (7)

  2. Static object on Tomcat[ Go to top ]

    Store the object in the application context, AKA servlet context:

    ServletContext context = getServletContext();
    context.setAttribute("[name]", object);

    Later ...

    Object object = context.getAttribute("[name]");
  3. Static object on Tomcat[ Go to top ]

    Ok, I just tried that and I am now finding the object, however the changes to the object are not registering.

    For example:
    I open the page, the servlet gets the object and I am able to change the it.
    My friend opens the same page and should see the changes to that object but they are not showing up.

    This is part of a locking mechanism that I am working on. Basically, the object mentioned above is a HashMap of lock descriptors. Each lock descriptor has a String that represents the user's name and then a Calendar object that tells when the lock expires. The HashMap is found now, however when one opens up an object from the HashMap and locks it, that information is not showing up for the other users.
  4. Static object on Tomcat[ Go to top ]

    Without seeing your code, I could not even begin to guess what is going wrong. In principle, this should work. There must be something wrong with the way you are retrieving or updating your data.

    BTW, since the Map is being accessed by multiple users, you will need to make your logic thread-safe, e.g. by using a Hashtable or other synchronized map:

    Collections.synchronizedMap();
  5. Static object on Tomcat[ Go to top ]

    Ok, here is the code that deals with the part in question.

    public class LockHandler {

      public static HashMap Locks = null;
      ...
      public void initialize() {
        try {
          ServletContext context = ses.getServletContext();
          if (Locks == null) Locks = (HashMap)context.getAttribute("Locks");
          if (Locks == null) {
            Locks = new HashMap();
            context.setAttribute("Locks", Locks);
          }
          else {
            System.out.println("--- Server already has Locks initialized ---");
          }
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
    }

    In the servlets, I then access the Locks object. Every servlet initializes a LockHandler object and then accesses the Locks object therein.

    The problem that I am still getting is that the HashMap seems to be cleared out after every servlet executes. I need the data there to be static so that all of the users get the same information on the locks.
  6. Static object on Tomcat[ Go to top ]

    I don't see any obvious mistakes in the code. Maybe it is a problem with how the locks are used elsewhere in your code.

    I suggest you try the singleton approach suggested by Alf. You will also need to make sure everything is properly synchronized (which is also an issue for data stored in the ServletContext).

    Here is a simpler implementation of the same thing.


    public class LockHandler {
        private static final Map LOCKS =
            Collections.synchronizedMap(new HashMap());

        public static Object getLock(String key) {
            return LOCKS.get(key);
        }

        public static void setLock(String key, Object lock) {
            return LOCKS.set(key, lock);
        }
    }
  7. Static object on Tomcat[ Go to top ]

    I used that Singleton class and it is working great now. It seems that my problem was with a line of code that I did not get rid of from an earlier attempt to solve the problem.

    Thanks for the help.
  8. As long as the servlets run in the same JVM that should work.

    Below is an example.
    -------------------------------

    import java.util.Properties;
    import java.io.InputStream;
    import java.io.IOException;
    import java.io.FileNotFoundException;

    /**
     * Singelton class containing the parameters to the application.
     * It loads the properties for the application from the property
     * file and set up the meta-data and text properties for the
     * application
     */
    public final class ServerProperties{
        // The singelton ServerProperties object
        private static final ServerProperties self = new ServerProperties();
        
        // The properties for the Server
        private static Properties args;

        private static boolean initialized = false;
        
        /**
         * Name of the file to read the properties for the application from
         */
        public static String propertiesFileName = "myapp.properties";
        
        /**
         * Initialization of singelton object. Reads the property file as given
         * PROPERTIES_FILE_NAME
         */
        private ServerProperties() {
    loadProperties();
        }

        public static synchronized final void reset() {
    initialized = false;
    loadProperties();
    }
        
        /**
         * loads the properties from the properties file
         */
        public static synchronized final void loadProperties() {
            if ( initialized ) return ;
            
            try{
                getReference().args = new java.util.Properties();
                
                java.io.InputStream is = ServerProperties.class.getResourceAsStream(ServerProperties.propertiesFileName);
                getReference().args.load(is);
            }
            catch (java.io.FileNotFoundException fnf) {
                // May not have a log session yet, send an message to stderr
                System.err.println("Filename not found: " + fnf.getMessage());
            }
            catch (java.io.IOException ioe) {
                System.err.println("IOError: " + ioe.getMessage());
            }
            initialized = true;
        }
        
        /**
         * Returns a reference to the ServerProperties object
         */
        public final static ServerProperties getReference(){
            return self;
        }
        
        /**
         * Returns all properties for the server
         */
        public static java.util.Properties getProperties(){
            return args;
        }
        /**
         * Returns the named property as found in the property file
         *
         * @param str name of the property
         */
        public static final java.lang.String getProperty(java.lang.String str){
            if (null == str)
             return null;
            
            final ServerProperties local = ServerProperties.getReference();
            final String retVal = local.args.getProperty(str);
            
            return retVal;
        }
    }