You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@locus.apache.org on 2000/10/14 23:43:55 UTC

cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/session StandardManager.java

craigmcc    00/10/14 14:43:55

  Modified:    catalina/src/share/org/apache/catalina Manager.java
               catalina/src/share/org/apache/catalina/core
                        LocalStrings.properties StandardContext.java
               catalina/src/share/org/apache/catalina/session
                        StandardManager.java
  Log:
  Finish refactoring and make session persistence across auto-reload (either
  because a class in WEB-INF/classes was changed or initiated through the
  manager application) and server shutdown/restart.
  
  When a reload is initiated, any loaded filters and application event
  listeners are also released and re-initialized, to avoid class cast errors
  due to the creation of a new classloader after the reload.
  
  Application event listeners will see sessions being persisted to storage
  and then expired, followed by being recreated and the attributes re-added
  after the reload.
  
  Revision  Changes    Path
  1.2       +26 -4     jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/Manager.java
  
  Index: Manager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/Manager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Manager.java	2000/08/11 05:24:09	1.1
  +++ Manager.java	2000/10/14 21:43:53	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/Manager.java,v 1.1 2000/08/11 05:24:09 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/08/11 05:24:09 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/Manager.java,v 1.2 2000/10/14 21:43:53 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/10/14 21:43:53 $
    *
    * ====================================================================
    *
  @@ -86,7 +86,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2000/08/11 05:24:09 $
  + * @version $Revision: 1.2 $ $Date: 2000/10/14 21:43:53 $
    */
   
   public interface Manager {
  @@ -196,11 +196,33 @@
   
   
       /**
  +     * Load any currently active sessions that were previously unloaded
  +     * to the appropriate persistence mechanism, if any.  If persistence is not
  +     * supported, this method returns without doing anything.
  +     *
  +     * @exception ClassNotFoundException if a serialized class cannot be
  +     *  found during the reload
  +     * @exception IOException if an input/output error occurs
  +     */
  +    public void load() throws ClassNotFoundException, IOException;
  +
  +
  +    /**
        * Remove a property change listener from this component.
        *
        * @param listener The listener to remove
        */
       public void removePropertyChangeListener(PropertyChangeListener listener);
  +
  +
  +    /**
  +     * Save any currently active sessions in the appropriate persistence
  +     * mechanism, if any.  If persistence is not supported, this method
  +     * returns without doing anything.
  +     *
  +     * @exception IOException if an input/output error occurs
  +     */
  +    public void unload() throws IOException;
   
   
   }
  
  
  
  1.16      +3 -3      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/LocalStrings.properties,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- LocalStrings.properties	2000/10/14 05:21:11	1.15
  +++ LocalStrings.properties	2000/10/14 21:43:54	1.16
  @@ -22,15 +22,15 @@
   interceptorValve.notStarted=InterceptorValve has not yet been started
   standardContext.alreadyStarted=Context has already been started
   standardContext.applicationListener=Error configuring application listener of class {0}
  -standardContext.defaultLoader=Configuring default Loader
  -standardContext.defaultManager=Configuring default Manager
  -standardContext.defaultResources=Configuring default Resources
  +standardContext.applicationSkipped=Skipped installing application listeners due to previous error(s)
   standardContext.filterMap.either=Filter mapping must specify either a <url-pattern> or a <servlet-name>
   standardContext.filterMap.name=Filter mapping specifies an unknown filter name {0}
   standardContext.filterMap.pattern=Invalid <url-pattern> {0} in filter mapping
   standardContext.isUnavailable=This application is not currently available
   standardContext.listenerStart=Exception sending context initialized event to listener instance of class {0}
   standardContext.listenerStop=Exception sending context destroyed event to listener instance of class {0}
  +standardContext.managerLoad=Exception loading sessions from persistent storage
  +standardContext.managerUnload=Exception unloading sessions to persistent storage
   standardContext.mappingError=MAPPING configuration error for relative URI {0}
   standardContext.notReloadable=Reloading is disabled on this Context
   standardContext.notStarted=Context has not yet been started
  
  
  
  1.21      +127 -44   jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java
  
  Index: StandardContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- StandardContext.java	2000/10/14 05:21:11	1.20
  +++ StandardContext.java	2000/10/14 21:43:54	1.21
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.20 2000/10/14 05:21:11 craigmcc Exp $
  - * $Revision: 1.20 $
  - * $Date: 2000/10/14 05:21:11 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.21 2000/10/14 21:43:54 craigmcc Exp $
  + * $Revision: 1.21 $
  + * $Date: 2000/10/14 21:43:54 $
    *
    * ====================================================================
    *
  @@ -113,7 +113,7 @@
    * requests directed to a particular servlet.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.20 $ $Date: 2000/10/14 05:21:11 $
  + * @version $Revision: 1.21 $ $Date: 2000/10/14 21:43:54 $
    */
   
   public final class StandardContext
  @@ -1813,9 +1813,8 @@
   	// Stop accepting requests temporarily
   	setPaused(true);
   
  -	// Shut down the current version of the relevant components
  +	// Shut down the current version of all active servlets
   	Container children[] = findChildren();
  -
   	for (int i = 0; i < children.length; i++) {
   	    Wrapper wrapper = (Wrapper) children[i];
   	    if (wrapper instanceof Lifecycle) {
  @@ -1829,9 +1828,18 @@
   	    }
   	}
   
  +        // Unload sessions to persistent storage, if supported
  +        try {
  +            getManager().unload();
  +        } catch (Throwable t) {
  +            log(sm.getString("standardContext.managerUnload"), t);
  +        }
  +
  +        // Shut down filters and application event listeners
  +        filterStop();
           listenerStop();
  -        setApplicationListeners(null);
   
  +        // Shut down our session manager
   	if ((manager != null) && (manager instanceof Lifecycle)) {
   	    try {
   		((Lifecycle) manager).stop();
  @@ -1840,6 +1848,7 @@
   	    }
   	}
   
  +        // Shut down our application class loader
   	if ((loader != null) && (loader instanceof Lifecycle)) {
   	    try {
   		((Lifecycle) loader).stop();
  @@ -1848,16 +1857,16 @@
   	    }
   	}
   
  -	// Start up the new version of the relevant components
  +        // Restart our application class loader
   	if ((loader != null) && (loader instanceof Lifecycle)) {
   	    try {
  -		;	// FIXME - check for new WEB-INF/lib/*.jar files?
   		((Lifecycle) loader).start();
   	    } catch (LifecycleException e) {
   		log(sm.getString("standardContext.startingLoader"), e);
   	    }
   	}
   
  +        // Restart our session manager
   	if ((manager != null) && (manager instanceof Lifecycle)) {
   	    try {
   		((Lifecycle) manager).start();
  @@ -1866,9 +1875,18 @@
   	    }
   	}
   
  -        listenerConfig();
  +        // Restart our application event listeners and filters
           listenerStart();
  +        filterStart();
   
  +        // Load sessions from persistent storage, if supported
  +        try {
  +            getManager().load();
  +        } catch (Throwable t) {
  +            log(sm.getString("standardContext.managerLoad"), t);
  +        }
  +
  +        // Restart our currently defined servlets
   	for (int i = 0; i < children.length; i++) {
   	    Wrapper wrapper = (Wrapper) children[i];
   	    if (wrapper instanceof Lifecycle) {
  @@ -2398,15 +2416,46 @@
   
   
       /**
  +     * Configure and initialize the set of filters for this Context.
  +     * Return <code>true</code> if all filter initialization completed
  +     * successfully, or <code>false</code> otherwise.
  +     */
  +    public boolean filterStart() {
  +
  +        if (debug >= 1)
  +            log("Starting filters");
  +
  +        return (true);  // No actions currently required
  +
  +    }
  +
  +
  +    /**
  +     * Finalize and release the set of filters for this Context.
  +     * Return <code>true</code> if all filter finalization completed
  +     * successfully, or <code>false</code> otherwise.
  +     */
  +    public boolean filterStop() {
  +
  +        if (debug >= 1)
  +            log("Stopping filters");
  +
  +        return (true);  // No actions currently required
  +
  +    }
  +
  +
  +    /**
        * Configure the set of instantiated application event listeners
        * for this Context.  Return <code>true</code> if all listeners wre
        * initialized successfully, or <code>false</code> otherwise.
        */
  -    public boolean listenerConfig() {
  +    public boolean listenerStart() {
   
           if (debug >= 1)
   	    log("Configuring application event listeners");
   
  +        // Instantiate the required listeners
           ClassLoader loader = getLoader().getClassLoader();
   	String listeners[] = findApplicationListeners();
           Object results[] = new Object[listeners.length];
  @@ -2419,45 +2468,39 @@
   		Class clazz = loader.loadClass(listeners[i]);
   		results[i] = clazz.newInstance();
   	    } catch (Throwable t) {
  -		log(sm.getString("contextConfig.applicationListener",
  +		log(sm.getString("standardContext.applicationListener",
   				 listeners[i]), t);
                   ok = false;
   	    }
   	}
  -	if (ok)
  -	    setApplicationListeners(results);
  -        return (ok);
  -    }
  -
  +	if (!ok) {
  +            log(sm.getString("standardContext.applicationSkipped"));
  +            return (false);
  +        }
   
  -    /**
  -     * Send an application start event to all interested listeners.
  -     * Return <code>true</code> if all events were sent successfully,
  -     * or <code>false</code> otherwise.
  -     */
  -    public boolean listenerStart() {
  +        // Send application start events
   
           if (debug >= 1)
   	    log("Sending application start events");
   
  -        boolean ok = true;
  -        Object listeners[] = getApplicationListeners();
  -        if (listeners == null)
  +        setApplicationListeners(results);
  +        Object instances[] = getApplicationListeners();
  +        if (instances == null)
   	    return (ok);
   	ServletContextEvent event =
   	  new ServletContextEvent(getServletContext());
  -	for (int i = 0; i < listeners.length; i++) {
  -            if (listeners[i] == null)
  +	for (int i = 0; i < instances.length; i++) {
  +            if (instances[i] == null)
                   continue;
  -	    if (!(listeners[i] instanceof ServletContextListener))
  +	    if (!(instances[i] instanceof ServletContextListener))
   	        continue;
   	    try {
   	        ServletContextListener listener =
  -		  (ServletContextListener) listeners[i];
  +		  (ServletContextListener) instances[i];
   		listener.contextInitialized(event);
   	    } catch (Throwable t) {
   	        log(sm.getString("standardContext.listenerStart",
  -                                 listeners[i].getClass().getName()), t);
  +                                 instances[i].getClass().getName()), t);
                   ok = false;
   	    }
   	}
  @@ -2498,6 +2541,7 @@
                   ok = false;
   	    }
   	}
  +        setApplicationListeners(null);
           return (ok);
   
       }
  @@ -2510,43 +2554,55 @@
        */
       public void start() throws LifecycleException {
   
  +        if (debug >= 1)
  +            log("Starting");
  +
           // Add missing components as necessary
           if (getResources() == null) {   // (1) Required by Loader
               if (debug >= 1)
  -                log(sm.getString("standardContext.defaultResources"));
  +                log("Configuring default Resources");
               setResources(new FileResources());
           }
           if (getLoader() == null) {      // (2) Required by Manager
               if (debug >= 1)
  -                log(sm.getString("standardContext.defaultLoader"));
  +                log("Configuring default Loader");
               setLoader(new StandardLoader(getParentClassLoader()));
           }
           if (getManager() == null) {     // (3) After prerequisites
               if (debug >= 1)
  -                log(sm.getString("standardContext.defaultManager"));
  +                log("Configuring default Manager");
               setManager(new StandardManager());
           }
   
   	// Standard container startup
  +        if (debug >= 1)
  +            log("Processing standard container startup");
   	super.start();
           if (!available)
               return;
   
  -        // Configure and call application event listeners
  -        if (!listenerConfig()) {
  -            setAvailable(false);
  -            return;
  -        }
  -        if (!listenerStart()) {
  -            setAvailable(false);
  -            return;
  -        }
  +        // Configure and call application event listeners and filters
  +        listenerStart();
  +        filterStart();
   
   	// Create context attributes that will be required
  +        if (debug >= 1)
  +            log("Posting standard context attributes");
   	postWelcomeFiles();
   	postWorkDirectory();
   
  +        // Reload sessions from persistent storage if supported
  +        try {
  +            if (debug >= 1)
  +                log("Loading persisted sessions");
  +            getManager().load();
  +        } catch (Throwable t) {
  +            log(sm.getString("standardContext.managerLoad"), t);
  +        }
  +
           // Collect "load on startup" servlets that need to be initialized
  +        if (debug >= 1)
  +            log("Identifying load-on-startup servlets");
           TreeMap map = new TreeMap();
           Container children[] = findChildren();
           for (int i = 0; i < children.length; i++) {
  @@ -2566,6 +2622,8 @@
           }
   
           // Load the collected "load on startup" servlets
  +        if (debug >= 1)
  +            log("Loading " + map.size() + " load-on-startup servlets");
           Iterator keys = map.keySet().iterator();
           while (keys.hasNext()) {
               Integer key = (Integer) keys.next();
  @@ -2582,6 +2640,9 @@
               }
           }
   
  +        if (debug >= 1)
  +            log("Starting completed");
  +
       }
   
   
  @@ -2592,10 +2653,32 @@
        */
       public void stop() throws LifecycleException {
   
  +        if (debug >= 1)
  +            log("Stopping");
  +
  +        // Mark this application as unavailable while we shut down
           setAvailable(false);
  +
  +        // Unload sessions to persistent storage, if supported
  +        try {
  +            if (debug >= 1)
  +                log("Saving persisted sessions");
  +            getManager().unload();
  +        } catch (Throwable t) {
  +            log(sm.getString("standardContext.managerUnload"), t);
  +        }
  +
  +        // Stop our filters and application listeners
  +        filterStop();
           listenerStop();
  -        setApplicationListeners(null);
  +
  +        // Normal container shutdown processing
  +        if (debug >= 1)
  +            log("Processing standard container shutdown");
           super.stop();
  +
  +        if (debug >= 1)
  +            log("Stopping complete");
   
       }
   
  
  
  
  1.4       +216 -176  jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/session/StandardManager.java
  
  Index: StandardManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/session/StandardManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- StandardManager.java	2000/10/07 19:13:50	1.3
  +++ StandardManager.java	2000/10/14 21:43:54	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/session/StandardManager.java,v 1.3 2000/10/07 19:13:50 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2000/10/07 19:13:50 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/session/StandardManager.java,v 1.4 2000/10/14 21:43:54 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2000/10/14 21:43:54 $
    *
    * ====================================================================
    *
  @@ -78,6 +78,7 @@
   import java.io.ObjectInputStream;
   import java.io.ObjectOutputStream;
   import java.io.ObjectStreamClass;
  +import java.util.ArrayList;
   import java.util.Iterator;
   import javax.servlet.ServletContext;
   import org.apache.catalina.Container;
  @@ -104,7 +105,7 @@
    * <code>stop()</code> methods of this class at the correct times.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2000/10/07 19:13:50 $
  + * @version $Revision: 1.4 $ $Date: 2000/10/14 21:43:54 $
    */
   
   public final class StandardManager
  @@ -319,6 +320,211 @@
       }
   
   
  +    /**
  +     * Load any currently active sessions that were previously unloaded
  +     * to the appropriate persistence mechanism, if any.  If persistence is not
  +     * supported, this method returns without doing anything.
  +     *
  +     * @exception ClassNotFoundException if a serialized class cannot be
  +     *  found during the reload
  +     * @exception IOException if an input/output error occurs
  +     */
  +    public void load() throws ClassNotFoundException, IOException {
  +
  +        if (debug >= 1)
  +            log("Loading persisted sessions");
  +
  +	// Initialize our internal data structures
  +	recycled.clear();
  +	sessions.clear();
  +
  +	// Open an input stream to the specified pathname, if any
  +	File file = file();
  +	if (file == null)
  +	    return;
  +	if (debug >= 1)
  +	    log(sm.getString("standardManager.loading", pathname));
  +	FileInputStream fis = null;
  +	ObjectInputStream ois = null;
  +	Loader loader = null;
  +	ClassLoader classLoader = null;
  +	try {
  +	    fis = new FileInputStream(file.getAbsolutePath());
  +	    BufferedInputStream bis = new BufferedInputStream(fis);
  +	    if (container != null)
  +		loader = container.getLoader();
  +	    if (loader != null)
  +		classLoader = loader.getClassLoader();
  +	    if (classLoader != null)
  +		ois = new CustomObjectInputStream(bis, classLoader);
  +	    else
  +		ois = new ObjectInputStream(bis);
  +	} catch (FileNotFoundException e) {
  +            if (debug >= 1)
  +                log("No persisted data file found");
  +	    return;
  +	} catch (IOException e) {
  +	    if (ois != null) {
  +		try {
  +		    ois.close();
  +		} catch (IOException f) {
  +		    ;
  +		}
  +		ois = null;
  +	    }
  +	    throw e;
  +	}
  +
  +	// Load the previously unloaded active sessions
  +	synchronized (sessions) {
  +	    try {
  +		Integer count = (Integer) ois.readObject();
  +		int n = count.intValue();
  +                if (debug >= 1)
  +                    log("Loading " + n + " persisted sessions");
  +		for (int i = 0; i < n; i++) {
  +		    StandardSession session = new StandardSession(this);
  +                    session.readObjectData(ois);
  +		    session.setManager(this);
  +		    sessions.put(session.getId(), session);
  +		}
  +	    } catch (ClassNotFoundException e) {
  +		if (ois != null) {
  +		    try {
  +			ois.close();
  +		    } catch (IOException f) {
  +			;
  +		    }
  +		    ois = null;
  +		}
  +		throw e;
  +	    } catch (IOException e) {
  +		if (ois != null) {
  +		    try {
  +			ois.close();
  +		    } catch (IOException f) {
  +			;
  +		    }
  +		    ois = null;
  +		}
  +		throw e;
  +	    }
  +	}
  +
  +	// Close the input stream
  +	try {
  +	    ois.close();
  +	} catch (IOException f) {
  +	    ;
  +	}
  +
  +        // Delete the persistent storage file
  +        file.delete();
  +
  +        if (debug >= 1)
  +            log("Loading complete");
  +
  +    }
  +
  +
  +    /**
  +     * Save any currently active sessions in the appropriate persistence
  +     * mechanism, if any.  If persistence is not supported, this method
  +     * returns without doing anything.
  +     *
  +     * @exception IOException if an input/output error occurs
  +     */
  +    public void unload() throws IOException {
  +
  +        if (debug >= 1)
  +            log("Unloading persisted sessions");
  +
  +	// Open an output stream to the specified pathname, if any
  +	File file = file();
  +	if (file == null)
  +	    return;
  +	if (debug >= 1)
  +	    log(sm.getString("standardManager.unloading", pathname));
  +	FileOutputStream fos = null;
  +	ObjectOutputStream oos = null;
  +	try {
  +	    fos = new FileOutputStream(file.getAbsolutePath());
  +	    oos = new ObjectOutputStream(new BufferedOutputStream(fos));
  +	} catch (IOException e) {
  +	    if (oos != null) {
  +		try {
  +		    oos.close();
  +		} catch (IOException f) {
  +		    ;
  +		}
  +		oos = null;
  +	    }
  +	    throw e;
  +	}
  +
  +	// Write the number of active sessions, followed by the details
  +        ArrayList list = new ArrayList();
  +	synchronized (sessions) {
  +            if (debug >= 1)
  +                log("Unloading " + sessions.size() + " sessions");
  +	    try {
  +		oos.writeObject(new Integer(sessions.size()));
  +		Iterator elements = sessions.values().iterator();
  +		while (elements.hasNext()) {
  +		    StandardSession session =
  +                        (StandardSession) elements.next();
  +                    list.add(session);
  +                    session.writeObjectData(oos);
  +		}
  +	    } catch (IOException e) {
  +		if (oos != null) {
  +		    try {
  +			oos.close();
  +		    } catch (IOException f) {
  +			;
  +		    }
  +		    oos = null;
  +		}
  +		throw e;
  +	    }
  +	}
  +
  +	// Flush and close the output stream
  +	try {
  +	    oos.flush();
  +	    oos.close();
  +	    oos = null;
  +	} catch (IOException e) {
  +	    if (oos != null) {
  +		try {
  +		    oos.close();
  +		} catch (IOException f) {
  +		    ;
  +		}
  +		oos = null;
  +	    }
  +	    throw e;
  +	}
  +
  +        // Expire all the sessions we just wrote
  +        if (debug >= 1)
  +            log("Expiring " + list.size() + " persisted sessions");
  +        Iterator expires = list.iterator();
  +        while (expires.hasNext()) {
  +            StandardSession session = (StandardSession) expires.next();
  +            try {
  +                session.expire();
  +            } catch (Throwable t) {
  +                ;
  +            }
  +        }
  +
  +        if (debug >= 1)
  +            log("Unloading complete");
  +
  +    }
  +
  +
       // ------------------------------------------------------ Lifecycle Methods
   
   
  @@ -358,6 +564,9 @@
        */
       public void start() throws LifecycleException {
   
  +        if (debug >= 1)
  +            log("Starting");
  +
   	// Validate and update our current component state
   	if (started)
   	    throw new LifecycleException
  @@ -365,9 +574,6 @@
   	lifecycle.fireLifecycleEvent(START_EVENT, null);
   	started = true;
   
  -	// Load any previously persisted sessions
  -	load();
  -
   	// Start the background reaper thread
   	threadStart();
   
  @@ -385,6 +591,9 @@
        */
       public void stop() throws LifecycleException {
   
  +        if (debug >= 1)
  +            log("Stopping");
  +
   	// Validate and update our current component state
   	if (!started)
   	    throw new LifecycleException
  @@ -395,9 +604,6 @@
   	// Stop the background reaper thread
   	threadStop();
   
  -	// Save any currently active sessions
  -	unload();
  -
   	// Expire all active sessions
   	Session sessions[] = findSessions();
   	for (int i = 0; i < sessions.length; i++) {
  @@ -472,98 +678,6 @@
   
   
       /**
  -     * Load any currently active sessions that were previously unloaded
  -     * to the specified persistence file, if any.
  -     *
  -     * @exception LifecycleException if a fatal error is encountered
  -     */
  -    private void load() throws LifecycleException {
  -
  -	// Initialize our internal data structures
  -	recycled.clear();
  -	sessions.clear();
  -
  -	// Open an input stream to the specified pathname, if any
  -	File file = file();
  -	if (file == null)
  -	    return;
  -	if (debug >= 1)
  -	    log(sm.getString("standardManager.loading", pathname));
  -	FileInputStream fis = null;
  -	ObjectInputStream ois = null;
  -	Loader loader = null;
  -	ClassLoader classLoader = null;
  -	try {
  -	    fis = new FileInputStream(file.getAbsolutePath());
  -	    BufferedInputStream bis = new BufferedInputStream(fis);
  -	    if (container != null)
  -		loader = container.getLoader();
  -	    if (loader != null)
  -		classLoader = loader.getClassLoader();
  -	    if (classLoader != null)
  -		ois = new CustomObjectInputStream(bis, classLoader);
  -	    else
  -		ois = new ObjectInputStream(bis);
  -	} catch (FileNotFoundException e) {
  -	    return;
  -	} catch (IOException e) {
  -	    if (ois != null) {
  -		try {
  -		    ois.close();
  -		} catch (IOException f) {
  -		    ;
  -		}
  -		ois = null;
  -	    }
  -	    throw new LifecycleException("load/open: IOException", e);
  -	}
  -
  -	// Load the previously unloaded active sessions
  -	synchronized (sessions) {
  -	    try {
  -		Integer count = (Integer) ois.readObject();
  -		int n = count.intValue();
  -		for (int i = 0; i < n; i++) {
  -		    StandardSession session = new StandardSession(this);
  -                    session.readObjectData(ois);
  -		    session.setManager(this);
  -		    sessions.put(session.getId(), session);
  -		}
  -	    } catch (ClassNotFoundException e) {
  -		if (ois != null) {
  -		    try {
  -			ois.close();
  -		    } catch (IOException f) {
  -			;
  -		    }
  -		    ois = null;
  -		}
  -		throw new LifecycleException
  -		    ("load/read: ClassNotFoundException", e);
  -	    } catch (IOException e) {
  -		if (ois != null) {
  -		    try {
  -			ois.close();
  -		    } catch (IOException f) {
  -			;
  -		    }
  -		    ois = null;
  -		}
  -		throw new LifecycleException("load/read: IOException", e);
  -	    }
  -	}
  -
  -	// Close the input stream
  -	try {
  -	    ois.close();
  -	} catch (IOException f) {
  -	    ;
  -	}
  -
  -    }
  -
  -
  -    /**
        * Invalidate all sessions that have expired.
        */
       private void processExpires() {
  @@ -583,80 +697,6 @@
   	    if (timeIdle >= maxInactiveInterval)
   		session.expire();
   	}
  -    }
  -
  -
  -    /**
  -     * Save any currently active sessions in the specified persistence file,
  -     * if any.
  -     *
  -     * @exception LifecycleException if a fatal error is encountered
  -     */
  -    private void unload() throws LifecycleException {
  -
  -	// Open an output stream to the specified pathname, if any
  -	File file = file();
  -	if (file == null)
  -	    return;
  -	if (debug >= 1)
  -	    log(sm.getString("standardManager.unloading", pathname));
  -	FileOutputStream fos = null;
  -	ObjectOutputStream oos = null;
  -	try {
  -	    fos = new FileOutputStream(file.getAbsolutePath());
  -	    oos = new ObjectOutputStream(new BufferedOutputStream(fos));
  -	} catch (IOException e) {
  -	    if (oos != null) {
  -		try {
  -		    oos.close();
  -		} catch (IOException f) {
  -		    ;
  -		}
  -		oos = null;
  -	    }
  -	    throw new LifecycleException("unload/open: IOException", e);
  -	}
  -
  -	// Write the number of active sessions, followed by the details
  -	synchronized (sessions) {
  -	    try {
  -		oos.writeObject(new Integer(sessions.size()));
  -		Iterator elements = sessions.values().iterator();
  -		while (elements.hasNext()) {
  -		    StandardSession session =
  -                        (StandardSession) elements.next();
  -                    session.writeObjectData(oos);
  -		}
  -	    } catch (IOException e) {
  -		if (oos != null) {
  -		    try {
  -			oos.close();
  -		    } catch (IOException f) {
  -			;
  -		    }
  -		    oos = null;
  -		}
  -		throw new LifecycleException("unload/write: IOException", e);
  -	    }
  -	}
  -
  -	// Flush and close the output stream
  -	try {
  -	    oos.flush();
  -	    oos.close();
  -	    oos = null;
  -	} catch (IOException e) {
  -	    if (oos != null) {
  -		try {
  -		    oos.close();
  -		} catch (IOException f) {
  -		    ;
  -		}
  -		oos = null;
  -	    }
  -	    throw new LifecycleException("unload/close: IOException", e);
  -	}
  -
       }