mardi 24 février 2015

Replace the class of a field at runtime (for protostuff)

I'm working on a framework for backwards compatiblity between different versions of a class (from serialized binary representations).


One thing I'm stuck on is how to replace a field used in a class with a different version of the field's class - at runtime.


I know how I could do it using a Classloader if the class in question is the parent object ( Java - how to load different versions of the same class? ).


But this doesn't work when I already have an object and need to change a field of it (or I don't see how). The reflection API also doesn't seem to have methods to set classes after they have been instantiated.


I'll give an example so it's better to understand. Let's say I have a wrapper class:



class Wrapper{
int version;
Object content;
}


Now assume that the class I'm loading as the variable content changed 20 versions ago. I still have the original .java (or .class-)file used from back then though. What I intend to do is, create an instance of wrapper with the old class version of content, load that from disc, transform it and write it into a up to date version of wrapper with the current version of the class used for content.


It also needs to be very generic, which is why I'm using object and not the actual class in the wrapper. The real issue is that I need this for protostuff runtime (de-)serialization. Which means I'm passing Wrapper.class to protostuff and it generates a serialization schema for it. This currently fails because the wrapper.class file automatically references the new version (it's in the project's package).



Schema<Wrapper> schema= RuntimeSchema.getSchema(Wrapper.class);
Wrapper resultWrapper = schema.newMessage();


I'm not sure if this ever even goes through a classloader and if so, when. I suppose it has to, but I'm not sure when this happens.


What would be the best way of approaching this?






Aucun commentaire:

Enregistrer un commentaire