1
votes

I'm trying to get Tomcat to persist my sessions on shutdown. I have already taken care of the requirement that everything I store in the sessions be serializable, and when I run Tomcat under Eclipse, this works fine: when a code change forces Eclipse to reload the webapp, the sessions now survive.

However, when I try to do the same thing in a stand-alone Tomcat, I run into a problem.

I have un-commented the Manager element in ${catalina.base}/conf/context.xml and set the pathname attribute to ${catalina.base}/SESSIONS.ser, and on shutdown, I see the SESSIONS.ser file appear. So far, so good.

But when I restart Tomcat, this appears in catalina.out:

[...]
06-Apr-2017 13:39:52.570 SEVERE [localhost-startStop-1] org.apache.catalina.session.StandardManager.startInternal Exception loading sessions from persistent storage
 java.lang.ClassNotFoundException: com.mycompany.wtt.util.LogoutLogger
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1285)
[...]
06-Apr-2017 13:39:54.158 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive /data/tokken/apache-tomcat-8.5.12/webapps/wtt.war has finished in 1,134 ms
[...]

The class com.mycompany.wtt.util.LogoutLogger is a part of the wtt.war webapp, and apparently, Tomcat tries to deserialize the webapp's session before having loaded the webapp. It looks like this means that I can't put application-specific classes in my session, and that's a big problem, because some of my logic relies on being able to do just that, and create custom behaviors by implementing javax.servlet.http.HttpSessionActivationListener.

Is there a way to make Tomcat deserialize sessions after having loaded the webapps?

Versions: Tomcat 8.5.12, Java 1.8.0_121.

1

1 Answers

1
votes

It turns out that the problem was configuring the Manager in the global context.xml, with an absolute path. This means that when Tomcat reads the serialized session, it doesn't know which webapp it belongs to, and apparently it just tries to load it anyway (into the first webapp it deploys?), and fails because of the application-specific classes.

I got it to work by changing ${catalina.home}/conf/context.xml back to its original state, with the Manager element commented out, and instead added <Manager pathname="${catalina.home}/sessions/wtt.ser"> in the webapp's META-INF/context.xml.

Note that if you simply say pathname="SESSIONS.ser", your sessions will survive server restarts, but they will not survive an app redeploy, because the latter destroys the app's work directory, and this is where sessions with relative pathnames are stored. Saying pathname="${catalina.home}/sessions/wtt.ser" avoids this (but make sure that whatever directory you want your sessions to get written to exists in advance, because Tomcat will not create it for you).