river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject Re: Uuid, Versioning, Object Identity & The future.
Date Sun, 16 Aug 2009 12:49:20 GMT
Hi Pete,

I guess it wasn't such a good example, didn't look into it that deeply, 
on the surface...  Thanks for the information though, details are relevant.

I recently refactored the versioning interfaces somewhat, will upload.

The theory behind versioning is to lay down a framework / rules to 
provide support for evolution of objects in a long lived djinn 
environment, which may also include parts of the platform itself.

The implementation is based around compatible interfaces and proxy's 
(PersistentObjectDelegate <was MobileObjectDelegate>) for 
PersistentObjects, the idea being to version class files within a package
to enable class file upgrades, while persisting objects over package 
upgrades using serialization between
ClassLoaders, hence the use of proxy's: A package is to be serialized 
from its current ClassLoader to a new ClassLoader, changing the object's 
Type.  Interfaces only need be implemented for the Package's public 
API.  All references to package objects are held by proxy objects 
(PersistentObjectDelegate).

I was thinking of using reflection to implement the proxy's and 
@annotations for the locking strategy for each, however I haven't got 
that far yet and will work on ClassLoading first.

I'm planning on using the com.sun.jini.tools.classdepend package to 
analyse in the codebase to allow class version dependency hierarchy's to 
be determined for each package that supports versioning.  Different 3rd 
Party Library versions can be identified by their checksum and jar 
files.  This will somehow need to be recorded in the dependency array 
for packages also.  I'd like to make it possible to load different 
Library versions into different ClassLoaders, providing visibility only 
to the package ClassLoader that depends upon it.

The reason I've chosen the package level instead of an entire 
application upgrade as it allows an incremental agile approach for less 
change more often.

I'm hoping I can get some comments on the interfaces etc so I can revise.

Lost codebases can be solved by a codebase service, I'm hoping to hear 
back from Michal Kleczek regarding licensing before implementing.  XPro 
has a P2P codebase service implementation that sounds very interesting.

This is all a big experiment of course, I'd like to think it will bear 
fruit.

N.B. I haven't forgotten about the jtreg tests, or AR2 will get back to 
them in the near future.

Cheers,

Peter.








Peter Jones wrote:
> 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.
>
>


Mime
View raw message