Received: (qmail 77573 invoked by uid 501); 18 May 2000 11:41:58 -0000 Message-Id: <20000518114158.77572.qmail@locus.apache.org> Date: 18 May 2000 11:41:58 -0000 From: Babak Kunze Reply-To: bk@cm-ag.de To: submit@bugz.apache.org Subject: Session serialization fails! X-Send-Pr-Version: 3.110 >Number: 6099 >Category: mod_jserv >Synopsis: Session serialization fails! >Confidential: no >Severity: critical >Priority: medium >Responsible: jserv >State: open >Class: sw-bug >Submitter-Id: apache >Arrival-Date: Thu May 18 04:50:00 PDT 2000 >Closed-Date: >Last-Modified: >Originator: bk@cm-ag.de >Release: 1.3.12 >Organization: apache >Environment: All machines (plattform independent) >Description: When JServServletManager serializes sessions upon zone reload, the following problem occurs: If a session does not have any variables associated with it (through putValue), the whole serialization fails. The reason is a bug in JServSession, that allways assumes that the sessionData Hashtable's size is allway greater than "0". In allmost all cases this is true. But if a new session was created right before the "writeObject" call than the following code fragment causes an IllegalArgumentException: public class JServSession implements HttpSession, JServLogChannels, Serializable { . . . private synchronized void writeObject(ObjectOutputStream stream) throws IOException { // Write the session identifier stream.writeObject(id); . . . // write out the user session data that is Serializable Hashtable saveData = new Hashtable(sessionData.size()); . . . } } Since sessionData.size() returns "zero", which is not a valid argument for the Hashtable constructor. >How-To-Repeat: Just create a new session and touch a servlet to cause zone reload. All sessions are lost as a consequence. >Fix: writeObject code in JServSession could go like this: private synchronized void writeObject(ObjectOutputStream stream) throws IOException { // Write the session identifier stream.writeObject(id); // Write the other scalar instance variables stream.writeObject(new Date(creationTime)); stream.writeObject(new Date(lastAccessTime)); stream.writeObject(new Boolean(valid)); stream.writeObject(new Boolean(isNew)); if (sessionData.size() > 0) { // write out the user session data that is Serializable Hashtable saveData = new Hashtable(sessionData.size()); String key = null; Object value = null; Enumeration keys = sessionData.keys(); while(keys.hasMoreElements()) { key = (String) keys.nextElement(); value = sessionData.get(key); if (value instanceof Serializable) { saveData.put(key, value); } // if we can't serialize the object stored in // the session, then check to see if it implements // HttpSessionBindingListener and then call its // valueUnbound method, allowing it to save its state // correctly instead of just being lost into the etherworld else if (value instanceof HttpSessionBindingListener ) { try { HttpSessionBindingListener event = (HttpSessionBindingListener) sessionData.get(key); event.valueUnbound(new HttpSessionBindingEvent(this, key)); } catch (Exception e) { } } } stream.writeObject(saveData); } else stream.writeObject(sessionData); } >Release-Note: >Audit-Trail: >Unformatted: [In order for any reply to be added to the PR database, you need] [to include in the Cc line and make sure the] [subject line starts with the report component and number, with ] [or without any 'Re:' prefixes (such as "general/1098:" or ] ["Re: general/1098:"). If the subject doesn't match this ] [pattern, your message will be misfiled and ignored. The ] ["apbugs" address is not added to the Cc line of messages from ] [the database automatically because of the potential for mail ] [loops. If you do not include this Cc, your reply may be ig- ] [nored unless you are responding to an explicit request from a ] [developer. Reply only with text; DO NOT SEND ATTACHMENTS! ]