Addressing compatibility issues that may be introduced by the new mail attributes
feature, I'd like to write the following considerations:
1. Using file-based repositories
1.1 The mechanism used to have messages persistent is by java
serialization/de-serialization. MailImpl.writeObject(java.io.ObjectOutputStream out)
and MailImpl.readObject(java.io.ObjectInputStream in) do the work. The various fields
of a MailImpl object are explicitely managed by appropriate in.readObject() and
out.writeObject(...) commands, in a synchronized sequence. The last field being
serialized and hence de-serialized is the "lastUpdated" field.
1.2 Soeren Hilmer implemented serialization/de-serialization of the mail
attributes HashMap by serializing the "attributes" field as the last but one
field,i.e. the sequence is:
...
out.writeObject(attributes);
out.writeObject(lastUpdated);
...
1.3 De-serialization for those two last fields is done as follows:
...
Object o = in.readObject();
//this check is done to be backwards compatible with mail repositories
if (o instanceof Date) {
setLastUpdated((Date)o);
attributes = new HashMap();
} else {
attributes = (HashMap)o;
setLastUpdated((Date) in.readObject());
}
...
1.4 This way, any message serialized by a "pre-mailAttributesFeature"
James.sar, that hence is WITHOUT the "attributes" field, will be automatically
de-serialized by a "post-mailAttributesFeature" James.sar, and the attributes field
will simply contain an empty HashMap. Backwards compatibility is achieved. I did test
it.
1.5 It is not true the reverse (forward compatibility): if a message is
stored by a "post-mailAttributesFeature" James.sar, hence WITH the "attributes" field,
and for some reason the James installation is reverted back to a
"pre-mailAttributesFeature" James.sar, a de-serialization of such message will throw
an exception, probably a ClassCastException.
1.6 Because of that I suggest the following change:
1.6.1 Serialize the attributes by last:
...
out.writeObject(lastUpdated);
out.writeObject(attributes);
...
1.6.2 De-serialize with the following code:
...
setLastUpdated((Date) in.readObject());
// the following is under try/catch to be backwards compatible
// with messages created with James version <= 2.2.0a8
try {
attributes = (HashMap) in.readObject();
} catch (OptionalDataException ode) {
if (ode.eof) {
attributes = new HashMap();
} else {
throw ode;
}
}
...
1.6.3 This way compatibility would be automatically and safely
achieved in both directions. I just tested all this and it works both ways.
2. Using db-based repositories
2.1 In this case things are simpler, though not automatic. It's based on
the following two steps:
2.1.1 Installing the "post-mailAttributesFeature" James.sar. This
will *not* by itself activate the mail attributes feature.
2.1.2 Some time later on changing sqlResources.xml
(commenting/uncommenting all together the relevant sql commands) and having the
"message_attributes" field defined in the "inbox" and "spool" tables. Restarting the
server at this point will activate the mail attributes feature.
2.2 If there is (like in 1.4) any message serialized by a
"pre-mailAttributesFeature" James.sar, that hence is WITHOUT the "attributes" field,
it will be automatically de-serialized by a "post-mailAttributesFeature" James.sar,
and the attributes field will simply contain an empty HashMap. Backwards compatibility
is again achieved. I did test it. The only thing to care is that, when altering the
two tables to define the "message_attributes" field, it will have to allow for nulls,
even if new messages will be stored with "message_attributes" set to a valid HashMap.
2.3 Going back to a "pre-mailAttributesFeature" James.sar (forward
compatibility) implies also reverting to a "pre-mailAttributesFeature"
sqlResources.xml. The "message_attributes" field must either be dropped OR set to
allow nulls. Because of this, I suggest to have the "inbox" and "spool" tables create
statements in sqlResources.xml have the definition of the "message_attributes"
allowing nulls IN ANY CASE.
Any suggestion, particularly regarding points 1.6 and 2.3?
Vincenzo
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]