On 03/12/2024 22:30, Pascal Rigaux wrote:
Oops, I missed something :

When you use <Manager pathname="xxx"> or <Store className="org.apache.catalina.session.FileStore" directory="xxx"/> the behaviour is different if the pathname/directory is absolute or relative.

If it is relative, it is stored relative to each applications temporary work directory, and handled with each application classLoader, and it works perfectly.

Maybe this should be mentionned more clearly in the documentation? Maybe display a warning log for absolute pathname/directory in global context.xml?

Nope. That isn't what is going on here.

Think about what you have configured for a moment.

Anything you configure in the global context.xml file is equivalent to adding the same configuration to each context.xml for each deployed web application.

If you configure an absolute path, you are telling each web application to use the same file to persist session data. That is going to cause all sorts of problems.

1. As each web application stops it will overwrite the persistence file. So only the last session to stop will persist data.

2. When each web application starts, and assuming you have web application specific classes in the persistence file, only one of those web applications will be able to load that file - the one that wrote it. All the others will fail with the stack trace you have observed.

The Manager/Store component can't easily determine if it is being configured from the global, host or context level context.xml file.

The root cause here is configuration error - configuring multiple web applications to use the same file for session persistence.

Mark



cu,
Pascal R.

On 03/12/2024 16:36, Pascal Rigaux wrote:
Hi,

I have bug https://bz.apache.org/bugzilla/show_bug.cgi?id=48007 on recent tomcats.

To reproduce one must:
- use PersistentManager in global context.xml
- have an object in session only available through a webapp class loader
- wait for manager backgroundProcess to call PersistentManagerBase.processExpires > Storebase.processExpires
   (by default, 6 * 10 seconds)

=> it fails to unserialize, and removes the session from FileStore.


My technical understanding of the issue:

getObjectInputStream() is using Thread.currentThread().getContextClassLoader()
which is set in FileStore.load() using current Context classLoader

This is ok when called by manager.findSession(...) , but Storebase.processExpires() is using current context

=> it is ok when PersistentManager is in the application specific
context.xml
=> it is wrong when PersistentManager is in global context.xml

One can workaround the issue by moving <PersistentManager> from global context.xml to webapp context.xml , as explained here : https://dev.wicket.apache.narkive.com/KXmPFrnQ/ problems-with-tomcat-session-persistence-classnotfoundexception-of- secondlevelcachesessionstore

If you use PersistentValve, another workaround is to use <Manager processExpiresFrequency="9999999"> + an external cron.


Stacktrace with tomcat 9:

SEVERE [Catalina-utility-3] org.apache.catalina.session.StoreBase.processExpires Error processing session expiration for key [xxx]          java.lang.ClassNotFoundException: org.springframework.security.core.context.SecurityContextImpl                  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1339)                  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1148)
                 at java.base/java.lang.Class.forName0(Native Method)
                 at java.base/java.lang.Class.forName(Unknown Source)
                 at org.apache.catalina.util.CustomObjectInputStream.resolveClass(CustomObjectInputStream.java:149)                  at java.base/ java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)                  at java.base/ java.io.ObjectInputStream.readClassDesc(Unknown Source)                  at java.base/ java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)                  at java.base/ java.io.ObjectInputStream.readObject0(Unknown Source)                  at java.base/ java.io.ObjectInputStream.readObject(Unknown Source)                  at java.base/ java.io.ObjectInputStream.readObject(Unknown Source)                  at org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1268)                  at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:846)                  at org.apache.catalina.session.FileStore.load(FileStore.java:203)                  at org.apache.catalina.session.StoreBase.processExpires(StoreBase.java:138)                  at org.apache.catalina.session.PersistentManagerBase.processExpires(PersistentManagerBase.java:409)                  at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:595)                  at org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:4823)
                 ..........

It would be nice in my use-cases to be able to configure globally PersistentManager. It would be enough for us to have an option to disable Storebase.processExpires(), but it may be somewhat ugly...

cu
Pascal Rigaux.



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to