[infinispan-commits] Infinispan SVN: r334 - in trunk/core: src/main/java/org/infinispan/marshall/jboss and 3 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Thu May 21 18:11:21 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-05-21 18:11:21 -0400 (Thu, 21 May 2009)
New Revision: 334

Added:
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ClassExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/Externalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/BucketExternalizer.java
Modified:
   trunk/core/
   trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ArrayListExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/DeltaAwareExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExceptionResponseExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExtendedResponseExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheEntryExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheValueExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmutableMapExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/InternalCachedEntryExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/JGroupsAddressExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/LinkedListExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MapExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MarshalledValueExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheEntryExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheValueExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ReplicableCommandExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SetExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SingletonListExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SuccessfulResponseExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheEntryExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheValueExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheEntryExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheValueExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/UnsuccessfulResponseExternalizer.java
   trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java
   trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
Log:
[ISPN-59] (Add unit test that verifies number of written bytes) Implemented more efficient marshalling framework based on JBoss Marshaller where size of payloads are reduced and faster code path is used.


Property changes on: trunk/core
___________________________________________________________________
Name: svn:ignore
   - target
.settings
eclipse-output
.classpath
.project
temp-testng-customsuite.xml

   + target
.settings
eclipse-output
test-output
output
.classpath
.project
temp-testng-customsuite.xml


Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ClassExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ClassExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ClassExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+
+/**
+ * JBoss Marshalling implementation is now based only on ObjectTable instances
+ * and so JBMAR ClassTable is not used any longer. Instead, for those cases where
+ * classes need to be written, a new ClassTable has been redefined that allows 
+ * reducing the number of writes written for a Class.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface ClassExternalizer {
+   /**
+    * Write the predefined class reference to the stream.
+    *
+    * @param output the marshaller to write to
+    * @param subjectType the class reference to write
+    * @throws IOException if an I/O error occurs
+    */
+   void writeClass(Marshaller output, Class<?> subjectType) throws IOException;
+   
+   /**
+    * Read a class from the stream.  The class will have been written by the
+    * writeClass(Marshaller, Class) method, as defined above.
+    *
+    * @param unmarshaller the unmarshaller to read from
+    * @return the class
+    * @throws IOException if an I/O error occurs
+    */
+   Class<?> readClass(Unmarshaller input) throws IOException;
+      
+   /**
+    * Classes that provide a shortened version of Class information should
+    * implement this interface in order to get a callback to set the ClassTable. 
+    */
+   interface ClassWritable {
+      /**
+       * Set ClassTable callback to be able to provide a write a shortened 
+       * Class version.
+       * 
+       * @param classTable
+       */
+      void setClassExternalizer(ClassExternalizer classExt);
+   }
+}

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,65 +22,247 @@
 package org.infinispan.marshall.jboss;
 
 import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.atomic.AtomicHashMap;
+import org.infinispan.commands.LockControlCommand;
+import org.infinispan.commands.control.StateTransferControlCommand;
+import org.infinispan.commands.read.GetKeyValueCommand;
+import org.infinispan.commands.remote.ClusteredGetCommand;
+import org.infinispan.commands.remote.MultipleRpcCommand;
+import org.infinispan.commands.remote.SingleRpcCommand;
+import org.infinispan.commands.tx.CommitCommand;
+import org.infinispan.commands.tx.PrepareCommand;
+import org.infinispan.commands.tx.RollbackCommand;
+import org.infinispan.commands.write.ClearCommand;
+import org.infinispan.commands.write.InvalidateCommand;
+import org.infinispan.commands.write.InvalidateL1Command;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.commands.write.PutMapCommand;
+import org.infinispan.commands.write.RemoveCommand;
+import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.container.entries.ImmortalCacheEntry;
+import org.infinispan.container.entries.ImmortalCacheValue;
+import org.infinispan.container.entries.MortalCacheEntry;
+import org.infinispan.container.entries.MortalCacheValue;
+import org.infinispan.container.entries.TransientCacheEntry;
+import org.infinispan.container.entries.TransientCacheValue;
+import org.infinispan.container.entries.TransientMortalCacheEntry;
+import org.infinispan.container.entries.TransientMortalCacheValue;
+import org.infinispan.loaders.bucket.Bucket;
+import org.infinispan.marshall.MarshalledValue;
+import org.infinispan.marshall.jboss.externalizers.ArrayListExternalizer;
+import org.infinispan.marshall.jboss.externalizers.BucketExternalizer;
+import org.infinispan.marshall.jboss.externalizers.DeltaAwareExternalizer;
+import org.infinispan.marshall.jboss.externalizers.ExceptionResponseExternalizer;
+import org.infinispan.marshall.jboss.externalizers.ExtendedResponseExternalizer;
+import org.infinispan.marshall.jboss.externalizers.GlobalTransactionExternalizer;
+import org.infinispan.marshall.jboss.externalizers.ImmortalCacheEntryExternalizer;
+import org.infinispan.marshall.jboss.externalizers.ImmortalCacheValueExternalizer;
+import org.infinispan.marshall.jboss.externalizers.ImmutableMapExternalizer;
+import org.infinispan.marshall.jboss.externalizers.JGroupsAddressExternalizer;
+import org.infinispan.marshall.jboss.externalizers.LinkedListExternalizer;
+import org.infinispan.marshall.jboss.externalizers.MapExternalizer;
+import org.infinispan.marshall.jboss.externalizers.MarshalledValueExternalizer;
+import org.infinispan.marshall.jboss.externalizers.MortalCacheEntryExternalizer;
+import org.infinispan.marshall.jboss.externalizers.MortalCacheValueExternalizer;
+import org.infinispan.marshall.jboss.externalizers.ReplicableCommandExternalizer;
+import org.infinispan.marshall.jboss.externalizers.SetExternalizer;
+import org.infinispan.marshall.jboss.externalizers.SingletonListExternalizer;
+import org.infinispan.marshall.jboss.externalizers.StateTransferControlCommandExternalizer;
+import org.infinispan.marshall.jboss.externalizers.SuccessfulResponseExternalizer;
+import org.infinispan.marshall.jboss.externalizers.TransactionLogExternalizer;
+import org.infinispan.marshall.jboss.externalizers.TransientCacheEntryExternalizer;
+import org.infinispan.marshall.jboss.externalizers.TransientCacheValueExternalizer;
+import org.infinispan.marshall.jboss.externalizers.TransientMortalCacheEntryExternalizer;
+import org.infinispan.marshall.jboss.externalizers.TransientMortalCacheValueExternalizer;
+import org.infinispan.remoting.responses.ExceptionResponse;
+import org.infinispan.remoting.responses.ExtendedResponse;
 import org.infinispan.remoting.responses.RequestIgnoredResponse;
+import org.infinispan.remoting.responses.SuccessfulResponse;
 import org.infinispan.remoting.responses.UnsuccessfulResponse;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.util.FastCopyHashMap;
