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);
- }
-
}