2

I have a very bizarre problem with a Spring 3.5, Webflow 2.2 application, running in Tomcat (6.0.32)

Part of the webflow calls to retrieve a list of objects. This list is placed in a viewScope object for use by a JSP view. Each object in this list inherits from a base class that contains some common fields.

The webflow then forwards to a JSP view that displays the contents of this list, by writing out all the objects.

When I run this from a stand-alone Tomcat, the fields on the base class are all somehow set to null. I have debugged and confirmed the list is built correctly from the code called by the webflow . So somewhere between putting the list into the webflow view scope, and then it later being retrieved by the JSP, the base class fields are being reset to null.

The REALLY bizarre part of the problem is that the app runs perfectly if I start and run Tomcat from within Intellij IDEA. I've tried various JDKs and Tomcat versions, and all have the same issue.

It appears to be a webflow problem (improper serialization maybe?) that's sensitive to whether Tomcat has been started from within IntelliJ.

What is IntelliJ doing that could cause Java serialization to misbehave?

David
  • 962
  • 2
  • 10
  • 29
  • Also - if some kind soul could point me at the classes in the Spring Webflow sources the deal with serializing/deseralizing objects in and out of view scope, that would be really useful. Thanks. – David Apr 11 '11 at 16:47
  • It does appear to be a serialization bug. The Spring SerializedFlowExectionSnapshot object contains a byte array containing the flowExecutionData - a serialized form of everything in view/flow scope. When the bug is evident this array is smaller than when the bug is not showing. Some of the data is missing! – David Apr 11 '11 at 20:15

2 Answers2

4

Well, I haven't found the exact underlying cause, but I do have a work-around. I simply implemented the custom object serialization methods - private void writeObject() and readObject() - on the objects that were being mysteriously not serialized properly, and everything started working. There are only a couple of simple types (couple of longs and a String) in the base class, so it's nothing complex.

Just to clarify (in case any one is interessted) - I had a data object used by a form in my web-app. This object contains a map of attribute objects, where each attribute object is based on a class hierarchy something like this:

Attribute class -> shared base class -> root base class

All this data gets persisted into a byte-array by Spring web-flow, then un-persisted when the web-flow calls the view. In my case, the fields of the root base class were not being persisted by the default mechanism.

I still don't know exactly exactly why though. And I still don't know why, when I started Tomcat from within IntelliJ, the serialization WORKED as expected. Very strange.


UPDATE: Found the culprit. A really bad Ant build script hiding a missing "serializable" interface marker.

The system in question is actually quite large, and has a nasty, hard-to-follow Ant build script. I'd assumed it was doing a full, proper clean build. In the class hierarchy I showed above, the Attribute class and the Root Base Class were in different jars. And the jar containing the root base class was in fact being cached and not rebuilt properly.

The older (incorrect) version of the base class being deployed did not have the "serializable" marker interface (the Attribute class did). So of course, its fields were not being serialized. When I tested from within IntelliJ, it was doing the build and deploy directly from my sources.

I feel really dumb now.

David
  • 962
  • 2
  • 10
  • 29
1

I've seen this sort of phenomena with various IDE's when I was building the WAR with the IDE, and when running in the IDE it was using different cached classes than when running outside of the IDE. To narrow down the phenomena, try the following:

If you haven't already, create an Ant or Maven build for your project. Clean up all .class files and other artifacts, shut down intellij, build the WAR with Ant or Maven, and try deploying that to Tomcat. See if you get the odd behavior.

Next, try starting a Tomcat server within Intellij, but don't deploy your application to it from within Intellij. Deploy your application to it externally by dropping your war into the Intellij Tomcat instance on the filesystem.

Lastly, don't start Tomcat from within Intellij, but start it externally and connect to it using remote debugging instead, then see if the issue occurs. See the following for how to configure remote debugging: http://wiki.apache.org/tomcat/FAQ/Developing.

squawknull
  • 5,131
  • 2
  • 17
  • 27
  • Thanks for the comments, but just so it's clear what the problem is - IntelliJ appears to be magically "fixing" the bug. If I use an Ant script to do a clean build and deploy to a stand-alone Tomcat I get the bug (and can see it manifest itself if I attach with a remote debug session). If I start Tomcat from within IntelliJ then the bug does NOT occur. As far as I can see, IntelliJ spawns a new CMD.EXE from which to start Tomcat, and the only runtime difference is a Groovy jar attached as an Agent for doing hot redeploys. I'm baffled as to how this could affect serialization of classes. – David Apr 14 '11 at 08:28
  • It wasn't the IDE that was incorrectly caching the classes, but a nasty Ant build. Otherwise, you were just about right... – David Apr 15 '11 at 10:05