I feel that wire versioning IS a very important feature, because if people are using JBoss
Remoting as the framework on which they are building distributed applications, then it
will be of the utmost importance for many to be able to upgrade one node at a time to
ensure zero downtime when upgrading the entire enterprise.
However, I think that only solves half of the problem. Wire versioning in 2.0.0 only
addresses the infrastructure, but there will still be issues at the application-level.
More precisely, regardless of whether the cooperating nodes' remoting capabilities can
be upgraded independently, if the application code running on top of that infrastructure
can't be updated in a similar "rolling" fashion, then much of the potential
utility for wire versioning is being restrained.
That being said, let's take a look at some of the use cases this application level
scheme needs to handle.
Essentially, if I have two participants sending and receiving the following definition for
Person:
public class Person
| {
| private String name; // version 1 only has a name
|
| // appropriate getters/setters
| }
And one of the participants gets upgraded with a new definition, say:
public class Person
| {
| private String name;
| private int age; // version 2 also has age
|
| // appropriate getters/setters
| }
Then there needs to be a mechanism to handle the graceful conversion of this one class
definition to the other, so that enterprises can upgrade each node's definition in a
"rolling" fashion.
The semantics of specifically what happens should perhaps be flexible within each remoting
node's configuration, but somethings need to be defined that will intercept the call
and handle the graceful transformation.
For instance, mabye extra attributes from an inconsistent class definition are simply
dropped. In the reverse scenario, missing attributes might get simply get type-defined
default values.
This example assumed that the change in the newest version of the class was a simple
addition. What happens in more complex cases? Let?s say from v2 to v3, Person had
changes that looked like:
public class Person
| {
| private String fullName; // refactor name to fullName
| private Date birthday; // change age type: int->Date
|
| // appropriate getters/setters
| }
Is it possible to design this application-level wire versioning in a way so that it
executes a translation when the object is being deserialized / unmarshalled on the
receiving end, so that I can transform names into fullNames (and vice versa), and
birthdates into ages and ages into (albeit not perfectly accurate) birthdates?
I'm thinking a solution might have to use something other than Java serialization
because by default there would be serialization exceptions all over the place unless the
exact same class definition existed on both ends. But maybe I'm mistaken here? Maybe
someone knows some clever trick that we could use to implement this indirectly using Java
serialization, such as pushing out some metadata in front of each serialized attribute,
and inspecting that metadata on the receiving end by the intercepting transformer?
Another approach that might was something I saw while reading through the source code for
some of the unmarshallers. It appears it's possible to use a remote classloader to
instantiate the serialized object when the class definition doesn't exist on the
receiving end. So maybe this could be adapted slightly to instantiate the object when the
class definitions differ, and then use some clever tricks with reflection to "copy
and paste" the data from the remote object type to the local one (e.g. something
along the lines of local.setAttr(remote.getAttr)).
Keep in mind that an overarching concern here is performance. So, I want to keep that
consideration clearly on the table as possible implementation strategies for this are
discussed further.
-joseph
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3971837#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...