Filtering Context Properties
dward Feb 26, 2013 1:45 PMAn issue was raised on a user forum thread "Load Balancing Question", which in turn, prompted the creation of this jira: SWITCHYARD-1325.
Boiled down, a Camel object finds it's way into a Context Property, and that Camel object cannot be deserialized since it doesn't have a no-arg constructor. We have a mechanism for classes we control, where we can annotate the class to define de/serialization strategy. We also have a mechanism for "special" JDK classes (like InputStreams, DataSources, Collections, etc.) to handle de/serialization as we walk the object graph.
Obviously, we can't add our annotations to Camel classes, and I personally don't want to add a bazillion "else if" blocks to handle every possible specific type of Camel object. That is simply not maintainable long-term. So, I'm wondering if the following is an option...
What if we were to filter non-serializable classes? We have a couple different options to do this:
- In our SwitchYardRemotingServlet, we already do a context.copy(), which internally will not copy properties that are marked with a "transient" label. We can add to our CamelContextMapper to automatically add the transient label to any properties it maps that are custom org.apache.camel.* objects. The properties will still get mapped, but if the runtime execution crosses a process boundry (specifically, goes through our remoting layer), at that point the properites get dropped.
- Same as #1, but we only add the label to camel objects that don't have no-arg constructors. Personally I don't like this option much, as then it will be confusing as hell to people why some Camel objects survived crossing the process boundry, but others didn't.
- We can add smarts to our ContextProperty implementation, such that any property that gets created will have it's value introspected, and any value that we know we can't handle during serialization will be automatically marked with a label of "transient". It's actually pretty straightforward to figure out if a value is de/serializable:
- It has a no-arg constructor (public/private doesn't matter, as we circumvent that via reflection), or...
- It is marked with our serialization @Strategy annotation, or...
- It is one of the (few) "special" types we handle in our serialization NodeBuilder class (InputStreams, DataSources, Collections, etc.), or...
- It is one of the basic (wrapper) java types (String, Boolean, Number, Date, etc.)
#3 would still have the same problem that I mentioned in #2, but we can do both #1 and #3...
Thoughts? I would like to fix this up ASAP.