On 27/05/2010 16:31, Howard Lewis Ship wrote: > I have a question, on behalf of a client, concerning Tomcat clustering > and deserialization, in the context of a Tapestry 5 application. > > Here's the short form: some of the objects that a Tapestry > application may put into the HttpSession will only deserialize > correctly > if the Tapestry application (in the form of a Servlet Filter) has > initialized first ... but it appears that when starting up a Tomcat > instance, > the HttpSession data is deserialized from disk *before* the filter is > initialized.
Is there a specific Tomcat version you're targeting? Session persistence is a Manager Valve function, so AFAIK the deserialisation will occur before Filters (or any other web app stuff, like ServletContextListeners) are started. p > Here's the stack trace: > > ERROR ( ManagerBase:412 ) - IOException while loading > persisted sessions: java.io.InvalidObjectException: Service token for > service 'ProductConfig' can not be converted back into a proxy because > no proxy provider has been registered. This may indicate that an IoC > Registry has not been started yet. > java.io.InvalidObjectException: Service token for service > 'ProductConfig' can not be converted back into a proxy because no > proxy provider has been registered. This may indicate that an IoC > Registry has not been started yet. > at > org.apache.tapestry5.ioc.internal.ServiceProxyToken.readResolve(ServiceProxyToken.java:41) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:597) > at > java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1061) > at > java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1762) > at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) > at > java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947) > at > java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871) > at > java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753) > at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) > at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) > at > org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1407) > at > org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:931) > at > org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:394) > at > org.apache.catalina.session.StandardManager.load(StandardManager.java:321) > at > org.apache.catalina.session.StandardManager.start(StandardManager.java:637) > at > org.apache.catalina.core.ContainerBase.setManager(ContainerBase.java:432) > at > org.apache.catalina.core.StandardContext.start(StandardContext.java:4160) > at > org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) > at org.apache.catalina.core.StandardHost.start(StandardHost.java:736) > at > org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) > at > org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) > at > org.apache.catalina.core.StandardService.start(StandardService.java:448) > at > org.apache.catalina.core.StandardServer.start(StandardServer.java:700) > at org.apache.catalina.startup.Catalina.start(Catalina.java:552) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:597) > at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295) > at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433) > Caused by: java.lang.RuntimeException: Service token for service > 'ProductConfig' can not be converted back into a proxy because no > proxy provider has been registered. This may indicate that an IoC > Registry has not been started yet. > at > org.apache.tapestry5.ioc.internal.SerializationSupport.readResolve(SerializationSupport.java:72) > at > org.apache.tapestry5.ioc.internal.ServiceProxyToken.readResolve(ServiceProxyToken.java:37) > > > The failure occurs inside this code: > > class ServiceProxyToken implements Serializable > { > private final String serviceId; > > ServiceProxyToken(String serviceId) > { > this.serviceId = serviceId; > } > > Object readResolve() throws ObjectStreamException > { > try > { > return SerializationSupport.readResolve(serviceId); > } > catch (Exception ex) > { > ObjectStreamException ose = new > InvalidObjectException(ex.getMessage()); > ose.initCause(ex); > > throw ose; > } > } > > } > > This occurs because the Tapestry IoC container has not been > initialized by the Tapestry Filter yet. > SerializationSupport.readResolve() requires that the Filter be > initialized. > > In case you are curious: these ServiceProxyToken objects are > placeholder for Tapestry IoC services. In Tapestry IoC, every service > implements an interface, and is exposed to user code as an instance of > a proxy. The proxy hides the lifecycle of the service (i.e., to > support just-in-time instantiation), and the proxy is Serializable > where the actual service implementation class is not. > > Sometimes an HttpSession object will hold a reference to a Tapestry > service. When serialized, the proxy serializes a ServiceProxyToken. > When that's deserialized, we get back an equivalent service in the new > server. > > So ... is there a configuration option somewhere to defer loading of > the HttpSession until after the filters are instantiated? Is there > some other mechanism that will support what I want to do? > > Alternately, I'd appreciate some pointers on what code would need to > be modified to support this scenario. It makes a big difference to > Tapestry 5 users who use Tomcat clustering! > >
signature.asc
Description: OpenPGP digital signature