2 Replies Latest reply on Apr 11, 2012 5:16 AM by galder.zamarreno

    override read/writeObject()

    matlach

      Hello 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,