Peter,
Sorry that I have not been able to read your various writings on this
broader topic-- but regarding the message below, I thought that I
should point out that the whole reason that net.jini.id.UuidFactory
creates instances of its nested seemingly-pointless Impl subclass of
Uuid (and Uuid itself is extensible but extremely paranoid about
subclass interference in its own behavior), was for this to serve as
an experiment in separating a serializable public API class (not
interface because exact behavior is required for security) for which
type sharing is desired, thus it should be non-preferred, from an
actual class that will carry the effective codebase annotation
(superclass annotations are unimportant), which should be preferred so
the codebase doesn't get "lost".
In practice, however, I don't think that the experiment yielded much,
because Uuid is such a fundamental and ubiquitous class that it always
ends up as part of the assumed "platform" anyway, so that the lost
codebase issue is moot.
(And then Java SE finally got around to adding its own UUID class in
5.0...)
-- Peter
On Aug 2, 2009, at 12:30 AM, Peter Firmstone wrote:
By creating the following interface for Uuid:
package org.apache.river.version;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
/**
* A common interface for a VersioningClassLoader to upcast a Uuid to.
* @author Peter Firmstone
*/
public interface IUuid extends Serializable {
long getLeastSignificantBits();
long getMostSignificantBits();
void write(OutputStream out) throws IOException;
}
The implmentation of Uuid.equals(Object obj) can be changed to:
+import org.apache.river.version.IUuid;
+import org.apache.river.version.VersionedPublicClass;
public class Uuid implements IUuid, VersionedPublicClass {
<snip>
public final boolean equals(Object obj) {
if (obj instanceof IUuid) {
IUuid other = (IUuid) obj;
return this.getLeastSignificantBits() ==
other.getLeastSignificantBits() && this.getMostSignificantBits() ==
other.getMostSignificantBits();
} else {
return false;
}
}
<snip>
}
This provides a common interface for two non identical Types to have
compatibility via upcasting, the VersioningClassLoader can use the
new Uuid class bytecode in preference to the existing, while
retaining compatibility with existing Uuid objects. UuidFactory
could be changed to return an IUuid.
The VersioningClassLoader needs to place all application interfaces
into an ApplicationInterface ClassRealm and make this available to
all versions of the application. How does one identify interfaces
and load them into a separate ClassLoader than the rest of the
package?
Class.getInterfaces() ? We would have to load the class to do this.
It would be better to flag all interfaces in the dependency array
provided by the codesource that are loaded first, where required,
into the Interface ClassRealm.
Interfaces will allways use the existing loaded class file, new
interfaces may extend old, and Obsolete interface method
implementations may return ObsoleteMethodException.
The latest class file version would always be preferred. Each
codebase would provide a dependency array, that contained
checksum's, class names and versions for each class. The dependency
array could be auto generated by a codebase at runtime, allowing us
to use existing jar files. All dependency objects could be
serialized and reconstituted by the classloader. The dependency
objects would need to implement an interface also.
So the answer is, yes existing implementations with some
modifications can support versioning. Uuid and UuidFactory, could
easily be extended to support versioning, with a
MobileObjectDelegate that implements IUuid being returned by a
UuidFactory, allowing the Uuid implementation to change and be
updated as need if ever needed.
Detailed versioning of library's isn't always necessary, it can
simply be a library version, where the currently visible library
ClassRealm used by an Versioned Application Package, is simply the
library used by that Application Version. One then has to test if
library objects support compatiblity between versions and if not
work out a way to reconstruct these objects from application code.
I think in the case of Uuid, if a later library version broke
compatibility, it wouldn't be easy to reconstruct the object without
breaking identity without versioning
N.B. I was thinking of renaming MobileObjectDelegate to
ObjectInterceptorDelegate or ObjectDelegate? Note that all
MobileObjectDelegates (MOD) live inside the main application space,
the class files for MOD's would never be Garbage collected (their
objects would), so it is important to minimise their number and
size. This is actually where inheritance makes sense, the MOD's
would have standard abstract synchronization strategy classes to
inherit from, perhaps one MOD for each interface. Any number of
VersionedPublicClass implementations might share the same MOD
implementation.
Who wants to help work out the ClassLoader side of things? I need
to figure out how Security fits in with Versioning.
This work is inspired by Michael Warres work and the findings of
project neuromancer, I'm starting to feel positive, that versioning
can assist with long lived objects and codebase upgrades in a
djinn, this is relevant for me; business domain models are required
to undergo continuous change, otherwise the model risks constraining
the business itself. I get to use the software I develop, what do
they call it, eat your own dog food?
By storing versioning information into the serialized form of an
object (ObjectPreservedOnUpdate), it has the potential to allow
objects to be stored to disk (remain in their serialized state) for
long periods of time, while allowing the programmer to formulate
strategies to handle the different object versions and forms during
unmarshalling. By not requiring objects to support serialization
back to earlier class versions, it also, frees a programmer from
having to support the earlier class form indefinitely. That would
also mean that programmers are free to fix bad implementations of
Serialization, eg where a programmer has just added: "implements
Serializable".
Cheers,
Peter.