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. 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! -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org