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,