override read/writeObject()
matlach Apr 3, 2012 11:13 PMHello everyone,
I'd like to implements some object versioning into infinispan.
The simplest way I know to do it in java is by implementing java.io.Serializable as well as overriding both read and write object methods :
Let's consider :
public class SimpleObject implements Serializable{
private static final long serialVersionUID = 1L;
private static final int VERSION = 1;
private String id;
public SimpleObject(){
super();
}
public final String getId() {
return id;
}
public final void setId(String id) {
this.id = id;
}
private void writeObject(ObjectOutputStream oos) throws IOException{
oos.writeInt(VERSION);
oos.writeUTF(id);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException{
int version = ois.readInt();
switch (version){
case VERSION :
this.id = ois.readUTF();
break;
default : throw new IOException("bad version : " + version);
}
}
}
If running the example the following test :
public static void main(String[] args) throws IOException, ClassNotFoundException{
SimpleObject a = new SimpleObject();
a.setId("abc");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/tmp/test.bin"));
oos.writeObject(a);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/tmp/test.bin"));
a = (SimpleObject) ois.readObject();
ois.close();
}
Java serialization is handled correctly and by implementing different switch statement I could easily make my SimpleObject evolve over time.
Tough now in infinispan, I'm adding the following a cache loader to persist my versionable SimpleObject :
public Configuration avatarCacheConfiguration() {
return new ConfigurationBuilder()
.storeAsBinary()
.loaders()
.shared(false)
.passivation(false)
.addFileCacheStore()
.fetchPersistentState(true)
.ignoreModifications(false)
.purgeOnStartup(false)
.location("/tmp")
.async()
.enable()
.build();
}
but then, when putting my SimpleObject in cache I run into this :
java.io.NotActiveException: Fields were never written at org.jboss.marshalling.river.RiverObjectOutputStream.finish(RiverObjectOutputStream.java:175) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1003) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:879) at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119) at org.infinispan.container.entries.ImmortalCacheEntry$Externalizer.writeObject(ImmortalCacheEntry.java:152) at org.infinispan.container.entries.ImmortalCacheEntry$Externalizer.writeObject(ImmortalCacheEntry.java:148) at org.infinispan.marshall.jboss.ExternalizerTable$ExternalizerAdapter.writeObject(ExternalizerTable.java:394) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:145) at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119) at org.infinispan.loaders.bucket.Bucket$Externalizer.writeObject(Bucket.java:148) at org.infinispan.loaders.bucket.Bucket$Externalizer.writeObject(Bucket.java:139) at org.infinispan.marshall.jboss.ExternalizerTable$ExternalizerAdapter.writeObject(ExternalizerTable.java:394) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:145) at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119) at org.infinispan.marshall.jboss.AbstractJBossMarshaller.objectToObjectStream(AbstractJBossMarshaller.java:86) at org.infinispan.marshall.VersionAwareMarshaller.objectToBuffer(VersionAwareMarshaller.java:89) at org.infinispan.marshall.AbstractMarshaller.objectToByteBuffer(AbstractMarshaller.java:78) at org.infinispan.marshall.AbstractMarshaller.objectToByteBuffer(AbstractMarshaller.java:71) at org.infinispan.marshall.AbstractDelegatingMarshaller.objectToByteBuffer(AbstractDelegatingMarshaller.java:74) at org.infinispan.loaders.file.FileCacheStore.updateBucket(FileCacheStore.java:335) at org.infinispan.loaders.bucket.BucketBasedCacheStore.insertBucket(BucketBasedCacheStore.java:137) at org.infinispan.loaders.bucket.BucketBasedCacheStore.storeLockSafe(BucketBasedCacheStore.java:94) at org.infinispan.loaders.bucket.BucketBasedCacheStore.storeLockSafe(BucketBasedCacheStore.java:49) at org.infinispan.loaders.LockSupportCacheStore.store(LockSupportCacheStore.java:207) at org.infinispan.interceptors.DistCacheStoreInterceptor.visitPutKeyValueCommand(DistCacheStoreInterceptor.java:93) at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)
I don't know if anyone has already run into this issue but any help to fix this would be greatly appreciated.
Do I miss something with the internals mechanisms of the jboss marshalling api ?
Should I rely instead on Externalizable interface ?
Big thanks,