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
