You may also find the following filter helpful. I wrote it to find those
session members who were not serializable.
Tim
package tim.lucia;
import java.io.IOException;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* J2EE "Filter" to dump session info
*
* @author tim.lucia
*/
public class SessionDumper implements Filter
{
private final static Log logger =
LogFactory.getLog(SessionDumper.class);
private final static String defaultSessionStatusFormat = "SessionID
[{0}] created {1, date, yyyy-MMM-dd hh:mm a zzz} last {2, date, yyyy-MMM-dd
hh:mm a zzz}";
private final static String defaultSessionObjectFormat = "[{0}] =
[{1}]";
private final static boolean defaultShowSerializable = false;
private static String sessionStatusFormat = defaultSessionStatusFormat;
private static String sessionObjectFormat = defaultSessionObjectFormat;
private static boolean showSerializable = defaultShowSerializable;
/**
* Container startup notification
*/
public void init(FilterConfig arg0) throws ServletException
{
if (logger.isDebugEnabled()) {
logger.debug("init(): " + arg0);
}
String value = arg0.getInitParameter("sessionStatusFormat");
if (null != value) {
sessionStatusFormat = value;
}
value = arg0.getInitParameter("sessionObjectFormat");
if (null != value) {
sessionObjectFormat = value;
}
value = arg0.getInitParameter("showSerializable");
if (null != value) {
showSerializable = Boolean.valueOf(value).booleanValue();
}
}
/**
* Container shutdown notification
*/
public void destroy()
{
logger.debug("destroy()");
}
/**
* Process the container's filter request.
* @param request - Request object
* @param response - response object
* @param chain - next filter in the chain.
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
if (logger.isDebugEnabled()) {
HttpServletRequest httpRequest = (HttpServletRequest)request;
String uri = httpRequest.getRequestURI();
chain.doFilter(request, response);
logger.debug("Session for " + uri);
dumpSession(request);
}
else {
chain.doFilter(request, response);
}
}
private void dumpSession(ServletRequest request)
{
if (request instanceof HttpServletRequest) {
HttpSession session =
((HttpServletRequest)request).getSession(false);
if (null != session) {
final String sessionID = session.getId();
final long createdAt = session.getCreationTime();
final long lastAccessed =
session.getLastAccessedTime();
if (logger.isDebugEnabled()) {
final String sessionStatus =
MessageFormat.format(sessionStatusFormat, new
Object[] { sessionID, new Date(createdAt), new Date(lastAccessed) });
logger.debug(sessionStatus);
}
Enumeration enumerator =
session.getAttributeNames();
Collection serializable = new LinkedList();
Collection nonSerializable = new LinkedList();
while (enumerator.hasMoreElements()) {
final String key =
(String)enumerator.nextElement();
final Object value =
session.getAttribute(key);
final String message =
MessageFormat.format(sessionObjectFormat, new Object[] {key, value});
if (value instanceof Serializable) {
serializable.add(message);
}
else {
nonSerializable.add(message);
}
if (showSerializable) {
dumpList("====>Serializable<====",
serializable);
}
dumpList("====>Non-Serializable<====",
nonSerializable);
}
}
}
}
private void dumpList(String header, Collection list)
{
if (list.size() > 0) {
logger.debug(header);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
logger.debug(iterator.next());
}
}
}
}
-----Original Message-----
From: Reinhard Moosauer [mailto:[EMAIL PROTECTED]
Sent: Wednesday, March 15, 2006 3:58 AM
To: Tomcat Users List
Subject: Re: manager-remove/undeploy without losing sessions
i filed an enhancement request for this issue here:
http://issues.apache.org/bugzilla/show_bug.cgi?id=38975
Rodrigo,
The mentioned session serialization is always activated and works fully
automatic. But only if all requirements to your applicatin are met:
All objects, which are ever bound to a HttpSession have to implement
'Serializable' and should also have a serialVersionUid the enable compatible
changes. And all objects which are referenced by the session-attributes.
In practice there some more requirements:
- follow the guidelines for compatible changes to serializable objects
(see jdk-docs)
- make all references to unserializable objects 'transient'
- Implement a public no-args constructor to initialize all these transient
members correctly. (Sometimes necessary for loggers or db-connections)
- Check 'catalina.out' for NotSerializableExceptions and fix them.
A nice side effect of these guidlines is: you can use tomcat's clustering
facilities quite easily, because it only requires serializable sessions!
Hope that helps,
Reinhard
Am Dienstag, 14. März 2006 16:29 schrieb Asensio, Rodrigo:
> Reinhard, thanks for the tip, is that option (serialize sessions) in
> the manager or in the admin ? Or it is a value that need to be changed
> manually in server.xml or any props file ?
>
> Thanks
>
> Rodrigo Asensio
>
> -----Original Message-----
> From: Reinhard Moosauer [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, March 14, 2006 9:04 AM
> To: Tomcat Users List
> Subject: Re: manager-remove/undeploy without losing sessions
>
> Hi List,
>
> I found something, that looked promising, but did not work.
> Developers, please look, this could be a bug:
>
> The deploy-task has an attribute "update", removes the context before
> re-installing it. I hoped that this one would do what I want.
>
> But unfortunately, it is equivalent to undeploy/deploy so my sessions
> are gone again. :-(
>
> Maybe I have to clarify, what I am doing with my sessions (for Rodrigo):
>
> I have all session-attribute in my application serializable, so that
> tomcat can save all session data to disk when the context or tomcat
> itself is stopped. At startup these serialized data is being read back
> by tomcat automatically. As a result, users can coutinue their work
> exactly where the are.
> (Except that the application is not available for 1-2 seconds. But it
> is still unlikely that a users fires a request just in this moment, at
> least for medium-frequency apps) Formerly, the persisted session data
> survived the remove, so I could re-install the app.
>
> Please help!
>
> Reinhard
>
> Am Dienstag, 14. März 2006 13:53 schrieb Reinhard Moosauer:
> > Hello List,
> >
> > recently I upgraded from tomcat 5.5.9 to 5.5.15 Since then, all my
> > sessions are lost after a remove/install via the manager.
> >
> > The problem is the following:
> > I installed a war-file, which is copied to the webapps-folder during
> > manager-install. When I want to replace the war with a new version,
> > I _have_ to undeploy, which deletes my persistent sessions too.
> >
> > How can I get back the smooth behavior of 5.5.9, which allowed me an
> > application update on the fly without disturbing user sessions?
> >
> > many thanks in advance for your advice
> >
> > Reinhard
> >
> > --------------------------------------------------------------------
> > - To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
> This message (including any attachments) contains confidential and/or
> proprietary information intended only for the addressee.
> Any unauthorized disclosure, copying, distribution or reliance on the
> contents of this information is strictly prohibited and may constitute
> a violation of law. If you are not the intended recipient, please
> notify the sender immediately by responding to this e-mail, and delete
> the message from your system. If you have any questions about this
> e-mail please notify the sender immediately.
>
> Ce message (ainsi que les eventuelles pieces jointes) est
> exclusivement adresse au destinataire et contient des informations
> confidentielles. La copie, la communication ou la distribution du
> contenu de ce message sans l'accord prealable de l'expediteur sont
> strictement interdits et peuvent constituer un delit. Si vous n'etes
> pas destinataire de ce message, merci de le detruire et d'avertir
> l'expediteur. Si vous avez des questions se rapportant a ce courrier
> electronique, merci de bien vouloir notifier l'expediteur
> immediatement.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]