Hello Chris,

On Tue, May 28, 2024 at 6:38 PM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> Jakub,
>
> On 5/24/24 09:31, Jakub Królikowski wrote:
> > On Fri, May 24, 2024 at 11:23 AM Mark Thomas <ma...@apache.org> wrote:
> >
> >> Can you provide the simplest web application (with source) that
> >> replications the problem?
> >>
> >> Mark
> >>
> >>
> >> On 23/05/2024 23:45, Jakub Królikowski wrote:
> >>> Hi,
> >>>
> >>> I'm working with Tomcat 10.1.
> >>>
> >>> When a user starts using the store in my web application, I save the
> >>> ShopCart object on the "cart" session attribute.
> >>> I want the "cart" attributes to return to the session after restarting
> >> the
> >>> app.
> >>>
> >>>
> >>> To enable session persistence I added
> >>>
> >>> <Manager pathname="SESSIONS.ser" />
> >>>
> >>> to the Context. It loads the StandardManager.
> >>>
> >>> And this works fine - after reload / restart the object "ShopCart" is
> >> back
> >>> in the session.
> >>>
> >>>
> >>>
> >>> I want to experiment with PersistentManager. Tomcat docs says: "
> >>> The persistence across restarts provided by the *StandardManager* is a
> >>> simpler implementation than that provided by the *PersistentManager*.
> If
> >>> robust, production quality persistence across restarts is required then
> >> the
> >>> *PersistentManager* should be used with an appropriate configuration.
> >>>
> >>> "
> >>>
> >>> I hope for a Listener of deserialization of the session attributes.
> >>>
> >>> The new Manager configuration looks like this:
> >>>
> >>> <Manager className="org.apache.catalina.session.PersistentManager"
> >>> maxActiveSessions="2" saveOnRestart="true">
> >>>
> >>> <Store className="org.apache.catalina.session.FileStore" directory=
> >>> "c:\tomcat10\sessionperm"/>
> >>>
> >>> </Manager>
> >>>
> >>> But it doesn't work. After restart I get this exception:
> >>>
> >>>
> >>> java.lang.ClassNotFoundException: ....ShopCart
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1144)
> >>>
> >>> at java.base/java.lang.Class.forName0(Native Method)
> >>>
> >>> at java.base/java.lang.Class.forName(Class.java:534)
> >>>
> >>> at java.base/java.lang.Class.forName(Class.java:513)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.util.CustomObjectInputStream.resolveClass(CustomObjectInputStream.java:158)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2061)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readClassDesc(ObjectInputStream.java:1927)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2252)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readObject0(ObjectInputStream.java:1762)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readObject(ObjectInputStream.java:540)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readObject(ObjectInputStream.java:498)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1198)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:831)
> >>>
> >>> 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:587)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:4787)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1172)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1154)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
> >>
> >
> >
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
> >>>
> >>> at
> >>>
> >>
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
> >>>
> >>> at java.base/java.lang.Thread.run(Thread.java:1583)
> >>>
> >>>
> >>> I guess this means that the two managers use ClassLoader differently.
> >>> How to get the PersistentManager to work in this case?
> >>>
> >>> Best regards,
> >>> --
> >>> Jakub Królikowski
> >>>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> >> For additional commands, e-mail: users-h...@tomcat.apache.org
> >>
> >>
> >
> > Hi Mark,
> > It seems to me that this can be tested on any application.
> > In Tomcat 10.1, if any session attribute is an instance of a new public
> > class (unknown to Tomcat and to Tomcat class loader), implementing
> > java.io.Serializable,
> > then on reloading the application PersistanceManager (configured as in
> the
> > first message) crashes with ClassNotFoundException. StandardManager
> works.
> > I don't know if this problem occurred in earlier versions of Tomcat.
> >
> > If you fail to reproduce this bug, let me know, I will prepare a simple
> web
> > app.
>
> Where is your <Manager> configuration located? It *should* be inside
> your <Context> located in META-INF/context.xml in your web application.
> If it's in there, then everything it does should be in the context (and
> ClassLoader) of your web application -- where your classes should be
> locatable.
>
> If you have it anywhere else, it probably won't work the way you expect
> it to work.
>
> -chris
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Yes, you are right! Thank you for this hint!
I have configured <Manager> in <tomcat-dir>/conf/server.xml.
And indeed - interestingly, StandardManager, works correctly even there!
PersistentManager, however, does not.
After moving the configuration to <app-dir>/META-INF/context.xml, both
managers work fine.
It may be worth mentioning this in the documentation:
https://tomcat.apache.org/tomcat-10.1-doc/config/manager.html#Persistence_Across_Restarts

Jakub

Reply via email to