+import org.infinispan.util.Util;
 import org.jboss.marshalling.Marshaller;
 import org.jboss.marshalling.ObjectTable;
 import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.IdentityHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 /**
- * CustomObjectTable.
+ * Custom ObjectTable that deals with both constant instances and 
+ * externalizer-like ReadWriter implementations.
  *
  * @author Galder Zamarreño
  * @since 4.0
  */
 public class CustomObjectTable implements ObjectTable {
+   private static final Map<String, String> WRITERS = new HashMap<String, String>();
 
+   static {
+      WRITERS.put(GlobalTransaction.class.getName(), GlobalTransactionExternalizer.class.getName());
+      WRITERS.put(JGroupsAddress.class.getName(), JGroupsAddressExternalizer.class.getName());
+      WRITERS.put(ArrayList.class.getName(), ArrayListExternalizer.class.getName());
+      WRITERS.put(LinkedList.class.getName(), LinkedListExternalizer.class.getName());
+      WRITERS.put(HashMap.class.getName(), MapExternalizer.class.getName());
+      WRITERS.put(TreeMap.class.getName(), MapExternalizer.class.getName());
+      WRITERS.put(HashSet.class.getName(), SetExternalizer.class.getName());
+      WRITERS.put(TreeSet.class.getName(), SetExternalizer.class.getName());
+      WRITERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", ImmutableMapExternalizer.class.getName());
+      WRITERS.put(MarshalledValue.class.getName(), MarshalledValueExternalizer.class.getName());
+      WRITERS.put(FastCopyHashMap.class.getName(), MapExternalizer.class.getName());
+      WRITERS.put("java.util.Collections$SingletonList", SingletonListExternalizer.class.getName());
+      WRITERS.put("org.infinispan.transaction.TransactionLog$LogEntry", TransactionLogExternalizer.class.getName());
+      WRITERS.put(ExtendedResponse.class.getName(), ExtendedResponseExternalizer.class.getName());
+      WRITERS.put(SuccessfulResponse.class.getName(), SuccessfulResponseExternalizer.class.getName());
+      WRITERS.put(ExceptionResponse.class.getName(), ExceptionResponseExternalizer.class.getName());
+      WRITERS.put(AtomicHashMap.class.getName(), DeltaAwareExternalizer.class.getName());
+
+      WRITERS.put(StateTransferControlCommand.class.getName(), StateTransferControlCommandExternalizer.class.getName());
+      WRITERS.put(ClusteredGetCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(MultipleRpcCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(SingleRpcCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(GetKeyValueCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(PutKeyValueCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(RemoveCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(InvalidateCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(ReplaceCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(ClearCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(PutMapCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(PrepareCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(CommitCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(RollbackCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(InvalidateL1Command.class.getName(), ReplicableCommandExternalizer.class.getName());
+      WRITERS.put(LockControlCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+
+      WRITERS.put(ImmortalCacheEntry.class.getName(), ImmortalCacheEntryExternalizer.class.getName());
+      WRITERS.put(MortalCacheEntry.class.getName(), MortalCacheEntryExternalizer.class.getName());
+      WRITERS.put(TransientCacheEntry.class.getName(), TransientCacheEntryExternalizer.class.getName());
+      WRITERS.put(TransientMortalCacheEntry.class.getName(), TransientMortalCacheEntryExternalizer.class.getName());    
+      WRITERS.put(ImmortalCacheValue.class.getName(), ImmortalCacheValueExternalizer.class.getName());
+      WRITERS.put(MortalCacheValue.class.getName(), MortalCacheValueExternalizer.class.getName());
+      WRITERS.put(TransientCacheValue.class.getName(), TransientCacheValueExternalizer.class.getName());
+      WRITERS.put(TransientMortalCacheValue.class.getName(), TransientMortalCacheValueExternalizer.class.getName());
+      
+      WRITERS.put(Bucket.class.getName(), BucketExternalizer.class.getName());      
+   }
+
+   /** Contains list of singleton objects written such as constant objects, 
+    * singleton ReadWriter implementations...etc. When writing, index of each 
+    * object is written, and when reading, index is used to find the instance 
+    * in this list.*/
    private final List<Object> objects = new ArrayList<Object>();
+   /** Contains mapping of constant instances to their writers */
    private final Map<Object, Writer> writers = new IdentityHashMap<Object, Writer>();
+   /** Contains mapping of custom object externalizer classes to their 
+    * ReadWriter instances. Do not use this map for storing ReadWriter 
+    * implementations for user classes. For these, please use weak key based 
+    * maps, i.e WeakHashMap */
+   private final Map<Class<?>, Externalizer> readwriters = new IdentityHashMap<Class<?>, Externalizer>();
    private byte index;
+   private final Transport transport;
+   private final MagicNumberClassTable classTable = new MagicNumberClassTable();
+   
+   public CustomObjectTable(Transport transport) {
+      this.transport = transport;
+   }
 
    public void init() {
+      // Init singletons
       objects.add(RequestIgnoredResponse.INSTANCE);
-      writers.put(RequestIgnoredResponse.INSTANCE, new CustomObjectWriter(index++));
+      writers.put(RequestIgnoredResponse.INSTANCE, new InstanceWriter(index++));
       objects.add(UnsuccessfulResponse.INSTANCE);
-      writers.put(UnsuccessfulResponse.INSTANCE, new CustomObjectWriter(index++));
+      writers.put(UnsuccessfulResponse.INSTANCE, new InstanceWriter(index++));
+      
+      try {
+         for (Map.Entry<String, String> entry : WRITERS.entrySet()) {
+            Class typeClazz = Util.loadClass(entry.getKey());
+            Externalizer delegate = (Externalizer) Util.getInstance(entry.getValue());
+            if (delegate instanceof StateTransferControlCommandExternalizer) {
+               ((StateTransferControlCommandExternalizer) delegate).init(transport);
+            }
+            if (delegate instanceof ClassExternalizer.ClassWritable) {
+               ((ClassExternalizer.ClassWritable) delegate).setClassExternalizer(classTable);
+            }
+            Externalizer rwrt = new DelegatingReadWriter(index++, delegate);
+            objects.add(rwrt);
+            readwriters.put(typeClazz, rwrt);
+         }
+         
+      } catch (IOException e) {
+         throw new CacheException("Unable to open load magicnumbers.properties", e);
+      } catch (ClassNotFoundException e) {
+         throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
+      } catch (Exception e) {
+         throw new CacheException("Unable to instantiate Externalizer class", e);
+      }
    }
 
    public void stop() {
+      classTable.stop();
       writers.clear();
       objects.clear();
+      readwriters.clear();
    }
 
-   public void add(Object o) {
-      objects.add(o);
-      writers.put(o, new CustomObjectWriter(index++));
-   }
-
    public Writer getObjectWriter(Object o) throws IOException {
+      Object singleton = writers.get(o);
+      if (singleton == null) {
+         return readwriters.get(o.getClass()); 
+      }
       return writers.get(o);
    }
 
    public Object readObject(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
-      return objects.get(unmarshaller.readUnsignedByte());
+      Object o = objects.get(unmarshaller.readUnsignedByte());
+      if (o instanceof Externalizer) {
+         return ((Externalizer) o).readObject(unmarshaller);
+      }
+      return o;
    }
+   
+   @Immutable
+   static class InstanceWriter implements Writer {
+      private final byte id;
 
+      InstanceWriter(byte objectId) {
+         this.id = objectId;
+      }
+
+      public void writeObject(Marshaller marshaller, Object object) throws IOException {
+         marshaller.write(id);
+      }
+   }   
+   
    @Immutable
-   static class CustomObjectWriter implements Writer {
+   static class DelegatingReadWriter implements Externalizer {
       private final byte id;
+      private final Externalizer delegate;
 
-      CustomObjectWriter(byte objectId) {
+      DelegatingReadWriter(byte objectId, Externalizer delegate) {
          this.id = objectId;
+         this.delegate = delegate;
       }
 
       public void writeObject(Marshaller marshaller, Object object) throws IOException {
          marshaller.write(id);
+         delegate.writeObject(marshaller, object);
       }
-   }
+
+      public Object readObject(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
+         return delegate.readObject(unmarshaller);
+      }
+   }   
 }

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/Externalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/Externalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/Externalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.ObjectTable.Writer;
+
+/**
+ * Extended interface that extends capabilities of writing predefined objects 
+ * with the possibility of reading them. Any new externalizer implementations
+ * should implement this interface. 
+ * 
+ * Optionally, Externalizer implementations should implement 
+ * {@code ClassTable.ClassReadWritable} when they want to add class information to the 
+ * marshalled payload. This is useful in cases where ReadWriter implementations
+ * will create, upon read, new instances using reflection.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface Externalizer extends Writer {
+   
+   /**
+    * Read an instance from the stream.  The instance will have been written by the
+    * {@link #writeObject(Object)} method.
+    *
+    * @param unmarshaller the unmarshaller to read from
+    * @return the object instance
+    * @throws IOException if an I/O error occurs
+    * @throws ClassNotFoundException if a class could not be found
+    */
+   Object readObject(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException;
+}

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -48,6 +48,7 @@
 import org.infinispan.container.entries.TransientCacheValue;
 import org.infinispan.container.entries.TransientMortalCacheEntry;
 import org.infinispan.container.entries.TransientMortalCacheValue;
+import org.infinispan.loaders.bucket.Bucket;
 import org.infinispan.marshall.MarshalledValue;
 import org.infinispan.marshall.jboss.externalizers.*;
 import org.infinispan.remoting.responses.ExceptionResponse;
@@ -76,93 +77,96 @@
  *
  * @author Galder Zamarreño
  * @since 4.0
+ * @deprecated No longer in use. A purely ObjectTable based solution is now in use.
  */
 @Immutable
+ at Deprecated
 public class ExternalizerClassFactory implements ClassExternalizerFactory {
    private static final Map<String, String> EXTERNALIZERS = new HashMap<String, String>();
 
-   static {
-      EXTERNALIZERS.put(GlobalTransaction.class.getName(), GlobalTransactionExternalizer.class.getName());
-      EXTERNALIZERS.put(JGroupsAddress.class.getName(), JGroupsAddressExternalizer.class.getName());
-      EXTERNALIZERS.put(ArrayList.class.getName(), ArrayListExternalizer.class.getName());
-      EXTERNALIZERS.put(LinkedList.class.getName(), LinkedListExternalizer.class.getName());
-      EXTERNALIZERS.put(HashMap.class.getName(), MapExternalizer.class.getName());
-      EXTERNALIZERS.put(TreeMap.class.getName(), MapExternalizer.class.getName());
-      EXTERNALIZERS.put(HashSet.class.getName(), SetExternalizer.class.getName());
-      EXTERNALIZERS.put(TreeSet.class.getName(), SetExternalizer.class.getName());
-      EXTERNALIZERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", ImmutableMapExternalizer.class.getName());
-      EXTERNALIZERS.put(MarshalledValue.class.getName(), MarshalledValueExternalizer.class.getName());
-      EXTERNALIZERS.put(FastCopyHashMap.class.getName(), MapExternalizer.class.getName());
-      EXTERNALIZERS.put("java.util.Collections$SingletonList", SingletonListExternalizer.class.getName());
-      EXTERNALIZERS.put("org.infinispan.transaction.TransactionLog$LogEntry", TransactionLogExternalizer.class.getName());
-      EXTERNALIZERS.put(ExtendedResponse.class.getName(), ExtendedResponseExternalizer.class.getName());
-      EXTERNALIZERS.put(SuccessfulResponse.class.getName(), SuccessfulResponseExternalizer.class.getName());
-      EXTERNALIZERS.put(ExceptionResponse.class.getName(), ExceptionResponseExternalizer.class.getName());
-      EXTERNALIZERS.put(AtomicHashMap.class.getName(), DeltaAwareExternalizer.class.getName());
+//   static {
+//      EXTERNALIZERS.put(GlobalTransaction.class.getName(), GlobalTransactionExternalizer.class.getName());
+//      EXTERNALIZERS.put(JGroupsAddress.class.getName(), JGroupsAddressExternalizer.class.getName());
+//      EXTERNALIZERS.put(ArrayList.class.getName(), ArrayListExternalizer.class.getName());
+//      EXTERNALIZERS.put(LinkedList.class.getName(), LinkedListExternalizer.class.getName());
+//      EXTERNALIZERS.put(HashMap.class.getName(), MapExternalizer.class.getName());
+//      EXTERNALIZERS.put(TreeMap.class.getName(), MapExternalizer.class.getName());
+//      EXTERNALIZERS.put(HashSet.class.getName(), SetExternalizer.class.getName());
+//      EXTERNALIZERS.put(TreeSet.class.getName(), SetExternalizer.class.getName());
+//      EXTERNALIZERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", ImmutableMapExternalizer.class.getName());
+//      EXTERNALIZERS.put(MarshalledValue.class.getName(), MarshalledValueExternalizer.class.getName());
+//      EXTERNALIZERS.put(FastCopyHashMap.class.getName(), MapExternalizer.class.getName());
+//      EXTERNALIZERS.put("java.util.Collections$SingletonList", SingletonListExternalizer.class.getName());
+//      EXTERNALIZERS.put("org.infinispan.transaction.TransactionLog$LogEntry", TransactionLogExternalizer.class.getName());
+//      EXTERNALIZERS.put(ExtendedResponse.class.getName(), ExtendedResponseExternalizer.class.getName());
+//      EXTERNALIZERS.put(SuccessfulResponse.class.getName(), SuccessfulResponseExternalizer.class.getName());
+//      EXTERNALIZERS.put(ExceptionResponse.class.getName(), ExceptionResponseExternalizer.class.getName());
+//      EXTERNALIZERS.put(AtomicHashMap.class.getName(), DeltaAwareExternalizer.class.getName());
+//
+//      EXTERNALIZERS.put(StateTransferControlCommand.class.getName(), StateTransferControlCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(ClusteredGetCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(MultipleRpcCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(SingleRpcCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(GetKeyValueCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(PutKeyValueCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(RemoveCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(InvalidateCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(ReplaceCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(ClearCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(PutMapCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(PrepareCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(CommitCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(RollbackCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(InvalidateL1Command.class.getName(), ReplicableCommandExternalizer.class.getName());
+//      EXTERNALIZERS.put(LockControlCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//
+//      EXTERNALIZERS.put(ImmortalCacheEntry.class.getName(), ImmortalCacheEntryExternalizer.class.getName());
+//      EXTERNALIZERS.put(MortalCacheEntry.class.getName(), MortalCacheEntryExternalizer.class.getName());
+//      EXTERNALIZERS.put(TransientCacheEntry.class.getName(), TransientCacheEntryExternalizer.class.getName());
+//      EXTERNALIZERS.put(TransientMortalCacheEntry.class.getName(), TransientMortalCacheEntryExternalizer.class.getName());    
+//      EXTERNALIZERS.put(ImmortalCacheValue.class.getName(), ImmortalCacheValueExternalizer.class.getName());
+//      EXTERNALIZERS.put(MortalCacheValue.class.getName(), MortalCacheValueExternalizer.class.getName());
+//      EXTERNALIZERS.put(TransientCacheValue.class.getName(), TransientCacheValueExternalizer.class.getName());
+//      EXTERNALIZERS.put(TransientMortalCacheValue.class.getName(), TransientMortalCacheValueExternalizer.class.getName());
+//      
+//      EXTERNALIZERS.put(Bucket.class.getName(), BucketExternalizer.class.getName());
+//   }
+//
+//   private final Map<Class<?>, Externalizer> externalizers = new WeakHashMap<Class<?>, Externalizer>();
+//   private final Transport transport;
+//   private final CustomObjectTable objectTable;
+//
+//   public ExternalizerClassFactory(Transport transport, CustomObjectTable objectTable) {
+//      this.transport = transport;
+//      this.objectTable = objectTable;
+//   }
+//
+//   public void init() {
+//      try {
+//         for (Map.Entry<String, String> entry : EXTERNALIZERS.entrySet()) {
+//            Class typeClazz = Util.loadClass(entry.getKey());
+//            Externalizer ext = (Externalizer) Util.getInstance(entry.getValue());
+//            if (ext instanceof StateTransferControlCommandExternalizer) {
+//               ((StateTransferControlCommandExternalizer) ext).init(transport);
+//            }
+//            externalizers.put(typeClazz, ext);
+//            objectTable.add(ext);
+//         }
+//      } catch (IOException e) {
+//         throw new CacheException("Unable to open load magicnumbers.properties", e);
+//      } catch (ClassNotFoundException e) {
+//         throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
+//      } catch (Exception e) {
+//         throw new CacheException("Unable to instantiate Externalizer class", e);
+//      }
+//   }
 
-      EXTERNALIZERS.put(StateTransferControlCommand.class.getName(), StateTransferControlCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(ClusteredGetCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(MultipleRpcCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(SingleRpcCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(GetKeyValueCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(PutKeyValueCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(RemoveCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(InvalidateCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(ReplaceCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(ClearCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(PutMapCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(PrepareCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(CommitCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(RollbackCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
-      EXTERNALIZERS.put(LockControlCommand.class.getName(), ReplicableCommandExternalizer.class.getName());
+//   public void stop() {
+//      externalizers.clear();
+//   }
 
-      EXTERNALIZERS.put(ImmortalCacheEntry.class.getName(), ImmortalCacheEntryExternalizer.class.getName());
-      EXTERNALIZERS.put(MortalCacheEntry.class.getName(), MortalCacheEntryExternalizer.class.getName());
-      EXTERNALIZERS.put(TransientCacheEntry.class.getName(), TransientCacheEntryExternalizer.class.getName());
-      EXTERNALIZERS.put(TransientMortalCacheEntry.class.getName(), TransientMortalCacheEntryExternalizer.class.getName());    
-
-      EXTERNALIZERS.put(InvalidateL1Command.class.getName(), ReplicableCommandExternalizer.class.getName());
-      
-      EXTERNALIZERS.put(ImmortalCacheValue.class.getName(), ImmortalCacheValueExternalizer.class.getName());
-      EXTERNALIZERS.put(MortalCacheValue.class.getName(), MortalCacheValueExternalizer.class.getName());
-      EXTERNALIZERS.put(TransientCacheValue.class.getName(), TransientCacheValueExternalizer.class.getName());
-      EXTERNALIZERS.put(TransientMortalCacheValue.class.getName(), TransientMortalCacheValueExternalizer.class.getName());
-   }
-
-   private final Map<Class<?>, Externalizer> externalizers = new WeakHashMap<Class<?>, Externalizer>();
-   private final Transport transport;
-   private final CustomObjectTable objectTable;
-
-   public ExternalizerClassFactory(Transport transport, CustomObjectTable objectTable) {
-      this.transport = transport;
-      this.objectTable = objectTable;
-   }
-
-   public void init() {
-      try {
-         for (Map.Entry<String, String> entry : EXTERNALIZERS.entrySet()) {
-            Class typeClazz = Util.loadClass(entry.getKey());
-            Externalizer ext = (Externalizer) Util.getInstance(entry.getValue());
-            if (ext instanceof StateTransferControlCommandExternalizer) {
-               ((StateTransferControlCommandExternalizer) ext).init(transport);
-            }
-            externalizers.put(typeClazz, ext);
-            objectTable.add(ext);
-         }
-      } catch (IOException e) {
-         throw new CacheException("Unable to open load magicnumbers.properties", e);
-      } catch (ClassNotFoundException e) {
-         throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
-      } catch (Exception e) {
-         throw new CacheException("Unable to instantiate Externalizer class", e);
-      }
-   }
-
-   public void stop() {
-      externalizers.clear();
-   }
-
    public Externalizer getExternalizer(Class<?> clazz) {
-      return externalizers.get(clazz);
+//      return externalizers.get(clazz);
+      return null;
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -57,23 +57,15 @@
 public class JBossMarshaller extends AbstractMarshaller {
    private static final Log log = LogFactory.getLog(JBossMarshaller.class);
    private static final String DEFAULT_MARSHALLER_FACTORY = "org.jboss.marshalling.river.RiverMarshallerFactory";
-   //   private static final int VERSION_400 = 400;
-   //   private static final int DEFAULT_VERSION = VERSION_400;
    private ClassLoader defaultClassLoader;
    private MarshallingConfiguration configuration;
    private MarshallerFactory factory;
-   private MagicNumberClassTable classTable;
    private CustomObjectTable objectTable;
-   private ExternalizerClassFactory externalizerFactoryAndObjectTable;
-///   private boolean trace;
 
    @Inject
    public void init(ClassLoader defaultCl, Transport transport) {
       log.debug("Using JBoss Marshalling based marshaller.");
-
-//      trace = log.isTraceEnabled();
       defaultClassLoader = defaultCl;
-
       try {
          // Todo: Enable different marshaller factories via configuration
          factory = (MarshallerFactory) Util.getInstance(DEFAULT_MARSHALLER_FACTORY);
@@ -81,29 +73,28 @@
          throw new CacheException("Unable to load JBoss Marshalling marshaller factory " + DEFAULT_MARSHALLER_FACTORY, e);
       }
 
-      classTable = createMagicNumberClassTable();
-      objectTable = createCustomObjectTable();
-      externalizerFactoryAndObjectTable = createCustomExternalizerFactory(transport, objectTable);
-
+      objectTable = createCustomObjectTable(transport);
       configuration = new MarshallingConfiguration();
       configuration.setCreator(new SunReflectiveCreator());
-      configuration.setClassTable(classTable);
-      configuration.setClassExternalizerFactory(externalizerFactoryAndObjectTable);
       configuration.setObjectTable(objectTable);
+      
+      /* Doubtful: Setting version to 0 reduces the payload avoiding block mode 
+       * (each object in a block) but could potentially be a security issue 
+       * and could spoil things when trying to serialize a spec-compliant 
+       * Serializable object which relies on reading a -1 to know when its data 
+       * ends will "overrun" the buffer if there's no block mode in place. 
+       */ 
+//      configuration.setVersion(0);
 
       // ContextClassResolver provides same functionality as MarshalledValueInputStream
       configuration.setClassResolver(new ContextClassResolver());
-//      // Todo: This is the JBMAR underlying protocol version, don't touch! Think about how to get VAM into JBMAR
-//      configuration.setVersion(DEFAULT_VERSION);
    }
 
    @Stop
    public void stop() {
       // Do not leak classloader when cache is stopped.
       defaultClassLoader = null;
-      classTable.stop();
       objectTable.stop();
-      externalizerFactoryAndObjectTable.stop();
    }
 
    public byte[] objectToByteBuffer(Object obj) throws IOException {
@@ -116,8 +107,11 @@
    public ByteBuffer objectToBuffer(Object o) throws IOException {
       ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream(128);
       ObjectOutput marshaller = startObjectOutput(baos);
-      objectToObjectStream(o, marshaller);
-      finishObjectOutput(marshaller);
+      try {
+         objectToObjectStream(o, marshaller);
+      } finally {
+         finishObjectOutput(marshaller);
+      }
       return new ByteBuffer(baos.getRawBuffer(), 0, baos.size());
    }
 
@@ -157,8 +151,12 @@
                                                                                  ClassNotFoundException {
       ByteArrayInputStream is = new ByteArrayInputStream(buf, offset, length);
       ObjectInput unmarshaller = startObjectInput(is);
-      Object o = objectFromObjectStream(unmarshaller);
-      finishObjectInput(unmarshaller);
+      Object o = null;
+      try {
+         o = objectFromObjectStream(unmarshaller);
+      } finally {
+         finishObjectInput(unmarshaller);
+      }
       return o;
    }
 
@@ -179,20 +177,8 @@
       return in.readObject();
    }
 
-   protected MagicNumberClassTable createMagicNumberClassTable() {
-      MagicNumberClassTable classTable = new MagicNumberClassTable();
-      classTable.init();
-      return classTable;
-   }
-
-   protected ExternalizerClassFactory createCustomExternalizerFactory(Transport transport, CustomObjectTable objectTable) {
-      ExternalizerClassFactory externalizerFactory = new ExternalizerClassFactory(transport, objectTable);
-      externalizerFactory.init();
-      return externalizerFactory;
-   }
-
-   private CustomObjectTable createCustomObjectTable() {
-      CustomObjectTable objectTable = new CustomObjectTable();
+   private CustomObjectTable createCustomObjectTable(Transport transport) {
+      CustomObjectTable objectTable = new CustomObjectTable(transport);
       objectTable.init();
       return objectTable;
    }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -23,9 +23,7 @@
 
 import net.jcip.annotations.Immutable;
 import org.infinispan.CacheException;
-import org.infinispan.atomic.AtomicHashMap;
 import org.infinispan.commands.LockControlCommand;
-import org.infinispan.commands.control.StateTransferControlCommand;
 import org.infinispan.commands.read.GetKeyValueCommand;
 import org.infinispan.commands.remote.ClusteredGetCommand;
 import org.infinispan.commands.remote.MultipleRpcCommand;
@@ -40,37 +38,19 @@
 import org.infinispan.commands.write.PutMapCommand;
 import org.infinispan.commands.write.RemoveCommand;
 import org.infinispan.commands.write.ReplaceCommand;
-import org.infinispan.container.entries.ImmortalCacheEntry;
-import org.infinispan.container.entries.ImmortalCacheValue;
-import org.infinispan.container.entries.MortalCacheEntry;
-import org.infinispan.container.entries.MortalCacheValue;
-import org.infinispan.container.entries.TransientCacheEntry;
-import org.infinispan.container.entries.TransientCacheValue;
-import org.infinispan.container.entries.TransientMortalCacheEntry;
-import org.infinispan.container.entries.TransientMortalCacheValue;
-import org.infinispan.marshall.MarshalledValue;
-import org.infinispan.remoting.responses.ExceptionResponse;
-import org.infinispan.remoting.responses.ExtendedResponse;
-import org.infinispan.remoting.responses.RequestIgnoredResponse;
-import org.infinispan.remoting.responses.SuccessfulResponse;
-import org.infinispan.remoting.responses.UnsuccessfulResponse;
-import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.infinispan.transaction.xa.GlobalTransaction;
 import org.infinispan.util.FastCopyHashMap;
 import org.infinispan.util.Util;
-import org.jboss.marshalling.ClassTable;
 import org.jboss.marshalling.Marshaller;
 import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.util.IdentityIntMap;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
+import java.util.List;
 import java.util.TreeMap;
 import java.util.TreeSet;
-import java.util.WeakHashMap;
 
 /**
  * MagicNumberClassTable.
@@ -79,107 +59,71 @@
  * @since 4.0
  */
 @Immutable
-public class MagicNumberClassTable implements ClassTable {
-   private static final Map<String, Integer> MAGIC_NUMBERS = new WeakHashMap<String, Integer>();
+public class MagicNumberClassTable implements ClassExternalizer {
+   private static final List<String> MAGIC_NUMBERS = new ArrayList<String>();
 
    static {
-      MAGIC_NUMBERS.put(GlobalTransaction.class.getName(), 1);
-      MAGIC_NUMBERS.put(JGroupsAddress.class.getName(), 2);
-      MAGIC_NUMBERS.put(ArrayList.class.getName(), 3);
-      MAGIC_NUMBERS.put(LinkedList.class.getName(), 4);
-      MAGIC_NUMBERS.put(HashMap.class.getName(), 5);
-      MAGIC_NUMBERS.put(TreeMap.class.getName(), 6);
-      MAGIC_NUMBERS.put(HashSet.class.getName(), 7);
-      MAGIC_NUMBERS.put(TreeSet.class.getName(), 8);
-      MAGIC_NUMBERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", 9);
-      MAGIC_NUMBERS.put(MarshalledValue.class.getName(), 10);
-      MAGIC_NUMBERS.put(FastCopyHashMap.class.getName(), 11);
-      MAGIC_NUMBERS.put("java.util.Collections$SingletonList", 12);
-      MAGIC_NUMBERS.put("org.infinispan.transaction.TransactionLog$LogEntry", 13);
-
-      MAGIC_NUMBERS.put(RequestIgnoredResponse.class.getName(), 14);
-      MAGIC_NUMBERS.put(ExtendedResponse.class.getName(), 15);
-      MAGIC_NUMBERS.put(ExceptionResponse.class.getName(), 16);
-      MAGIC_NUMBERS.put(SuccessfulResponse.class.getName(), 17);
-      MAGIC_NUMBERS.put(UnsuccessfulResponse.class.getName(), 18);
-
-
-      MAGIC_NUMBERS.put(AtomicHashMap.class.getName(), 19);
-      MAGIC_NUMBERS.put(StateTransferControlCommand.class.getName(), 20);
-      MAGIC_NUMBERS.put(ClusteredGetCommand.class.getName(), 21);
-      MAGIC_NUMBERS.put(MultipleRpcCommand.class.getName(), 22);
-      MAGIC_NUMBERS.put(SingleRpcCommand.class.getName(), 23);
-      MAGIC_NUMBERS.put(GetKeyValueCommand.class.getName(), 24);
-      MAGIC_NUMBERS.put(PutKeyValueCommand.class.getName(), 25);
-      MAGIC_NUMBERS.put(RemoveCommand.class.getName(), 26);
-      MAGIC_NUMBERS.put(InvalidateCommand.class.getName(), 27);
-      MAGIC_NUMBERS.put(ReplaceCommand.class.getName(), 28);
-      MAGIC_NUMBERS.put(ClearCommand.class.getName(), 29);
-      MAGIC_NUMBERS.put(PutMapCommand.class.getName(), 30);
-      MAGIC_NUMBERS.put(PrepareCommand.class.getName(), 31);
-      MAGIC_NUMBERS.put(CommitCommand.class.getName(), 32);
-      MAGIC_NUMBERS.put(RollbackCommand.class.getName(), 33);
-
-      MAGIC_NUMBERS.put(ImmortalCacheEntry.class.getName(), 34);
-      MAGIC_NUMBERS.put(MortalCacheEntry.class.getName(), 35);
-      MAGIC_NUMBERS.put(TransientCacheEntry.class.getName(), 36);
-      MAGIC_NUMBERS.put(TransientMortalCacheEntry.class.getName(), 37);
+      MAGIC_NUMBERS.add(HashMap.class.getName());
+      MAGIC_NUMBERS.add(TreeMap.class.getName());
+      MAGIC_NUMBERS.add(FastCopyHashMap.class.getName());
       
-      MAGIC_NUMBERS.put(InvalidateL1Command.class.getName(), 38);
-
-      MAGIC_NUMBERS.put(ImmortalCacheValue.class.getName(), 39);
-      MAGIC_NUMBERS.put(MortalCacheValue.class.getName(), 40);
-      MAGIC_NUMBERS.put(TransientCacheValue.class.getName(), 41);
-      MAGIC_NUMBERS.put(TransientMortalCacheValue.class.getName(), 42);
+      MAGIC_NUMBERS.add(HashSet.class.getName());
+      MAGIC_NUMBERS.add(TreeSet.class.getName());
       
-      MAGIC_NUMBERS.put(LockControlCommand.class.getName(), 43);
+      MAGIC_NUMBERS.add(ClusteredGetCommand.class.getName());
+      MAGIC_NUMBERS.add(MultipleRpcCommand.class.getName());
+      MAGIC_NUMBERS.add(SingleRpcCommand.class.getName());
+      MAGIC_NUMBERS.add(GetKeyValueCommand.class.getName());
+      MAGIC_NUMBERS.add(PutKeyValueCommand.class.getName());
+      MAGIC_NUMBERS.add(RemoveCommand.class.getName());
+      MAGIC_NUMBERS.add(InvalidateCommand.class.getName());
+      MAGIC_NUMBERS.add(ReplaceCommand.class.getName());
+      MAGIC_NUMBERS.add(ClearCommand.class.getName());
+      MAGIC_NUMBERS.add(PutMapCommand.class.getName());
+      MAGIC_NUMBERS.add(PrepareCommand.class.getName());
+      MAGIC_NUMBERS.add(CommitCommand.class.getName());
+      MAGIC_NUMBERS.add(RollbackCommand.class.getName());
+      MAGIC_NUMBERS.add(InvalidateL1Command.class.getName());
+      MAGIC_NUMBERS.add(LockControlCommand.class.getName());
    }
+   
+   /** Class to int mapping providing magic number to be written. Do not use 
+    * this map for storing user classes. For these, please use weak key based 
+    * maps, i.e WeakHashMap */
+   private final IdentityIntMap<Class<?>> numbers = new IdentityIntMap<Class<?>>();
+   /** Contains list of class objects written. When writing, index of each 
+    * class object object, or magic number, is written, and when reading, index 
+    * is used to find the instance in this list.*/
+   private final List<Class<?>> classes = new ArrayList<Class<?>>();
+   private byte index;
 
-   private final Map<Class<?>, Writer> writers = new WeakHashMap<Class<?>, Writer>();
-   private final Map<Byte, Class<?>> classes = new HashMap<Byte, Class<?>>();
-
-   public void init() {
+   public MagicNumberClassTable() {
       try {
-         for (Map.Entry<String, Integer> entry : MAGIC_NUMBERS.entrySet()) {
-            Class clazz = Util.loadClass(entry.getKey());
-            Byte magicNumber = entry.getValue().byteValue();
-            Writer writer = createWriter(magicNumber);
-            writers.put(clazz, writer);
-            classes.put(magicNumber, clazz);
+         for (String entry : MAGIC_NUMBERS) {
+            Class clazz = Util.loadClass(entry);
+            numbers.put(clazz, index++);
+            classes.add(clazz);
          }
       } catch (ClassNotFoundException e) {
          throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
+      } catch (Exception e) {
+         throw new CacheException("Unable to instantiate Externalizer class", e);
       }
    }
 
    public void stop() {
-      writers.clear();
       classes.clear();
+      numbers.clear();
    }
 
-   public Writer getClassWriter(Class<?> clazz) throws IOException {
-      return writers.get(clazz);
+   public void writeClass(Marshaller marshaller, Class<?> clazz) throws IOException {
+      int number = numbers.get(clazz, -1);
+      marshaller.writeByte(number);
    }
 
-   public Class<?> readClass(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
-      byte magicNumber = unmarshaller.readByte();
+   public Class<?> readClass(Unmarshaller unmarshaller) throws IOException {
+      int magicNumber = unmarshaller.readUnsignedByte();
       return classes.get(magicNumber);
    }
-
-   protected Writer createWriter(byte magicNumber) {
-      return new MagicNumberWriter(magicNumber);
-   }
-
-   @Immutable
-   static class MagicNumberWriter implements Writer {
-      private final byte magicNumber;
-
-      MagicNumberWriter(byte magicNumber) {
-         this.magicNumber = magicNumber;
-      }
-
-      public void writeClass(Marshaller marshaller, Class<?> clazz) throws IOException {
-         marshaller.writeByte(magicNumber);
-      }
-   }
+   
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ArrayListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ArrayListExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ArrayListExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -23,12 +23,11 @@
 
 import net.jcip.annotations.Immutable;
 import org.infinispan.marshall.jboss.MarshallUtil;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -40,27 +39,18 @@
  */
 @Immutable
 public class ArrayListExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = 589638638644295615L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       MarshallUtil.marshallCollection((Collection) subject, output);
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       int size = MarshallUtil.readUnsignedInt(input);
       ArrayList l = new ArrayList(size);
       for (int i = 0; i < size; i++) l.add(input.readObject());
       return l;
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op since size was needed both for the creation and list population, 
-      // so all the work was done in createExternal 
-   }
-}
\ No newline at end of file
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/BucketExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/BucketExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/BucketExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss.externalizers;
+
+import java.io.IOException;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.container.entries.InternalCacheEntry;
+
+import org.infinispan.io.UnsignedNumeric;
+import org.infinispan.loaders.bucket.Bucket;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+
+/**
+ * BucketExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class BucketExternalizer implements Externalizer {
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -515803326753484284L;
+
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      Bucket b = (Bucket) subject;
+      UnsignedNumeric.writeUnsignedInt(output, b.getNumEntries());
+      for (InternalCacheEntry se : b.getEntries().values()) output.writeObject(se);
+   }
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      Bucket b = new Bucket();
+      int numEntries = UnsignedNumeric.readUnsignedInt(input);
+      for (int i = 0; i < numEntries; i++) b.addEntry((InternalCacheEntry) input.readObject());
+      return b;
+   }
+
+}

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/DeltaAwareExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/DeltaAwareExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/DeltaAwareExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -23,12 +23,11 @@
 
 import net.jcip.annotations.Immutable;
 import org.infinispan.atomic.DeltaAware;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * DeltaAwareExternalizer.
@@ -38,24 +37,16 @@
  */
 @Immutable
 public class DeltaAwareExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -1635913024455984627L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       DeltaAware dw = (DeltaAware) subject;
-      output.writeObject(dw.delta());
+      output.writeObject(dw.delta());      
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       return input.readObject();
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExceptionResponseExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExceptionResponseExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExceptionResponseExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -1,12 +1,11 @@
 package org.infinispan.marshall.jboss.externalizers;
 
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.remoting.responses.ExceptionResponse;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * Externalizes an ExceptionResponse
@@ -15,17 +14,18 @@
  * @since 4.0
  */
 public class ExceptionResponseExternalizer implements Externalizer {
-   public void writeExternal(Object o, ObjectOutput objectOutput) throws IOException {
-      ExceptionResponse er = (ExceptionResponse) o;
-      objectOutput.writeObject(er.getException());
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -8972357475889354040L;
+
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      ExceptionResponse er = (ExceptionResponse) subject;
+      output.writeObject(er.getException());
    }
 
-   public Object createExternal(Class<?> aClass, ObjectInput objectInput, Creator creator) throws IOException, ClassNotFoundException {
-      return new ExceptionResponse();
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      ExceptionResponse er = new ExceptionResponse();
+      er.setException((Exception) input.readObject());
+      return er;
    }
 
-   public void readExternal(Object o, ObjectInput objectInput) throws IOException, ClassNotFoundException {
-      ExceptionResponse er = (ExceptionResponse) o;
-      er.setException((Exception) objectInput.readObject());
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExtendedResponseExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExtendedResponseExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ExtendedResponseExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,15 +21,15 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
+ import net.jcip.annotations.Immutable;
+
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.remoting.responses.ExtendedResponse;
 import org.infinispan.remoting.responses.Response;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * ExtendedResponseExternalizer.
@@ -39,26 +39,19 @@
  */
 @Immutable
 public class ExtendedResponseExternalizer implements Externalizer {
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = 1529506931234856884L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       ExtendedResponse er = (ExtendedResponse) subject;
       output.writeBoolean(er.isReplayIgnoredRequests());
       output.writeObject(er.getResponse());
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       boolean replayIgnoredRequests = input.readBoolean();
       Response response = (Response) input.readObject();
       return new ExtendedResponse(response, replayIgnoredRequests);
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/GlobalTransactionExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,15 +21,15 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
+ import net.jcip.annotations.Immutable;
+
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.remoting.transport.Address;
 import org.infinispan.transaction.xa.GlobalTransaction;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * GlobalTransactionExternalizer.
@@ -39,29 +39,22 @@
  */
 @Immutable
 public class GlobalTransactionExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -8677909497367726531L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       GlobalTransaction gtx = (GlobalTransaction) subject;
       output.writeLong(gtx.getId());
-      output.writeObject(gtx.getAddress());
+      output.writeObject(gtx.getAddress());      
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
-      return new GlobalTransaction();
-   }
-
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      GlobalTransaction gtx = (GlobalTransaction) subject;
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      GlobalTransaction gtx = new GlobalTransaction();
       long id = input.readLong();
       Object address = input.readObject();
       gtx.setId(id);
       gtx.setAddress((Address) address);
+      return gtx;
    }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheEntryExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheEntryExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,41 +21,37 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
+import  java.io.IOException;
 
 import net.jcip.annotations.Immutable;
 
 import org.infinispan.container.entries.ImmortalCacheEntry;
 import org.infinispan.container.entries.InternalEntryFactory;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * ImmortalCacheEntryExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0 
  */
 @Immutable
 public class ImmortalCacheEntryExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = -5694009544854594909L;
-
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       ImmortalCacheEntry ice = (ImmortalCacheEntry) subject;
       output.writeObject(ice.getKey());
-      output.writeObject(ice.getValue());
+      output.writeObject(ice.getValue());      
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object k = input.readObject();
       Object v = input.readObject();
       return InternalEntryFactory.create(k, v);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheValueExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmortalCacheValueExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,36 +22,34 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
+import net.jcip.annotations.Immutable;
+
 import org.infinispan.container.entries.ImmortalCacheValue;
 import org.infinispan.container.entries.InternalEntryFactory;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * ImmortalCacheValueExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
+ at Immutable
 public class ImmortalCacheValueExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = 1196375204861850495L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       ImmortalCacheValue icv = (ImmortalCacheValue) subject;
-      output.writeObject(icv.getValue());
+      output.writeObject(icv.getValue());      
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object v = input.readObject();
       return InternalEntryFactory.createValue(v);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
 
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmutableMapExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmutableMapExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ImmutableMapExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -23,13 +23,12 @@
 
 import net.jcip.annotations.Immutable;
 import org.infinispan.marshall.jboss.MarshallUtil;
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.util.Immutables;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -41,25 +40,17 @@
  */
 @Immutable
 public class ImmutableMapExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -3592193723750924806L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
-      MarshallUtil.marshallMap((Map) subject, output);
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      MarshallUtil.marshallMap((Map) subject, output);      
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Map map = new HashMap();
       MarshallUtil.unmarshallMap(map, input);
       return Immutables.immutableMapWrap(map);
    }
-
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op since all the work is done in createExternal in order to be able to change identity.
-   }
+   
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/InternalCachedEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/InternalCachedEntryExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/InternalCachedEntryExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -27,6 +27,8 @@
 import org.infinispan.marshall.jboss.MarshallUtil;
 import org.jboss.marshalling.Creator;
 import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
 import java.io.ObjectInput;

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/JGroupsAddressExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/JGroupsAddressExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/JGroupsAddressExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,14 +21,14 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
+import net.jcip .annotations.Immutable;
+
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * JGroupsAddressExternalizer.
@@ -38,25 +38,17 @@
  */
 @Immutable
 public class JGroupsAddressExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = 2400716389425727329L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       JGroupsAddress address = (JGroupsAddress) subject;
       output.writeObject(address.getJGroupsAddress());
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
-      return new JGroupsAddress();
+   public Object readObject(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
+      JGroupsAddress address = new JGroupsAddress();
+      address.setJGroupsAddress((org.jgroups.Address) unmarshaller.readObject());
+      return address;
    }
-
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      JGroupsAddress address = (JGroupsAddress) subject;
-      address.setJGroupsAddress((org.jgroups.Address) input.readObject());
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/LinkedListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/LinkedListExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/LinkedListExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -23,12 +23,11 @@
 
 import net.jcip.annotations.Immutable;
 import org.infinispan.marshall.jboss.MarshallUtil;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.Collection;
 import java.util.LinkedList;
 
@@ -40,28 +39,18 @@
  */
 @Immutable
 public class LinkedListExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -3222803557498456230L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       MarshallUtil.marshallCollection((Collection) subject, output);
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       int size = MarshallUtil.readUnsignedInt(input);
       LinkedList l = new LinkedList();
       for (int i = 0; i < size; i++) l.add(input.readObject());
       return l;
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op since size was needed both for the creation and list population, 
-      // so work was done in createExternal 
-   }
-
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MapExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MapExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MapExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,16 +21,15 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
 import org.infinispan.CacheException;
+import org.infinispan.marshall.jboss.ClassExternalizer;
 import org.infinispan.marshall.jboss.MarshallUtil;
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.util.Util;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.Map;
 
 /**
@@ -40,29 +39,29 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
- at Immutable
-public class MapExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+public class MapExternalizer implements Externalizer, ClassExternalizer.ClassWritable {
+   /** The serialVersionUID */
    private static final long serialVersionUID = -532896252671303391L;
+   private ClassExternalizer classRw;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      classRw.writeClass(output, subject.getClass());
       MarshallUtil.marshallMap((Map) subject, output);
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      Class<?> subjectType = classRw.readClass(input);
+      Map subject = null;
       try {
-         return Util.getInstance(subjectType);
+         subject = (Map) Util.getInstance(subjectType);
       } catch (Exception e) {
          throw new CacheException("Unable to create new instance of ReplicableCommand", e);
       }
+      MarshallUtil.unmarshallMap(subject, input);
+      return subject;
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      MarshallUtil.unmarshallMap((Map) subject, input);
+   public void setClassExternalizer(ClassExternalizer classRw) {
+      this.classRw = classRw;
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MarshalledValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MarshalledValueExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MarshalledValueExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -24,12 +24,11 @@
 import net.jcip.annotations.Immutable;
 import org.infinispan.io.UnsignedNumeric;
 import org.infinispan.marshall.MarshalledValue;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * MarshalledValueExternalizer.
@@ -39,32 +38,25 @@
  */
 @Immutable
 public class MarshalledValueExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = 8473423584918714661L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       MarshalledValue mv = ((MarshalledValue) subject);
       byte[] raw = mv.getRaw();
       UnsignedNumeric.writeUnsignedInt(output, raw.length);
       output.write(raw);
-      output.writeInt(mv.hashCode());
+      output.writeInt(mv.hashCode());      
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
-      return new MarshalledValue();
-   }
-
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      MarshalledValue mv = ((MarshalledValue) subject);
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      MarshalledValue mv = new MarshalledValue();
       int length = UnsignedNumeric.readUnsignedInt(input);
       byte[] b = new byte[length];
       input.readFully(b);
       int hc = input.readInt();
       mv.init(b, hc);
+      return mv;
    }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheEntryExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheEntryExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,42 +22,41 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
+import net.jcip.annotations.Immutable;
+
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.MortalCacheEntry;
 import org.infinispan.io.UnsignedNumeric;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * MortalCacheEntryExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
+ at Immutable
 public class MortalCacheEntryExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = -6500630714670073716L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       MortalCacheEntry ice = (MortalCacheEntry) subject;
       output.writeObject(ice.getKey());
       output.writeObject(ice.getValue());
       UnsignedNumeric.writeUnsignedLong(output, ice.getCreated());
-      output.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs
+      output.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs      
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object k = input.readObject();
       Object v = input.readObject();
       long created = UnsignedNumeric.readUnsignedLong(input);
       Long lifespan = input.readLong();
       return InternalEntryFactory.create(k, v, created, lifespan, -1, -1);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheValueExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/MortalCacheValueExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,40 +22,36 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.MortalCacheValue;
 import org.infinispan.io.UnsignedNumeric;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * MortalCacheValueExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
 public class MortalCacheValueExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = 7962755251611394481L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       MortalCacheValue icv = (MortalCacheValue) subject;
       output.writeObject(icv.getValue());
       UnsignedNumeric.writeUnsignedLong(output, icv.getCreated());
       output.writeLong(icv.getLifespan()); // could be negative so should not use unsigned longs
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object v = input.readObject();
       long created = UnsignedNumeric.readUnsignedLong(input);
       Long lifespan = input.readLong();
       return InternalEntryFactory.createValue(v, created, lifespan, -1, -1);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ReplicableCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ReplicableCommandExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/ReplicableCommandExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,16 +21,15 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
 import org.infinispan.CacheException;
 import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.marshall.jboss.ClassExternalizer;
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.util.Util;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * ReplicableCommandExternalizer.
@@ -38,15 +37,13 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
- at Immutable
-public class ReplicableCommandExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+public class ReplicableCommandExternalizer implements Externalizer, ClassExternalizer.ClassWritable {
+   /** The serialVersionUID */
    private static final long serialVersionUID = 6915200269446867084L;
+   private ClassExternalizer classRw;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      writeClass(output, subject.getClass());
       ReplicableCommand command = (ReplicableCommand) subject;
       output.writeShort(command.getCommandId());
       Object[] args = command.getParameters();
@@ -57,23 +54,8 @@
       }
    }
 
-   /**
-    * In this case, subjectType will contain the class name of the ReplicableCommand subclass to create. Note that
-    * StateTransferControlCommand might need to be treated differently!!!
-    */
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
-      try {
-         ReplicableCommand command = (ReplicableCommand) Util.getInstance(subjectType);
-         return command;
-      } catch (Exception e) {
-         throw new CacheException("Unable to create new instance of ReplicableCommand", e);
-      }
-   }
-
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      ReplicableCommand command = (ReplicableCommand) subject;
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      ReplicableCommand command = (ReplicableCommand)createExternal(input);
       short methodId = input.readShort();
       byte numArgs = input.readByte();
       Object[] args = null;
@@ -82,5 +64,24 @@
          for (int i = 0; i < numArgs; i++) args[i] = input.readObject();
       }
       command.setParameters(methodId, args);
+      return command;
    }
+   
+   protected void writeClass(Marshaller output, Class<?> subjectType) throws IOException {
+      classRw.writeClass(output, subjectType);
+   }
+   
+   protected Object createExternal(Unmarshaller input) throws IOException, ClassNotFoundException {
+      try {
+         Class<?> subjectType = classRw.readClass(input);
+         ReplicableCommand command = (ReplicableCommand) Util.getInstance(subjectType);
+         return command;
+      } catch (Exception e) {
+         throw new CacheException("Unable to create new instance of ReplicableCommand", e);
+      }
+   }
+   
+   public void setClassExternalizer(ClassExternalizer classRw) {
+      this.classRw = classRw;
+   }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SetExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SetExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SetExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -23,14 +23,14 @@
 
 import net.jcip.annotations.Immutable;
 import org.infinispan.CacheException;
+import org.infinispan.marshall.jboss.ClassExternalizer;
 import org.infinispan.marshall.jboss.MarshallUtil;
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.util.Util;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.Collection;
 import java.util.Set;
 
@@ -41,30 +41,31 @@
  * @since 4.0
  */
 @Immutable
-public class SetExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+public class SetExternalizer implements Externalizer, ClassExternalizer.ClassWritable {
+   /** The serialVersionUID */
    private static final long serialVersionUID = -3147427397000304867L;
+   private ClassExternalizer classRw;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      classRw.writeClass(output, subject.getClass());
       MarshallUtil.marshallCollection((Collection) subject, output);
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      Class<?> subjectType = classRw.readClass(input);
+      Set subject = null;
       try {
-         return Util.getInstance(subjectType);
+         subject = (Set) Util.getInstance(subjectType);
       } catch (Exception e) {
          throw new CacheException("Unable to create new instance of ReplicableCommand", e);
       }
+      int size = MarshallUtil.readUnsignedInt(input);
+      for (int i = 0; i < size; i++) subject.add(input.readObject());
+      return subject;
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      Set set = (Set) subject;
-      int size = MarshallUtil.readUnsignedInt(input);
-      for (int i = 0; i < size; i++) set.add(input.readObject());
+   public void setClassExternalizer(ClassExternalizer classRw) {
+      this.classRw = classRw;
    }
+
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SingletonListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SingletonListExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SingletonListExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,13 +21,13 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import net.jcip.annotations.Immutable; 
 
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 import java.util.Collections;
 import java.util.List;
 
@@ -39,24 +39,15 @@
  */
 @Immutable
 public class SingletonListExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -714785461531351642L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       output.writeObject(((List) subject).get(0));
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       return Collections.singletonList(input.readObject());
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op since all the work is done during create.
-   }
-
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/StateTransferControlCommandExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,12 +21,12 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import org.infinispan.commands.control.StateTransferControlCommand;
+import org.infinispan.commands.control.StateTransferControlCommand; 
 import org.infinispan.remoting.transport.Transport;
-import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
 
 /**
  * StateTransferControlCommandExternalizer.
@@ -35,26 +35,21 @@
  * @since 4.0
  */
 public class StateTransferControlCommandExternalizer extends ReplicableCommandExternalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -3743458410265076691L;
-
    private Transport transport;
 
    public void init(Transport transport) {
       this.transport = transport;
    }
 
-   /**
-    * In this case, subjectType will contain the class name of the ReplicableCommand subclass to create.
-    * <p/>
-    * Note that StateTransferControlCommand might need to be treated differently!!! Todo: check outcome of email sent to
-    * dev list.
-    */
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   @Override
+   protected void writeClass(Marshaller output, Class<?> subjectType) throws IOException {
+      // No-op
+   }
+
+   @Override
+   protected Object createExternal(Unmarshaller input) throws IOException, ClassNotFoundException {
       StateTransferControlCommand command = new StateTransferControlCommand();
       command.init(transport);
       return command;

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SuccessfulResponseExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SuccessfulResponseExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/SuccessfulResponseExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -1,12 +1,13 @@
 package org.infinispan.marshall.jboss.externalizers;
 
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.marshall.jboss.Externalizer; 
 import org.infinispan.remoting.responses.SuccessfulResponse;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * Externalizes a SuccessfulResponse
@@ -14,18 +15,18 @@
  * @author Manik Surtani
  * @since 4.0
  */
+ at Immutable
 public class SuccessfulResponseExternalizer implements Externalizer {
-   public void writeExternal(Object o, ObjectOutput objectOutput) throws IOException {
-      SuccessfulResponse sr = (SuccessfulResponse) o;
-      objectOutput.writeObject(sr.getResponseValue());
+
+   public void writeObject(Marshaller output, Object subject) throws IOException {
+      SuccessfulResponse sr = (SuccessfulResponse) subject;
+      output.writeObject(sr.getResponseValue());      
    }
 
-   public Object createExternal(Class<?> aClass, ObjectInput objectInput, Creator creator) throws IOException, ClassNotFoundException {
-      return new SuccessfulResponse();
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
+      SuccessfulResponse sr = new SuccessfulResponse();
+      sr.setResponseValue(input.readObject());
+      return sr;
    }
 
-   public void readExternal(Object o, ObjectInput objectInput) throws IOException, ClassNotFoundException {
-      SuccessfulResponse sr = (SuccessfulResponse) o;
-      sr.setResponseValue(objectInput.readObject());
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransactionLogExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -21,17 +21,16 @@
  */
 package org.infinispan.marshall.jboss.externalizers;
 
-import net.jcip.annotations.Immutable;
+import net.jcip.annotations.Immutable; 
 import org.infinispan.commands.write.WriteCommand;
 import org.infinispan.marshall.jboss.MarshallUtil;
+import org.infinispan.marshall.jboss.Externalizer;
 import org.infinispan.transaction.xa.GlobalTransaction;
 import org.infinispan.transaction.TransactionLog;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 /**
  * TransactionLogExternalizer.
@@ -41,13 +40,10 @@
  */
 @Immutable
 public class TransactionLogExternalizer implements Externalizer {
-
-   /**
-    * The serialVersionUID
-    */
+   /** The serialVersionUID */
    private static final long serialVersionUID = -7341096933735222157L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       TransactionLog.LogEntry le = (TransactionLog.LogEntry) subject;
       output.writeObject(le.getTransaction());
       WriteCommand[] cmds = le.getModifications();
@@ -56,8 +52,7 @@
          output.writeObject(c);
    }
 
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       GlobalTransaction gtx = (GlobalTransaction) input.readObject();
       int numCommands = MarshallUtil.readUnsignedInt(input);
       WriteCommand[] cmds = new WriteCommand[numCommands];
@@ -65,8 +60,4 @@
       return new TransactionLog.LogEntry(gtx, cmds);
    }
 
-   public void readExternal(Object subject, ObjectInput input) throws IOException,
-                                                                      ClassNotFoundException {
-      // No-op since the initialisation the creation and read happens during the create phase.
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheEntryExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheEntryExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,42 +22,38 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.TransientCacheEntry;
 import org.infinispan.io.UnsignedNumeric;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * TransientCacheEntryExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
 public class TransientCacheEntryExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = -1076893995615398371L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       TransientCacheEntry ice = (TransientCacheEntry) subject;
       output.writeObject(ice.getKey());
       output.writeObject(ice.getValue());
       UnsignedNumeric.writeUnsignedLong(output, ice.getLastUsed());
       output.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object k = input.readObject();
       Object v = input.readObject();
       long lastUsed = UnsignedNumeric.readUnsignedLong(input);
       Long maxIdle = input.readLong();
       return InternalEntryFactory.create(k, v, -1, -1, lastUsed, maxIdle);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheValueExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientCacheValueExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,41 +22,36 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.TransientCacheValue;
 import org.infinispan.io.UnsignedNumeric;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * TransientCacheValueExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
 public class TransientCacheValueExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = 7600812173331344919L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       TransientCacheValue icv = (TransientCacheValue) subject;
       output.writeObject(icv.getValue());
       UnsignedNumeric.writeUnsignedLong(output, icv.getLastUsed());
       output.writeLong(icv.getMaxIdle()); // could be negative so should not use unsigned longs
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object v = input.readObject();
       long lastUsed = UnsignedNumeric.readUnsignedLong(input);
       Long maxIdle = input.readLong();
       return InternalEntryFactory.createValue(v, -1, -1, lastUsed, maxIdle);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
 
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheEntryExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheEntryExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,25 +22,25 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.TransientMortalCacheEntry;
 import org.infinispan.io.UnsignedNumeric;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * TransientMortalCacheEntryExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
 public class TransientMortalCacheEntryExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = -1076893995615398371L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       TransientMortalCacheEntry ice = (TransientMortalCacheEntry) subject;
       output.writeObject(ice.getKey());
       output.writeObject(ice.getValue());
@@ -49,9 +49,8 @@
       UnsignedNumeric.writeUnsignedLong(output, ice.getLastUsed());
       output.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object k = input.readObject();
       Object v = input.readObject();
       long created = UnsignedNumeric.readUnsignedLong(input);
@@ -60,8 +59,4 @@
       Long maxIdle = input.readLong();
       return InternalEntryFactory.create(k, v, created, lifespan, lastUsed, maxIdle);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheValueExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/TransientMortalCacheValueExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -22,25 +22,25 @@
 package org.infinispan.marshall.jboss.externalizers;
 
 import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
 
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.TransientMortalCacheValue;
 import org.infinispan.io.UnsignedNumeric;
-import org.jboss.marshalling.Creator;
-import org.jboss.marshalling.Externalizer;
+import org.infinispan.marshall.jboss.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 /**
  * TransientMortalCacheValueExternalizer.
  * 
  * @author Galder Zamarreño
+ * @since 4.0
  */
 public class TransientMortalCacheValueExternalizer implements Externalizer {
    /** The serialVersionUID */
    private static final long serialVersionUID = 8471189995556621061L;
 
-   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+   public void writeObject(Marshaller output, Object subject) throws IOException {
       TransientMortalCacheValue icv = (TransientMortalCacheValue) subject;
       output.writeObject(icv.getValue());
       UnsignedNumeric.writeUnsignedLong(output, icv.getCreated());
@@ -48,9 +48,8 @@
       UnsignedNumeric.writeUnsignedLong(output, icv.getLastUsed());
       output.writeLong(icv.getMaxIdle()); // could be negative so should not use unsigned longs
    }
-   
-   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
-         throws IOException, ClassNotFoundException {
+
+   public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
       Object v = input.readObject();
       long created = UnsignedNumeric.readUnsignedLong(input);
       Long lifespan = input.readLong();
@@ -58,9 +57,4 @@
       Long maxIdle = input.readLong();
       return InternalEntryFactory.createValue(v, created, lifespan, lastUsed, maxIdle);
    }
-   
-   public void readExternal(Object subject, ObjectInput input) throws IOException, ClassNotFoundException {
-      // No-op
-   }
-
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/UnsuccessfulResponseExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/UnsuccessfulResponseExternalizer.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/externalizers/UnsuccessfulResponseExternalizer.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -3,6 +3,8 @@
 import org.infinispan.remoting.responses.UnsuccessfulResponse;
 import org.jboss.marshalling.Creator;
 import org.jboss.marshalling.Externalizer;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
 
 import java.io.IOException;
 import java.io.ObjectInput;

Modified: trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/test/java/org/infinispan/marshall/MarshallersTest.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -38,10 +38,15 @@
 import org.infinispan.commands.write.RemoveCommand;
 import org.infinispan.commands.write.ReplaceCommand;
 import org.infinispan.container.entries.ImmortalCacheEntry;
+import org.infinispan.container.entries.ImmortalCacheValue;
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.MortalCacheEntry;
+import org.infinispan.container.entries.MortalCacheValue;
 import org.infinispan.container.entries.TransientCacheEntry;
+import org.infinispan.container.entries.TransientCacheValue;
 import org.infinispan.container.entries.TransientMortalCacheEntry;
+import org.infinispan.container.entries.TransientMortalCacheValue;
+import org.infinispan.loaders.bucket.Bucket;
 import org.infinispan.marshall.jboss.JBossMarshaller;
 import org.infinispan.remoting.responses.ExtendedResponse;
 import org.infinispan.remoting.responses.RequestIgnoredResponse;
@@ -311,6 +316,71 @@
       checkEqualityAndSize(entry4);
    }
    
+   public void testInternalCacheValueMarshalling() throws Exception {
+      byte[] bytes = null;
+      ImmortalCacheValue value1 = (ImmortalCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), -1);
+      List<Integer> sizes = new ArrayList<Integer>(2);
+      for (Marshaller marshaller : marshallers) {
+         bytes = marshaller.objectToByteBuffer(value1);
+         ImmortalCacheValue rvalue1 = (ImmortalCacheValue) marshaller.objectFromByteBuffer(bytes);
+         assert rvalue1.getValue().equals(value1.getValue()) : "Writen[" + rvalue1.getValue() + "] and read[" + value1.getValue() + "] objects should be the same";
+         sizes.add(bytes.length);
+      }
+      assert sizes.get(1) < sizes.get(0) : "JBoss Marshaller should write less bytes: bytesJBoss=" + sizes.get(1) + ", bytesHome=" + sizes.get(0);
+
+      sizes.clear();
+      for (Marshaller marshaller : marshallers) {
+         MortalCacheValue value2 = (MortalCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), -1);
+         bytes = marshaller.objectToByteBuffer(value2);
+         MortalCacheValue rvalue2 = (MortalCacheValue) marshaller.objectFromByteBuffer(bytes);
+         assert rvalue2.getValue().equals(value2.getValue()) : "Writen[" + rvalue2.getValue() + "] and read[" + value2.getValue() + "] objects should be the same";
+         sizes.add(bytes.length);
+      }
+      assert sizes.get(1) < sizes.get(0) : "JBoss Marshaller should write less bytes: bytesJBoss=" + sizes.get(1) + ", bytesHome=" + sizes.get(0);
+         
+      sizes.clear();
+      for (Marshaller marshaller : marshallers) {
+         TransientCacheValue value3 = (TransientCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), 4000000);
+         bytes = marshaller.objectToByteBuffer(value3);
+         TransientCacheValue rvalue3 = (TransientCacheValue) marshaller.objectFromByteBuffer(bytes);
+         assert rvalue3.getValue().equals(value3.getValue()) : "Writen[" + rvalue3.getValue() + "] and read[" + value3.getValue() + "] objects should be the same";
+         sizes.add(bytes.length);
+      }
+      assert sizes.get(1) < sizes.get(0) : "JBoss Marshaller should write less bytes: bytesJBoss=" + sizes.get(1) + ", bytesHome=" + sizes.get(0);
+      
+      sizes.clear();
+      for (Marshaller marshaller : marshallers) {
+         TransientMortalCacheValue value4 = (TransientMortalCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
+         bytes = marshaller.objectToByteBuffer(value4);
+         TransientMortalCacheValue rvalue4 = (TransientMortalCacheValue) marshaller.objectFromByteBuffer(bytes);
+         assert rvalue4.getValue().equals(value4.getValue()) : "Writen[" + rvalue4.getValue() + "] and read[" + value4.getValue() + "] objects should be the same";
+         sizes.add(bytes.length);
+      }
+      assert sizes.get(1) < sizes.get(0) : "JBoss Marshaller should write less bytes: bytesJBoss=" + sizes.get(1) + ", bytesHome=" + sizes.get(0);
+   }
+   
+   public void testBucketMarshalling() throws Exception {
+      ImmortalCacheEntry entry1 = (ImmortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), -1);
+      MortalCacheEntry entry2 = (MortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), -1);
+      TransientCacheEntry entry3 = (TransientCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), 4000000);
+      TransientMortalCacheEntry entry4 = (TransientMortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
+      Bucket b = new Bucket();
+      b.setBucketName("mybucket");
+      b.addEntry(entry1);
+      b.addEntry(entry2);
+      b.addEntry(entry3);
+      b.addEntry(entry4);
+      
+      List<Integer> sizes = new ArrayList<Integer>(2);
+      for (Marshaller marshaller : marshallers) {
+         byte[] bytes = marshaller.objectToByteBuffer(b);
+         Bucket rb = (Bucket) marshaller.objectFromByteBuffer(bytes);
+         assert rb.getEntries().equals(b.getEntries()) : "Writen[" + b.getEntries() + "] and read[" + rb.getEntries() + "] objects should be the same";         
+         sizes.add(bytes.length);
+      }
+      assert sizes.get(1) < sizes.get(0) : "JBoss Marshaller should write less bytes: bytesJBoss=" + sizes.get(1) + ", bytesHome=" + sizes.get(0);
+   }
+   
    protected void checkEqualityAndSize(Object writeObj) throws Exception {
       int bytesH = marshallAndAssertEquality(home, writeObj);
       int bytesJ = marshallAndAssertEquality(jboss, writeObj);

Modified: trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java	2009-05-21 13:47:21 UTC (rev 333)
+++ trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java	2009-05-21 22:11:21 UTC (rev 334)
@@ -37,10 +37,15 @@
 import org.infinispan.commands.write.RemoveCommand;
 import org.infinispan.commands.write.ReplaceCommand;
 import org.infinispan.container.entries.ImmortalCacheEntry;
+import org.infinispan.container.entries.ImmortalCacheValue;
 import org.infinispan.container.entries.InternalEntryFactory;
 import org.infinispan.container.entries.MortalCacheEntry;
+import org.infinispan.container.entries.MortalCacheValue;
 import org.infinispan.container.entries.TransientCacheEntry;
+import org.infinispan.container.entries.TransientCacheValue;
 import org.infinispan.container.entries.TransientMortalCacheEntry;
+import org.infinispan.container.entries.TransientMortalCacheValue;
+import org.infinispan.loaders.bucket.Bucket;
 import org.infinispan.marshall.MarshalledValue;
 import org.infinispan.remoting.responses.ExtendedResponse;
 import org.infinispan.remoting.responses.RequestIgnoredResponse;
@@ -267,7 +272,46 @@
       TransientMortalCacheEntry entry4 = (TransientMortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
       marshallAndAssertEquality(entry4);
    }
+   
+   public void testInternalCacheValueMarshalling() throws Exception {
+      ImmortalCacheValue value1 = (ImmortalCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), -1);
+      byte[] bytes = marshaller.objectToByteBuffer(value1);
+      ImmortalCacheValue rvalue1 = (ImmortalCacheValue) marshaller.objectFromByteBuffer(bytes);
+      assert rvalue1.getValue().equals(value1.getValue()) : "Writen[" + rvalue1.getValue() + "] and read[" + value1.getValue() + "] objects should be the same";
 
+      MortalCacheValue value2 = (MortalCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), -1);
+      bytes = marshaller.objectToByteBuffer(value2);
+      MortalCacheValue rvalue2 = (MortalCacheValue) marshaller.objectFromByteBuffer(bytes);
+      assert rvalue2.getValue().equals(value2.getValue()) : "Writen[" + rvalue2.getValue() + "] and read[" + value2.getValue() + "] objects should be the same";
+      
+      TransientCacheValue value3 = (TransientCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), 4000000);
+      bytes = marshaller.objectToByteBuffer(value3);
+      TransientCacheValue rvalue3 = (TransientCacheValue) marshaller.objectFromByteBuffer(bytes);
+      assert rvalue3.getValue().equals(value3.getValue()) : "Writen[" + rvalue3.getValue() + "] and read[" + value3.getValue() + "] objects should be the same";
+      
+      TransientMortalCacheValue value4 = (TransientMortalCacheValue) InternalEntryFactory.createValue("value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
+      bytes = marshaller.objectToByteBuffer(value4);
+      TransientMortalCacheValue rvalue4 = (TransientMortalCacheValue) marshaller.objectFromByteBuffer(bytes);
+      assert rvalue4.getValue().equals(value4.getValue()) : "Writen[" + rvalue4.getValue() + "] and read[" + value4.getValue() + "] objects should be the same";
+   }
+   
+   public void testBucketMarshalling() throws Exception {
+      ImmortalCacheEntry entry1 = (ImmortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), -1);
+      MortalCacheEntry entry2 = (MortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), -1);
+      TransientCacheEntry entry3 = (TransientCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), 4000000);
+      TransientMortalCacheEntry entry4 = (TransientMortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
+      Bucket b = new Bucket();
+      b.setBucketName("mybucket");
+      b.addEntry(entry1);
+      b.addEntry(entry2);
+      b.addEntry(entry3);
+      b.addEntry(entry4);
+      
+      byte[] bytes = marshaller.objectToByteBuffer(b);
+      Bucket rb = (Bucket) marshaller.objectFromByteBuffer(bytes);
+      assert rb.getEntries().equals(b.getEntries()) : "Writen[" + b.getEntries() + "] and read[" + rb.getEntries() + "] objects should be the same";
+   }
+
    protected void marshallAndAssertEquality(Object writeObj) throws Exception {
       byte[] bytes = marshaller.objectToByteBuffer(writeObj);
       Object readObj = marshaller.objectFromByteBuffer(bytes);




More information about the infinispan-commits mailing list