spring-webflow
spring-webflow copied to clipboard
Reloading classes of objects stored in a flow execution scope results in exception [SWF-354]
Graeme Rocher opened SWF-354 and commented
Currently if you reload a class that exists in flow/flash/conversation scope the exception below is triggered. This is problematic as it can only be corrected by a server restart. I'm not sure what can be done to workaround the cause of the problem but as workaround it would as a minimum be useful to have the ability to clear or invalidate the flow executions that currently exist in the repository with something like:
flowRepository.invalidateAll()
The Exception:
org.springframework.webflow.execution.repository.FlowExecutionRestorationFailureException: A problem occurred restoring the flow execution with key '_c14EB16BC-4442-78AA-139F-54EEA1B24085_k36AE12C7-23F1-602D-96A0-9A0145494C97'; nested exception is org.springframework.webflow.execution.repository.continuation.ContinuationUnmarshalException: IOException thrown deserializing the flow execution stored in this continuation -- this should not happen!; nested exception is java.io.InvalidClassException: BookService; local class incompatible: stream classdesc serialVersionUID = 7711171070262397453, local class serialVersionUID = 1780216400904263477 Caused by: org.springframework.webflow.execution.repository.continuation.ContinuationUnmarshalException: IOException thrown deserializing the flow execution stored in this continuation -- this should not happen!; nested exception is java.io.InvalidClassException: BookService; local class incompatible: stream classdesc serialVersionUID = 7711171070262397453, local class serialVersionUID = 1780216400904263477 Caused by: java.io.InvalidClassException: BookService; local class incompatible: stream classdesc serialVersionUID = 7711171070262397453, local class serialVersionUID = 1780216400904263477 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:546) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1552) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1699) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
Affects: 2.0 M1
Issue Links:
- #122 Add the ability to monitor in-progress flow executions with JMX
Erwin Vervaet commented
The problem is that the object in the serialized continuation snapshot still refers to the old class, before it was updated. We have seen this issue before and I'm not sure there is much we can do about it.
Objects in conversation scope should not suffer from this since they are not inside the continuation snapshot -- i.e. they are not serialized out.
A simple work around is to restart your browser: this will make sure you get a new session, and avoids hitting the old, 'corrupt' snapshots.
Graeme Rocher commented
As I mentioned in the post, a workaround from my perspective would be to be able to invalidate all serialized flows stored in the repository. This is the fix I need to get this working without browser/server restarts
Erwin Vervaet commented
Do you think a 'clear' call via JMX would be sufficient? #122 is asking for something like that.
Graeme Rocher commented
So you want users to clear flows via some JMX management console? No I need a programmatic way to do it.
Antranig Basman commented
The particular root exception class seems "highly recognisable", and it would seem reasonably straightforward to diagnose this situation by walking the "cause" stack and invalidate just the particular continuation snapshot that is involved. I'm interested though in how you are managing to reload the class without reloading the entire webapp - do you have Spring held at some higher ClassLoader level?