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

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Tue Apr 14 14:09:18 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-04-14 14:09:18 -0400 (Tue, 14 Apr 2009)
New Revision: 113

Added:
   trunk/core/src/main/java/org/infinispan/marshall/jboss/
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java
   trunk/core/src/test/java/org/infinispan/marshall/jboss/
   trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
Modified:
   trunk/core/
   trunk/core/pom.xml
   trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java
   trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
   trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java
   trunk/core/src/main/java/org/infinispan/util/Util.java
   trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java
   trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java
   trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java
Log:
[ISPN-44] (Integrate JBoss Marshalling) JBMAR based marshalling framework added, integrated and tested.


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


Modified: trunk/core/pom.xml
===================================================================
--- trunk/core/pom.xml	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/pom.xml	2009-04-14 18:09:18 UTC (rev 113)
@@ -44,12 +44,26 @@
          <artifactId>jboss-common-core</artifactId>
          <version>2.2.10.GA</version>
       </dependency>
-
+      
       <dependency>
+         <groupId>org.jboss.marshalling</groupId>
+         <artifactId>marshalling-api</artifactId>
+         <version>1.1.1.GA</version>
+      </dependency>
+      
+      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.14</version>
          <optional>true</optional>
       </dependency>
+
+      <dependency>
+         <groupId>org.jboss.marshalling</groupId>
+         <artifactId>river</artifactId>
+         <version>1.1.1.GA</version>
+         <scope>test</scope>
+      </dependency>
+
    </dependencies>
 </project>

Modified: trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -40,6 +40,7 @@
 import org.infinispan.transaction.TransactionLog;
 import org.infinispan.util.FastCopyHashMap;
 import org.infinispan.util.Immutables;
+import org.infinispan.util.Util;
 import org.jboss.util.NotImplementedException;
 import org.jboss.util.stream.MarshalledValueInputStream;
 
@@ -47,8 +48,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInput;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
+import java.io.OutputStream;
 import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.util.*;
@@ -57,6 +60,7 @@
  * Abstract marshaller
  *
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ * @author Galder Zamarreño
  * @since 4.0
  */
 public class HorizonMarshaller implements Marshaller {
@@ -795,6 +799,14 @@
             c.equals(Double.class));
    }
 
+   public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+      return new ObjectOutputStream(os);
+   }
+   
+   public void finishObjectOutput(ObjectOutput oo) {
+      Util.flushAndCloseOutput(oo);
+   }
+   
    public void objectToObjectStream(Object o, ObjectOutput out) throws IOException {
       Map<Object, Integer> refMap = useRefs ? new IdentityHashMap<Object, Integer>() : null;
       ClassLoader toUse = defaultClassLoader;
@@ -810,6 +822,14 @@
          current.setContextClassLoader(old);
       }
    }
+   
+   public ObjectInput startObjectInput(InputStream is) throws IOException {
+      return new ObjectInputStream(is);
+   }
+   
+   public void finishObjectInput(ObjectInput oi) {
+      Util.closeInput(oi);
+   }
 
    public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
       UnmarshalledReferences refMap = useRefs ? new UnmarshalledReferences() : null;

Modified: trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -29,6 +29,7 @@
 import java.io.InputStream;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.io.OutputStream;
 
 /**
  * A marshaller is a class that is able to marshall and unmarshall objects efficiently.
@@ -52,11 +53,33 @@
  * transferring state en-masse.
  *
  * @author <a href="mailto://manik@jboss.org">Manik Surtani</a>
+ * @author Galder Zamarreño
  * @since 4.0
  */
 @Scope(Scopes.GLOBAL)
 public interface Marshaller {
+   
    /**
+    * Create and open a new ObjectOutput for the given output stream. This 
+    * method should be used for opening data outpus when multiple 
+    * objectToObjectStream() calls will be made before the stream is closed
+    * 
+    * @param os output stream 
+    * @return ObjectOutput to write to
+    * @throws IOException
+    */
+   ObjectOutput startObjectOutput(OutputStream os) throws IOException;
+   
+   /**
+    * Finish using the given ObjectOutput. After opening a ObjectOutput and 
+    * calling objectToObjectStream() mutliple times, use this method to flush 
+    * the data and close if necessary
+    * 
+    * @param oo data output that finished using
+    */
+   void finishObjectOutput(ObjectOutput oo);
+   
+   /**
     * Marshalls an object to a given {@link java.io.ObjectOutput}
     *
     * @param obj object to marshall
@@ -65,6 +88,26 @@
    void objectToObjectStream(Object obj, ObjectOutput out) throws IOException;
 
    /**
+    * Create and open a new ObjectInput for the given input stream. This 
+    * method should be used for opening data inputs when multiple 
+    * objectFromObjectStream() calls will be made before the stream is closed.
+    * 
+    * @param is input stream 
+    * @return ObjectInput to read from
+    * @throws IOException
+    */
+   ObjectInput startObjectInput(InputStream is) throws IOException;
+   
+   /**
+    * Finish using the given ObjectInput. After opening a ObjectInput and 
+    * calling objectFromObjectStream() mutliple times, use this method to flush 
+    * the data and close if necessary
+    * 
+    * @param oi data input that finished using
+    */
+   void finishObjectInput(ObjectInput oi);
+   
+   /**
     * Unmarshalls an object from an {@link java.io.ObjectInput}
     *
     * @param in stream to unmarshall from

Modified: trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -36,6 +36,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
+import java.io.OutputStream;
 
 /**
  * A delegate to various other marshallers like {@link HorizonMarshaller}. This delegating marshaller adds versioning
@@ -43,7 +44,7 @@
  * based on the versioning information when unmarshalling objects.
  *
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ * @author Galder Zamarreño
  * @since 4.0
  */
 public class VersionAwareMarshaller implements Marshaller {
@@ -109,12 +110,28 @@
       }
       return defaultMarshaller.objectFromObjectStream(in);
    }
+   
+   public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+      return defaultMarshaller.startObjectOutput(os);
+   }
+   
+   public void finishObjectOutput(ObjectOutput oo) {
+      defaultMarshaller.finishObjectOutput(oo);
+   }
 
    public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
       out.writeShort(VERSION_400);
       log.trace("Wrote version {0}", VERSION_400);
       defaultMarshaller.objectToObjectStream(obj, out);
    }
+   
+   public ObjectInput startObjectInput(InputStream is) throws IOException {
+      return defaultMarshaller.startObjectInput(is);
+   }
+   
+   public void finishObjectInput(ObjectInput oi) {
+      defaultMarshaller.finishObjectInput(oi);
+   }
 
    public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
       int versionId;

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,64 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * List externalizer dealing with ArrayList and LinkedList implementations.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ArrayListExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 589638638644295615L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      MarshallUtil.marshallCollection((Collection) subject, output);
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            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/CustomObjectTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,84 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.jgroups.RequestIgnoredResponse;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.ObjectTable;
+import org.jboss.marshalling.Unmarshaller;
+
+/**
+ * CustomObjectTable.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class CustomObjectTable implements ObjectTable {
+   
+   private final List<Object> objects = new ArrayList<Object>();
+   private final Map<Object, Writer> writers = new IdentityHashMap<Object, Writer>();
+   private byte index;
+   
+   public void init() {
+      objects.add(RequestIgnoredResponse.INSTANCE);
+      writers.put(RequestIgnoredResponse.INSTANCE, new CustomObjectWriter(index++));
+   }
+   
+   public void stop() {
+      writers.clear();
+      objects.clear();
+   }
+   
+   public void add(Object o) {
+      objects.add(o);
+      writers.put(o, new CustomObjectWriter(index++));      
+   }
+
+   public Writer getObjectWriter(Object o) throws IOException {
+      return writers.get(o);
+   }
+
+   public Object readObject(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
+      return objects.get(unmarshaller.readUnsignedByte());
+   }
+
+   @Immutable
+   static class CustomObjectWriter implements Writer {
+      private final byte id;
+
+      CustomObjectWriter(byte objectId) {
+         this.id = objectId;
+      }
+      
+      public void writeObject(Marshaller marshaller, Object object) throws IOException {
+         marshaller.write(id);
+      }      
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -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;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.atomic.DeltaAware;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * DeltaAwareExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class DeltaAwareExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -1635913024455984627L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      DeltaAware dw = (DeltaAware) subject;
+      output.writeObject(dw.delta());
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            throws IOException, ClassNotFoundException {
+      return input.readObject();
+   }
+
+   public void readExternal(Object subject, ObjectInput input) throws IOException,
+            ClassNotFoundException {
+      // No-op
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,62 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.jgroups.ExtendedResponse;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * ExtendedResponseExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ExtendedResponseExternalizer implements Externalizer {
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1529506931234856884L;
+
+   public void writeExternal(Object subject, ObjectOutput output) 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 {
+      boolean replayIgnoredRequests = input.readBoolean();
+      Object response = input.readObject();
+      return new ExtendedResponse(response, replayIgnoredRequests);
+   }
+
+   public void readExternal(Object subject, ObjectInput input) throws IOException,
+            ClassNotFoundException {
+      // No-op
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,121 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.remoting.RpcManager;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.ClassExternalizerFactory;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * CustomExternalizerFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ExternalizerClassFactory implements ClassExternalizerFactory {
+   private static final Map<String, String> EXTERNALIZERS = new HashMap<String, String>();
+   
+   static {
+      EXTERNALIZERS.put("org.infinispan.transaction.GlobalTransaction", "org.infinispan.marshall.jboss.GlobalTransactionExternalizer"); 
+      EXTERNALIZERS.put("org.infinispan.remoting.transport.jgroups.JGroupsAddress", "org.infinispan.marshall.jboss.JGroupsAddressExternalizer"); 
+      EXTERNALIZERS.put("java.util.ArrayList", "org.infinispan.marshall.jboss.ArrayListExternalizer");
+      EXTERNALIZERS.put("java.util.LinkedList", "org.infinispan.marshall.jboss.LinkedListExternalizer");
+      EXTERNALIZERS.put("java.util.HashMap", "org.infinispan.marshall.jboss.MapExternalizer");
+      EXTERNALIZERS.put("java.util.TreeMap", "org.infinispan.marshall.jboss.MapExternalizer");
+      EXTERNALIZERS.put("java.util.HashSet", "org.infinispan.marshall.jboss.SetExternalizer");
+      EXTERNALIZERS.put("java.util.TreeSet", "org.infinispan.marshall.jboss.SetExternalizer");
+      EXTERNALIZERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", "org.infinispan.marshall.jboss.ImmutableMapExternalizer");
+      EXTERNALIZERS.put("org.infinispan.marshall.MarshalledValue", "org.infinispan.marshall.jboss.MarshalledValueExternalizer");
+      EXTERNALIZERS.put("org.infinispan.util.FastCopyHashMap", "org.infinispan.marshall.jboss.MapExternalizer");
+      EXTERNALIZERS.put("java.util.Collections$SingletonList", "org.infinispan.marshall.jboss.SingletonListExternalizer");
+      EXTERNALIZERS.put("org.infinispan.transaction.TransactionLog$LogEntry", "org.infinispan.marshall.jboss.TransactionLogExternalizer");
+      EXTERNALIZERS.put("org.infinispan.remoting.transport.jgroups.ExtendedResponse", "org.infinispan.marshall.jboss.ExtendedResponseExternalizer");
+      EXTERNALIZERS.put("org.infinispan.atomic.AtomicHashMap", "org.infinispan.marshall.jboss.DeltaAwareExternalizer");
+
+      EXTERNALIZERS.put("org.infinispan.commands.control.StateTransferControlCommand", "org.infinispan.marshall.jboss.StateTransferControlCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.remote.ClusteredGetCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.remote.MultipleRpcCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.remote.SingleRpcCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");      
+      EXTERNALIZERS.put("org.infinispan.commands.read.GetKeyValueCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.write.PutKeyValueCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.write.RemoveCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.write.InvalidateCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.write.ReplaceCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.write.ClearCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.write.PutMapCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.tx.PrepareCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.tx.CommitCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+      EXTERNALIZERS.put("org.infinispan.commands.tx.RollbackCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+
+      EXTERNALIZERS.put("org.infinispan.container.entries.ImmortalCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+      EXTERNALIZERS.put("org.infinispan.container.entries.MortalCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+      EXTERNALIZERS.put("org.infinispan.container.entries.TransientCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+      EXTERNALIZERS.put("org.infinispan.container.entries.TransientMortalCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+   }
+   
+   private final Map<Class<?>, Externalizer> externalizers = new WeakHashMap<Class<?>, Externalizer>();
+   private final RpcManager rpcManager;
+   private final CustomObjectTable objectTable;
+   
+   public ExternalizerClassFactory(RpcManager rpcManager, CustomObjectTable objectTable) {
+      this.rpcManager = rpcManager;
+      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(rpcManager);
+		}
+		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);
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,66 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.transaction.GlobalTransaction;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * GlobalTransactionExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class GlobalTransactionExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -8677909497367726531L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      GlobalTransaction gtx = (GlobalTransaction) subject;
+      output.writeLong(gtx.getId());
+      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;
+      long id = input.readLong();
+      Object address = input.readObject();
+      gtx.setId(id);
+      gtx.setAddress((Address) address);
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,63 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.util.Immutables;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * ImmutableExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ImmutableMapExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -3592193723750924806L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      MarshallUtil.marshallMap((Map)subject, output);
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            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.
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,82 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * InternalCachedEntryExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class InternalCachedEntryExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -3475239737916428837L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      InternalCacheEntry ice = (InternalCacheEntry) subject;
+      output.writeObject(ice.getKey());
+      output.writeObject(ice.getValue());
+      if (ice.canExpire()) {
+         output.writeBoolean(true);
+         MarshallUtil.writeUnsignedLong(output, ice.getCreated());
+         output.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs
+         MarshallUtil.writeUnsignedLong(output, ice.getLastUsed());
+         output.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs
+      } else {
+         output.writeBoolean(false);
+      }
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            throws IOException, ClassNotFoundException {
+      Object k = input.readObject();
+      Object v = input.readObject();
+      boolean canExpire = input.readBoolean();
+      if (canExpire) {
+         long created = MarshallUtil.readUnsignedLong(input);
+         long lifespan = input.readLong(); // could be negative so should not use unsigned longs
+         long lastUsed = MarshallUtil.readUnsignedLong(input);
+         long maxIdle = input.readLong(); // could be negative so should not use unsigned longs
+         return InternalEntryFactory.create(k, v, created, lifespan, lastUsed, maxIdle);
+      } else {
+         return InternalEntryFactory.create(k, v);
+      }
+   }
+
+   public void readExternal(Object subject, ObjectInput input) throws IOException,
+            ClassNotFoundException {
+      // No-op
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,206 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.OutputStream;
+
+import org.infinispan.CacheException;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.factories.annotations.Stop;
+import org.infinispan.factories.scopes.Scope;
+import org.infinispan.factories.scopes.Scopes;
+import org.infinispan.io.ByteBuffer;
+import org.infinispan.io.ExposedByteArrayOutputStream;
+import org.infinispan.logging.Log;
+import org.infinispan.logging.LogFactory;
+import org.infinispan.marshall.Marshaller;
+import org.infinispan.remoting.RpcManager;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.ContextClassResolver;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.reflect.SunReflectiveCreator;
+
+/**
+ * JBossMarshaller.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Scope(Scopes.GLOBAL)
+public class JBossMarshaller implements Marshaller {
+   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, RpcManager rpcManager) {
+      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);         
+      } catch(Exception e) {
+         throw new CacheException("Unable to load JBoss Marshalling marshaller factory " + DEFAULT_MARSHALLER_FACTORY, e);
+      }
+
+      classTable = createMagicNumberClassTable();
+      objectTable = createCustomObjectTable();
+      externalizerFactoryAndObjectTable = createCustomExternalizerFactory(rpcManager, objectTable);
+
+      configuration = new MarshallingConfiguration();
+      configuration.setCreator(new SunReflectiveCreator());
+      configuration.setClassTable(classTable);
+      configuration.setClassExternalizerFactory(externalizerFactoryAndObjectTable);
+      configuration.setObjectTable(objectTable);
+
+      // 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 {
+      ByteBuffer b = objectToBuffer(obj);
+      byte[] bytes = new byte[b.getLength()];
+      System.arraycopy(b.getBuf(), b.getOffset(), bytes, 0, b.getLength());
+      return bytes;
+   }
+   
+   public ByteBuffer objectToBuffer(Object o) throws IOException {
+      ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream(128);
+      ObjectOutput marshaller = startObjectOutput(baos);
+      objectToObjectStream(o, marshaller);
+      finishObjectOutput(marshaller);
+      return new ByteBuffer(baos.getRawBuffer(), 0, baos.size());
+   }
+   
+   public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+      org.jboss.marshalling.Marshaller marshaller = factory.createMarshaller(configuration);
+      marshaller.start(Marshalling.createByteOutput(os));
+      return marshaller;
+   }
+   
+   public void finishObjectOutput(ObjectOutput oo) {
+      try {
+         ((org.jboss.marshalling.Marshaller) oo).finish();
+      } catch (IOException ioe) {
+      }
+   }
+
+   public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
+      ClassLoader toUse = defaultClassLoader;
+      Thread current = Thread.currentThread();
+      ClassLoader old = current.getContextClassLoader();
+      if (old != null) toUse = old;
+   
+      try {
+         current.setContextClassLoader(toUse);
+         out.writeObject(obj);
+      }
+      finally {
+         current.setContextClassLoader(old);
+      }
+   }
+   
+   public Object objectFromByteBuffer(byte[] buf) throws IOException, ClassNotFoundException {
+      return objectFromByteBuffer(buf, 0, buf.length);
+   }
+   
+   public Object objectFromByteBuffer(byte[] buf, int offset, int length) throws IOException,
+            ClassNotFoundException {
+      ByteArrayInputStream is = new ByteArrayInputStream(buf, offset, length);
+      ObjectInput unmarshaller = startObjectInput(is);
+      Object o = objectFromObjectStream(unmarshaller);
+      finishObjectInput(unmarshaller);
+      return o;
+   }
+   
+   public ObjectInput startObjectInput(InputStream is) throws IOException {
+      Unmarshaller unmarshaller = factory.createUnmarshaller(configuration);
+      unmarshaller.start(Marshalling.createByteInput(is));
+      return unmarshaller; 
+   }
+   
+   public void finishObjectInput(ObjectInput oi) {
+      try {
+         ((Unmarshaller) oi).finish();
+      } catch (IOException e) {
+      }
+   }
+
+   public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
+      return in.readObject();
+   }
+
+   public Object objectFromStream(InputStream is) throws IOException, ClassNotFoundException {
+      ObjectInput unmarshaller = startObjectInput(is);
+      Object o = objectFromObjectStream(unmarshaller);
+      finishObjectInput(unmarshaller);
+      return o;
+   }
+
+   protected MagicNumberClassTable createMagicNumberClassTable() {
+      MagicNumberClassTable classTable = new MagicNumberClassTable();
+      classTable.init();
+      return classTable;
+   }
+   
+   protected ExternalizerClassFactory createCustomExternalizerFactory(RpcManager rpcManager, CustomObjectTable objectTable) {
+      ExternalizerClassFactory externalizerFactory = new ExternalizerClassFactory(rpcManager, objectTable);
+      externalizerFactory.init();
+      return externalizerFactory;
+   }
+
+   private CustomObjectTable createCustomObjectTable() {
+      CustomObjectTable objectTable = new CustomObjectTable();
+      objectTable.init();
+      return objectTable;
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,61 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * JGroupsAddressExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class JGroupsAddressExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 2400716389425727329L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      JGroupsAddress address = (JGroupsAddress) subject;
+      address.writeExternal(output);
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            throws IOException, ClassNotFoundException {
+      return new JGroupsAddress();
+   }
+
+   public void readExternal(Object subject, ObjectInput input) throws IOException,
+            ClassNotFoundException {
+      JGroupsAddress address = (JGroupsAddress) subject;
+      address.readExternal(input);
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,65 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * LinkedListExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class LinkedListExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -3222803557498456230L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      MarshallUtil.marshallCollection((Collection) subject, output);
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            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 
+   }
+
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,132 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.ClassTable;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+
+/**
+ * MagicNumberClassTable.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MagicNumberClassTable implements ClassTable {
+   private static final Map<String, Integer> MAGIC_NUMBERS = new WeakHashMap<String, Integer>();
+   
+   static {
+      MAGIC_NUMBERS.put("org.infinispan.transaction.GlobalTransaction", 1);
+      MAGIC_NUMBERS.put("org.infinispan.remoting.transport.jgroups.JGroupsAddress", 2);
+      MAGIC_NUMBERS.put("java.util.ArrayList", 3);
+      MAGIC_NUMBERS.put("java.util.LinkedList", 8);
+      MAGIC_NUMBERS.put("java.util.HashMap", 9);
+      MAGIC_NUMBERS.put("java.util.TreeMap", 10);
+      MAGIC_NUMBERS.put("java.util.HashSet", 11);
+      MAGIC_NUMBERS.put("java.util.TreeSet", 12);
+      MAGIC_NUMBERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", 14);
+      MAGIC_NUMBERS.put("org.infinispan.marshall.MarshalledValue", 15);
+      MAGIC_NUMBERS.put("org.infinispan.util.FastCopyHashMap", 16);
+      MAGIC_NUMBERS.put("java.util.Collections$SingletonList", 23);
+      MAGIC_NUMBERS.put("org.infinispan.transaction.TransactionLog$LogEntry", 25);
+      MAGIC_NUMBERS.put("org.infinispan.remoting.transport.jgroups.ExtendedResponse", 28);
+      MAGIC_NUMBERS.put("org.infinispan.atomic.AtomicHashMap", 29);
+
+      MAGIC_NUMBERS.put("org.infinispan.commands.control.StateTransferControlCommand", 30);
+      MAGIC_NUMBERS.put("org.infinispan.commands.remote.ClusteredGetCommand", 31);
+      MAGIC_NUMBERS.put("org.infinispan.commands.remote.MultipleRpcCommand", 32);
+      MAGIC_NUMBERS.put("org.infinispan.commands.remote.SingleRpcCommand", 33);
+      MAGIC_NUMBERS.put("org.infinispan.commands.read.GetKeyValueCommand", 34);
+      MAGIC_NUMBERS.put("org.infinispan.commands.write.PutKeyValueCommand", 35);
+      MAGIC_NUMBERS.put("org.infinispan.commands.write.RemoveCommand", 36);
+      MAGIC_NUMBERS.put("org.infinispan.commands.write.InvalidateCommand", 38);
+      MAGIC_NUMBERS.put("org.infinispan.commands.write.ReplaceCommand", 39);
+      MAGIC_NUMBERS.put("org.infinispan.commands.write.ClearCommand", 40);
+      MAGIC_NUMBERS.put("org.infinispan.commands.write.PutMapCommand", 41);
+      MAGIC_NUMBERS.put("org.infinispan.commands.tx.PrepareCommand", 42);
+      MAGIC_NUMBERS.put("org.infinispan.commands.tx.CommitCommand", 43);
+      MAGIC_NUMBERS.put("org.infinispan.commands.tx.RollbackCommand", 44);
+
+      MAGIC_NUMBERS.put("org.infinispan.container.entries.ImmortalCacheEntry", 45);
+      MAGIC_NUMBERS.put("org.infinispan.container.entries.MortalCacheEntry", 46);
+      MAGIC_NUMBERS.put("org.infinispan.container.entries.TransientCacheEntry", 47);
+      MAGIC_NUMBERS.put("org.infinispan.container.entries.TransientMortalCacheEntry", 48);      
+   }
+      
+   private final Map<Class<?>, Writer> writers = new WeakHashMap<Class<?>, Writer>();
+   private final Map<Byte, Class<?>> classes = new HashMap<Byte, Class<?>>();
+   
+   public void init() {
+      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);         
+         }         
+      } catch (ClassNotFoundException e) {
+         throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
+      }
+   }
+   
+   public void stop() {
+      writers.clear();
+      classes.clear();
+   }
+
+   public Writer getClassWriter(Class<?> clazz) throws IOException {
+      return writers.get(clazz);
+   }
+
+   public Class<?> readClass(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
+      byte magicNumber = unmarshaller.readByte();
+      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);
+      }
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,66 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * Map externalizer for all map implementations except immutable maps and singleton maps, 
+ * i.e. FastCopyHashMap, HashMap, TreeMap.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MapExternalizer implements Externalizer {
+   
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -532896252671303391L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      MarshallUtil.marshallMap((Map) subject, output);
+   }
+   
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            throws IOException, ClassNotFoundException {
+      try {
+         return Util.getInstance(subjectType);        
+      } catch(Exception e) {
+         throw new CacheException("Unable to create new instance of ReplicableCommand", e);
+      }
+   }
+   
+   public void readExternal(Object subject, ObjectInput input) throws IOException,
+            ClassNotFoundException {
+      MarshallUtil.unmarshallMap((Map) subject, input);
+   }
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,120 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import net.jcip.annotations.Immutable;
+
+/**
+ * MarshallUtil.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MarshallUtil {
+
+   /**
+    * Writes an int in a variable-length format.  Writes between one and five bytes.  Smaller values take fewer bytes.
+    * Negative numbers are not supported.
+    *
+    * @param i int to write
+    */
+   protected static void writeUnsignedInt(ObjectOutput out, int i) throws IOException {
+      while ((i & ~0x7F) != 0) {
+         out.writeByte((byte) ((i & 0x7f) | 0x80));
+         i >>>= 7;
+      }
+      out.writeByte((byte) i);
+   }
+
+   /**
+    * Reads an int stored in variable-length format.  Reads between one and five bytes.  Smaller values take fewer
+    * bytes.  Negative numbers are not supported.
+    */
+   protected static int readUnsignedInt(ObjectInput in) throws IOException {
+      byte b = in.readByte();
+      int i = b & 0x7F;
+      for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+         b = in.readByte();
+         i |= (b & 0x7FL) << shift;
+      }
+      return i;
+   }
+   
+   protected static void marshallCollection(Collection c, ObjectOutput out) throws IOException {
+      writeUnsignedInt(out, c.size());
+      for (Object o : c) {
+         out.writeObject(o);
+      }
+   }
+   
+   protected static void marshallMap(Map map, ObjectOutput out) throws IOException {
+      int mapSize = map.size();
+      writeUnsignedInt(out, mapSize);
+      if (mapSize == 0) return;
+
+      for (Map.Entry me : (Set<Map.Entry>) map.entrySet()) {
+         out.writeObject(me.getKey());
+         out.writeObject(me.getValue());
+      }
+   }
+   
+   protected static void unmarshallMap(Map map, ObjectInput in) throws IOException, ClassNotFoundException{
+      int size = MarshallUtil.readUnsignedInt(in);
+      for (int i = 0; i < size; i++) map.put(in.readObject(), in.readObject());
+   }
+
+   /**
+    * Writes a long in a variable-length format.  Writes between one and nine bytes.  Smaller values take fewer bytes.
+    * Negative numbers are not supported.
+    *
+    * @param i int to write
+    */
+   protected static void writeUnsignedLong(ObjectOutput out, long i) throws IOException {
+      while ((i & ~0x7F) != 0) {
+         out.writeByte((byte) ((i & 0x7f) | 0x80));
+         i >>>= 7;
+      }
+      out.writeByte((byte) i);
+   }
+
+   /**
+    * Reads a long stored in variable-length format.  Reads between one and nine bytes.  Smaller values take fewer
+    * bytes.  Negative numbers are not supported.
+    */
+   protected static long readUnsignedLong(ObjectInput in) throws IOException {
+      byte b = in.readByte();
+      long i = b & 0x7F;
+      for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+         b = in.readByte();
+         i |= (b & 0x7FL) << shift;
+      }
+      return i;
+   }   
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -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;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.marshall.MarshalledValue;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * MarshalledValueExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MarshalledValueExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 8473423584918714661L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      ((MarshalledValue) subject).writeExternal(output);
+   }
+   
+   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) subject).readExternal(input);
+   }
+   
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,85 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * ReplicableCommandExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ReplicableCommandExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 6915200269446867084L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      ReplicableCommand command = (ReplicableCommand) subject;
+      output.writeShort(command.getCommandId());
+      Object[] args = command.getParameters();
+      byte numArgs = (byte) (args == null ? 0 : args.length);
+      output.writeByte(numArgs);
+      for (int i = 0; i < numArgs; i++) {
+         output.writeObject(args[i]);
+      }
+   }
+
+   /**
+    * 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;
+      short methodId = input.readShort();
+      byte numArgs = input.readByte();
+      Object[] args = null;
+      if (numArgs > 0) {
+         args = new Object[numArgs];
+         for (int i = 0; i < numArgs; i++) args[i] = input.readObject();
+      }
+      command.setParameters(methodId, args);
+   }
+}
\ No newline at end of file

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,68 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Set;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * Set externalizer for all set implementations, i.e. HashSet and TreeSet
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class SetExternalizer implements Externalizer {
+   
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -3147427397000304867L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      MarshallUtil.marshallCollection((Collection) subject, output);
+   }
+   
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            throws IOException, ClassNotFoundException {
+      try {
+         return Util.getInstance(subjectType);        
+      } catch(Exception e) {
+         throw new CacheException("Unable to create new instance of ReplicableCommand", e);
+      }
+   }
+   
+   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());
+   }
+}
\ No newline at end of file

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,61 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * SingletonListExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class SingletonListExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -714785461531351642L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      output.writeObject(((List) subject).get(0));
+   }
+   
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            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.
+   }
+
+}

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,61 @@
+/*
+ * 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 java.io.ObjectInput;
+
+import org.infinispan.commands.control.StateTransferControlCommand;
+import org.infinispan.remoting.RpcManager;
+import org.jboss.marshalling.Creator;
+
+/**
+ * StateTransferControlCommandExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class StateTransferControlCommandExternalizer extends ReplicableCommandExternalizer {
+   
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -3743458410265076691L;
+   
+   private RpcManager rpcManager;
+
+   public void init(RpcManager rpcManager) {
+      this.rpcManager = rpcManager;
+   }
+   
+   /**
+    * In this case, subjectType will contain the class name of the ReplicableCommand subclass to 
+    * create. 
+    * 
+    * 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 {
+      StateTransferControlCommand command = new StateTransferControlCommand();
+      command.init(rpcManager);
+      return command;
+   }
+}
\ No newline at end of file

Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,70 @@
+/*
+ * 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 java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.TransactionLog;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * TransactionLogExternalizer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class TransactionLogExternalizer implements Externalizer {
+
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -7341096933735222157L;
+
+   public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+      TransactionLog.LogEntry le = (TransactionLog.LogEntry) subject;
+      output.writeObject(le.getTransaction());
+      WriteCommand[] cmds = le.getModifications();
+      MarshallUtil.writeUnsignedInt(output, cmds.length);
+      for (WriteCommand c : cmds)
+         output.writeObject(c);
+   }
+
+   public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator) 
+            throws IOException, ClassNotFoundException {
+      GlobalTransaction gtx = (GlobalTransaction) input.readObject();
+      int numCommands = MarshallUtil.readUnsignedInt(input);
+      WriteCommand[] cmds = new WriteCommand[numCommands];
+      for (int i = 0; i < numCommands; i++) cmds[i] = (WriteCommand) input.readObject();
+      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/statetransfer/StateTransferManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -52,7 +52,9 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectInput;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.util.Arrays;
@@ -130,22 +132,22 @@
    }
 
    public void generateState(OutputStream out) throws StateTransferException {
-      ObjectOutputStream oos = null;
+      ObjectOutput oo = null;
       boolean txLogActivated = false;
       try {
          boolean canProvideState = (transientState || persistentState)
                && (txLogActivated = transactionLog.activate());
          if (log.isDebugEnabled()) log.debug("Generating state.  Can provide? {0}", canProvideState);
-         oos = new ObjectOutputStream(out);
-         marshaller.objectToObjectStream(canProvideState, oos);
+         oo = marshaller.startObjectOutput(out);
+         marshaller.objectToObjectStream(canProvideState, oo);
 
          if (canProvideState) {
-            delimit(oos);
-            if (transientState) generateInMemoryState(oos);
-            delimit(oos);
-            if (persistentState) generatePersistentState(oos);
-            delimit(oos);
-            generateTransactionLog(oos);
+            delimit(oo);
+            if (transientState) generateInMemoryState(oo);
+            delimit(oo);
+            if (persistentState) generatePersistentState(oo);
+            delimit(oo);
+            generateTransactionLog(oo);
 
             if (log.isDebugEnabled()) log.debug("State generated, closing object stream");
          } else {
@@ -157,12 +159,12 @@
       } catch (Exception e) {
          throw new StateTransferException(e);
       } finally {
-         Util.flushAndCloseStream(oos);
+         marshaller.finishObjectOutput(oo);
          if (txLogActivated) transactionLog.deactivate();
       }
    }
 
-   private void generateTransactionLog(ObjectOutputStream oos) throws Exception {
+   private void generateTransactionLog(ObjectOutput oo) throws Exception {
       // todo this should be configurable
       int maxNonProgressingLogWrites = 100;
       int flushTimeout = 60000;
@@ -173,7 +175,7 @@
          if (trace) log.trace("Transaction log size is {0}", transactionLog.size());
          for (int nonProgress = 0, size = transactionLog.size(); size > 0;) {
             if (trace) log.trace("Tx Log remaining entries = " + size);
-            transactionLog.writeCommitLog(marshaller, oos);
+            transactionLog.writeCommitLog(marshaller, oo);
             int newSize = transactionLog.size();
 
             // If size did not decrease then we did not make progress, and could be wasting
@@ -190,29 +192,29 @@
 
          // Signal to sender that we need a flush to get a consistent view
          // of the remaining transactions.
-         delimit(oos);
-         oos.flush();
+         delimit(oo);
+         oo.flush();
          if (trace) log.trace("Waiting for a distributed sync block");
          distributedSync.blockUntilAcquired(flushTimeout, MILLISECONDS);
 
          if (trace) log.trace("Distributed sync block received, proceeding with writing commit log");
          // Write remaining transactions
-         transactionLog.writeCommitLog(marshaller, oos);
-         delimit(oos);
+         transactionLog.writeCommitLog(marshaller, oo);
+         delimit(oo);
 
          // Write all non-completed prepares
-         transactionLog.writePendingPrepares(marshaller, oos);
-         delimit(oos);
-         oos.flush();
+         transactionLog.writePendingPrepares(marshaller, oo);
+         delimit(oo);
+         oo.flush();
       }
       finally {
          distributedSync.releaseProcessingLock();
       }
    }
 
-   private void processCommitLog(ObjectInputStream ois) throws Exception {
+   private void processCommitLog(ObjectInput oi) throws Exception {
       if (trace) log.trace("Applying commit log");
-      Object object = marshaller.objectFromObjectStream(ois);
+      Object object = marshaller.objectFromObjectStream(oi);
       while (object instanceof TransactionLog.LogEntry) {
          WriteCommand[] mods = ((TransactionLog.LogEntry) object).getModifications();
          if (trace) log.trace("Mods = {0}", Arrays.toString(mods));
@@ -224,17 +226,17 @@
             interceptorChain.invoke(ctx, mod);
          }
 
-         object = marshaller.objectFromObjectStream(ois);
+         object = marshaller.objectFromObjectStream(oi);
       }
 
       assertDelimited(object);
       if (trace) log.trace("Finished applying commit log");
    }
 
-   private void applyTransactionLog(ObjectInputStream ois) throws Exception {
+   private void applyTransactionLog(ObjectInput oi) throws Exception {
       if (trace) log.trace("Integrating transaction log");
 
-      processCommitLog(ois);
+      processCommitLog(oi);
       stateSender = rpcManager.getCurrentStateTransferSource();
       mimicPartialFlushViaRPC(stateSender, true);
       needToUnblockRPC = true;
@@ -242,11 +244,11 @@
       try {
          if (trace)
             log.trace("Retrieving/Applying post-flush commits");
-         processCommitLog(ois);
+         processCommitLog(oi);
 
          if (trace)
             log.trace("Retrieving/Applying pending prepares");
-         Object object = marshaller.objectFromObjectStream(ois);
+         Object object = marshaller.objectFromObjectStream(oi);
          while (object instanceof PrepareCommand) {
             PrepareCommand command = (PrepareCommand) object;
 
@@ -260,7 +262,7 @@
             } else {
                if (trace) log.trace("Prepare {0} not in tx log; not applying", command);
             }
-            object = marshaller.objectFromObjectStream(ois);
+            object = marshaller.objectFromObjectStream(oi);
          }
          assertDelimited(object);
       } catch (Exception e) {
@@ -288,17 +290,17 @@
 
    public void applyState(InputStream in) throws StateTransferException {
       if (log.isDebugEnabled()) log.debug("Applying state");
-      ObjectInputStream ois = null;
+      ObjectInput oi = null;
       try {
-         ois = new ObjectInputStream(in);
-         boolean canProvideState = (Boolean) marshaller.objectFromObjectStream(ois);
+         oi = marshaller.startObjectInput(in);
+         boolean canProvideState = (Boolean) marshaller.objectFromObjectStream(oi);
          if (canProvideState) {
-            assertDelimited(ois);
-            if (transientState) applyInMemoryState(ois);
-            assertDelimited(ois);
-            if (persistentState) applyPersistentState(ois);
-            assertDelimited(ois);
-            applyTransactionLog(ois);
+            assertDelimited(oi);
+            if (transientState) applyInMemoryState(oi);
+            assertDelimited(oi);
+            if (persistentState) applyPersistentState(oi);
+            assertDelimited(oi);
+            applyTransactionLog(oi);
             if (log.isDebugEnabled()) log.debug("State applied, closing object stream");
          } else {
             String msg = "Provider cannot provide state!";
@@ -311,11 +313,11 @@
          throw new StateTransferException(e);
       } finally {
          // just close the object stream but do NOT close the underlying stream
-         Util.closeStream(ois);
+         marshaller.finishObjectInput(oi);
       }
    }
 
-   private void applyInMemoryState(ObjectInputStream i) throws StateTransferException {
+   private void applyInMemoryState(ObjectInput i) throws StateTransferException {
       dataContainer.clear();
       try {
          Set<InternalCacheEntry> set = (Set<InternalCacheEntry>) marshaller.objectFromObjectStream(i);
@@ -327,7 +329,7 @@
       }
    }
 
-   private void generateInMemoryState(ObjectOutputStream o) throws StateTransferException {
+   private void generateInMemoryState(ObjectOutput oo) throws StateTransferException {
       // write all StoredEntries to the stream using the marshaller.
       // TODO is it safe enough to get these from the data container directly?
       try {
@@ -336,13 +338,13 @@
             if (!e.isExpired()) entries.add(e);
          }
          if (log.isDebugEnabled()) log.debug("Writing {0} StoredEntries to stream", entries.size());
-         marshaller.objectToObjectStream(entries, o);
+         marshaller.objectToObjectStream(entries, oo);
       } catch (Exception e) {
          throw new StateTransferException(e);
       }
    }
 
-   private void applyPersistentState(ObjectInputStream i) throws StateTransferException {
+   private void applyPersistentState(ObjectInput i) throws StateTransferException {
       try {
          // always use the unclosable stream delegate to ensure the impl doesn't close the stream
          cs.fromStream(new UnclosableObjectInputStream(i));
@@ -351,20 +353,20 @@
       }
    }
 
-   private void generatePersistentState(ObjectOutputStream o) throws StateTransferException {
+   private void generatePersistentState(ObjectOutput oo) throws StateTransferException {
       try {
          // always use the unclosable stream delegate to ensure the impl doesn't close the stream
-         cs.toStream(new UnclosableObjectOutputStream(o));
+         cs.toStream(new UnclosableObjectOutputStream(oo));
       } catch (CacheLoaderException cle) {
          throw new StateTransferException(cle);
       }
    }
 
-   private void delimit(ObjectOutputStream o) throws IOException {
-      marshaller.objectToObjectStream(DELIMITER, o);
+   private void delimit(ObjectOutput oo) throws IOException {
+      marshaller.objectToObjectStream(DELIMITER, oo);
    }
 
-   private void assertDelimited(ObjectInputStream i) throws StateTransferException {
+   private void assertDelimited(ObjectInput i) throws StateTransferException {
       Object o;
       try {
          o = marshaller.objectFromObjectStream(i);

Modified: trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -27,6 +27,7 @@
 import org.infinispan.logging.LogFactory;
 import org.infinispan.marshall.Marshaller;
 
+import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -128,7 +129,7 @@
       return entries.size();
    }
 
-   public void writeCommitLog(Marshaller marshaller, ObjectOutputStream out) throws Exception {
+   public void writeCommitLog(Marshaller marshaller, ObjectOutput out) throws Exception {
       List<LogEntry> buffer = new ArrayList<LogEntry>(10);
 
       while (entries.drainTo(buffer, 10) > 0) {
@@ -139,7 +140,7 @@
       }
    }
 
-   public void writePendingPrepares(Marshaller marshaller, ObjectOutputStream out) throws Exception {
+   public void writePendingPrepares(Marshaller marshaller, ObjectOutput out) throws Exception {
       if (log.isTraceEnabled()) log.trace("Writing {0} pending prepares to the stream", pendingPrepares.size());
       for (PrepareCommand entry : pendingPrepares.values()) marshaller.objectToObjectStream(entry, out);
    }

Modified: trunk/core/src/main/java/org/infinispan/util/Util.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/Util.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/util/Util.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -22,6 +22,8 @@
 package org.infinispan.util;
 
 import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.io.OutputStream;
 import java.lang.reflect.Method;
 import java.text.NumberFormat;
@@ -32,6 +34,7 @@
  * General utility methods used throughout the JBC code base.
  *
  * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @author Galder Zamarreño
  * @since 4.0
  */
 public final class Util {
@@ -165,6 +168,15 @@
       }
    }
 
+   public static void closeInput(ObjectInput i) {
+      if (i == null) return;
+      try {
+         i.close();
+      } catch (Exception e) {
+
+      }
+   }
+   
    public static void flushAndCloseStream(OutputStream o) {
       if (o == null) return;
       try {
@@ -179,4 +191,20 @@
 
       }
    }
+   
+   public static void flushAndCloseOutput(ObjectOutput o) {
+      if (o == null) return;
+      try {
+         o.flush();
+      } catch (Exception e) {
+
+      }
+
+      try {
+         o.close();
+      } catch (Exception e) {
+
+      }
+   }
+
 }

Modified: trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -1,6 +1,7 @@
 package org.infinispan.marshall;
 
 import org.infinispan.io.ByteBuffer;
+import org.infinispan.util.Util;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -10,6 +11,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
+import java.io.OutputStream;
 import java.io.Serializable;
 
 /**
@@ -18,6 +20,15 @@
  * @author Manik Surtani
  */
 public class ObjectStreamMarshaller implements Marshaller, Serializable {
+   
+   public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+      return new ObjectOutputStream(os);
+   }
+
+   public void finishObjectOutput(ObjectOutput oo) {
+      Util.flushAndCloseOutput(oo);
+   }
+   
    public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
       out.writeObject(obj);
    }
@@ -26,6 +37,14 @@
       return in.readObject();
    }
 
+   public ObjectInput startObjectInput(InputStream is) throws IOException {
+      return new ObjectInputStream(is);
+   }
+
+   public void finishObjectInput(ObjectInput oi) {
+      Util.closeInput(oi);
+   }
+
    public Object objectFromStream(InputStream is) throws IOException, ClassNotFoundException {
       if (is instanceof ObjectInputStream)
          return objectFromObjectStream((ObjectInputStream) is);
@@ -57,5 +76,4 @@
    public Object objectFromByteBuffer(byte[] buf) throws IOException, ClassNotFoundException {
       return objectFromObjectStream(new ObjectInputStream(new ByteArrayInputStream(buf)));
    }
-
 }

Added: trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,272 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.infinispan.commands.ReplicableCommand;
+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.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.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.InternalEntryFactory;
+import org.infinispan.container.entries.MortalCacheEntry;
+import org.infinispan.container.entries.TransientCacheEntry;
+import org.infinispan.container.entries.TransientMortalCacheEntry;
+import org.infinispan.marshall.MarshalledValue;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.jgroups.ExtendedResponse;
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.infinispan.remoting.transport.jgroups.RequestIgnoredResponse;
+import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.TransactionLog;
+import org.infinispan.util.FastCopyHashMap;
+import org.infinispan.util.Immutables;
+import org.jgroups.stack.IpAddress;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/**
+ * JBossMarshallingMarshallerTest.
+ * 
+ * Todo: AtomicHashMap missing.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Test(groups = "functional", testName = "marshall.jboss.JBossMarshallerTest")
+public class JBossMarshallerTest {
+
+   private final JBossMarshaller marshaller = new JBossMarshaller();
+   
+   @BeforeTest
+   public void setUp() {
+      marshaller.init(Thread.currentThread().getContextClassLoader(), null);
+   }
+   
+   @AfterTest
+   public void tearDown() {
+      marshaller.stop();
+   }
+   
+   public void testJGroupsAddressMarshalling() throws Exception {
+      JGroupsAddress address = new JGroupsAddress(new IpAddress(12345));
+      marshallAndAssertEquality(address);
+   }
+   
+   public void testGlobalTransactionMarshalling() throws Exception {
+      GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+      marshallAndAssertEquality(gtx);
+   }
+   
+   public void testListMarshalling() throws Exception {
+      List l1 = new ArrayList();
+      List l2 = new LinkedList();
+      for (int i = 0; i < 10; i++) {
+         GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+         l1.add(gtx);
+         l2.add(gtx);
+      }
+      marshallAndAssertEquality(l1);
+      marshallAndAssertEquality(l2);
+   }
+   
+   public void testMapMarshalling() throws Exception {
+      Map m1 = new HashMap();
+      Map m2 = new TreeMap();
+      Map m3 = new HashMap();
+      Map<Integer, GlobalTransaction> m4 = new FastCopyHashMap<Integer, GlobalTransaction>();
+      for (int i = 0; i < 10; i++) {
+         GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+         m1.put(1000 * i, gtx);
+         m2.put(1000 * i, gtx);
+         m4.put(1000 * i, gtx);
+      }
+      Map m5 = Immutables.immutableMapWrap(m3);
+      marshallAndAssertEquality(m1);
+      marshallAndAssertEquality(m2);
+      byte[] bytes = marshaller.objectToByteBuffer(m4);
+      Map<Integer, GlobalTransaction> m4Read = (Map<Integer, GlobalTransaction>) marshaller.objectFromByteBuffer(bytes);
+      for (Map.Entry<Integer, GlobalTransaction> entry : m4.entrySet()) {      
+         assert m4Read.get(entry.getKey()).equals(entry.getValue()) : "Writen[" + entry.getValue() + "] and read[" +  m4Read.get(entry.getKey()) +"] objects should be the same";
+      }
+      
+      marshallAndAssertEquality(m5);
+   }
+   
+   public void testSetMarshalling() throws Exception {
+      Set s1 = new HashSet();
+      Set s2 = new TreeSet();
+      for (int i = 0; i < 10; i++) {
+         Integer integ = new Integer(1000 * i);
+         s1.add(integ);
+         s2.add(integ);
+      }
+      marshallAndAssertEquality(s1);
+      marshallAndAssertEquality(s2);
+   }
+   
+   public void testMarshalledValueMarshalling() throws Exception {
+      GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+      MarshalledValue mv = new MarshalledValue(gtx, true);
+      marshallAndAssertEquality(mv);
+   }
+
+   public void testSingletonListMarshalling() throws Exception {
+      GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+      List l = Collections.singletonList(gtx);
+      marshallAndAssertEquality(l);
+   }
+   
+   public void testTransactionLogMarshalling() throws Exception {
+      GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+      PutKeyValueCommand command = new PutKeyValueCommand("k", "v", false, null, 0, 0);
+      TransactionLog.LogEntry entry = new TransactionLog.LogEntry(gtx, command);
+      byte[] bytes = marshaller.objectToByteBuffer(entry);
+      TransactionLog.LogEntry readObj = (TransactionLog.LogEntry) marshaller.objectFromByteBuffer(bytes);
+      assert Arrays.equals(readObj.getModifications(), entry.getModifications()) : 
+         "Writen[" + entry.getModifications() + "] and read[" +  readObj.getModifications() +"] objects should be the same";
+      assert readObj.getTransaction().equals(entry.getTransaction()) : 
+         "Writen[" + entry.getModifications() + "] and read[" +  readObj.getModifications() +"] objects should be the same";
+   }
+   
+   public void testRequestIgnoredResponseMarshalling() throws Exception {
+      marshallAndAssertEquality(RequestIgnoredResponse.INSTANCE);
+   }
+   
+   public void testExtendedResponseMarshalling() throws Exception {
+      PutKeyValueCommand command = new PutKeyValueCommand("k", "v", false, null, 0, 0);
+      ExtendedResponse extended = new ExtendedResponse(command, false);
+      byte[] bytes = marshaller.objectToByteBuffer(extended);
+      ExtendedResponse readObj = (ExtendedResponse) marshaller.objectFromByteBuffer(bytes);
+      assert extended.getResponse().equals(readObj.getResponse()) :
+         "Writen[" + extended.getResponse() + "] and read[" +  readObj.getResponse() +"] objects should be the same";
+      assert extended.isReplayIgnoredRequests() == readObj.isReplayIgnoredRequests() :
+         "Writen[" + extended.isReplayIgnoredRequests() + "] and read[" +  readObj.isReplayIgnoredRequests() +"] objects should be the same";
+   }
+   
+   public void testReplicableCommandsMarshalling() throws Exception {
+      StateTransferControlCommand c1 = new StateTransferControlCommand(true);
+      byte[] bytes = marshaller.objectToByteBuffer(c1);
+      StateTransferControlCommand rc1 = (StateTransferControlCommand)marshaller.objectFromByteBuffer(bytes);
+      assert rc1.getCommandId() == c1.getCommandId() : "Writen[" + c1.getCommandId() + "] and read[" +  rc1.getCommandId() +"] objects should be the same";
+      assert Arrays.equals(rc1.getParameters(), c1.getParameters()) : "Writen[" + c1.getParameters() + "] and read[" +  rc1.getParameters() +"] objects should be the same";
+      
+      ClusteredGetCommand c2 = new ClusteredGetCommand("key", "mycache");
+      marshallAndAssertEquality(c2);
+      
+      // SizeCommand does not have an empty constructor, so doesn't look to be one that is marshallable.      
+      
+      GetKeyValueCommand c4 = new GetKeyValueCommand("key", null);
+      bytes = marshaller.objectToByteBuffer(c4);
+      GetKeyValueCommand rc4 = (GetKeyValueCommand)marshaller.objectFromByteBuffer(bytes);
+      assert rc4.getCommandId() == c4.getCommandId() : "Writen[" + c4.getCommandId() + "] and read[" +  rc4.getCommandId() +"] objects should be the same";
+      assert Arrays.equals(rc4.getParameters(), c4.getParameters()) : "Writen[" + c4.getParameters() + "] and read[" +  rc4.getParameters() +"] objects should be the same";
+      
+      PutKeyValueCommand c5 = new PutKeyValueCommand("k", "v", false, null, 0, 0);
+      marshallAndAssertEquality(c5);
+      
+      RemoveCommand c6 = new RemoveCommand("key", null, null);
+      marshallAndAssertEquality(c6);
+      
+      // EvictCommand does not have an empty constructor, so doesn't look to be one that is marshallable.
+      
+      InvalidateCommand c7 = new InvalidateCommand(null, "key1", "key2");
+      bytes = marshaller.objectToByteBuffer(c7);
+      InvalidateCommand rc7 = (InvalidateCommand)marshaller.objectFromByteBuffer(bytes);
+      assert rc7.getCommandId() == c7.getCommandId() : "Writen[" + c7.getCommandId() + "] and read[" +  rc7.getCommandId() +"] objects should be the same";
+      assert Arrays.equals(rc7.getParameters(), c7.getParameters()) : "Writen[" + c7.getParameters() + "] and read[" +  rc7.getParameters() +"] objects should be the same";
+      
+      ReplaceCommand c8 = new ReplaceCommand("key", "oldvalue", "newvalue", 0, 0);
+      marshallAndAssertEquality(c8);
+      
+      ClearCommand c9 = new ClearCommand();
+      bytes = marshaller.objectToByteBuffer(c9);
+      ClearCommand rc9 = (ClearCommand)marshaller.objectFromByteBuffer(bytes);
+      assert rc9.getCommandId() == c9.getCommandId() : "Writen[" + c9.getCommandId() + "] and read[" +  rc9.getCommandId() +"] objects should be the same";
+      assert Arrays.equals(rc9.getParameters(), c9.getParameters()) : "Writen[" + c9.getParameters() + "] and read[" +  rc9.getParameters() +"] objects should be the same";
+
+      Map m1 = new HashMap();
+      for (int i = 0; i < 10; i++) {
+         GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+         m1.put(1000 * i, gtx);
+      }
+      PutMapCommand c10 = new PutMapCommand(m1, null, 0, 0);
+      marshallAndAssertEquality(c10);
+      
+      Address local = new JGroupsAddress(new IpAddress(12345));
+      GlobalTransaction gtx = GlobalTransaction.create(local);
+      PrepareCommand c11 = new PrepareCommand(gtx, local, true, c5, c6, c8, c10);
+      marshallAndAssertEquality(c11);
+      
+      CommitCommand c12 = new CommitCommand(gtx);
+      marshallAndAssertEquality(c12);
+      
+      RollbackCommand c13 = new RollbackCommand(gtx);
+      marshallAndAssertEquality(c13);
+      
+      MultipleRpcCommand c99 = new MultipleRpcCommand(Arrays.asList(new ReplicableCommand[] {c2, c5, c6, c8, c10, c12, c13}), "mycache");
+      marshallAndAssertEquality(c99);
+   }
+   
+   public void testInternalCacheEntryMarshalling() throws Exception {
+      ImmortalCacheEntry entry1 = (ImmortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), -1);
+      marshallAndAssertEquality(entry1);
+      
+      MortalCacheEntry entry2 =  (MortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), -1);
+      marshallAndAssertEquality(entry2);
+      
+      TransientCacheEntry entry3 = (TransientCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), 4000000);
+      marshallAndAssertEquality(entry3);
+      
+      TransientMortalCacheEntry entry4 = (TransientMortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
+      marshallAndAssertEquality(entry4);      
+   }
+   
+   protected void marshallAndAssertEquality(Object writeObj) throws Exception {
+      byte[] bytes = marshaller.objectToByteBuffer(writeObj);
+      Object readObj = marshaller.objectFromByteBuffer(bytes);
+      assert readObj.equals(writeObj) : "Writen[" + writeObj + "] and read[" +  readObj +"] objects should be the same";
+   }
+   
+}

Modified: trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -5,6 +5,7 @@
 import org.infinispan.manager.CacheManager;
 import org.infinispan.manager.DefaultCacheManager;
 import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
+import org.infinispan.util.Util;
 
 import java.util.Properties;
 
@@ -12,14 +13,18 @@
  * CacheManagers in unit tests should be created with this factory, in order to avoit resource clashes.
  *
  * @author Mircea.Markus at jboss.com
+ * @author Galder Zamarreño
  */
 public class TestCacheManagerFactory {
+   
+   public static final String MARSHALLER = System.getProperties().getProperty("infinispan.marshaller.class");
 
    /**
     * Creates an cache manager that does not support clustering.
     */
    public static CacheManager createLocalCacheManager() {
       GlobalConfiguration globalConfiguration = GlobalConfiguration.getNonClusteredDefault();
+      amendMarshaller(globalConfiguration);
 //      amendJmx(globalConfiguration);
       return new DefaultCacheManager(globalConfiguration);
    }
@@ -29,6 +34,7 @@
     */
    public static CacheManager createClusteredCacheManager() {
       GlobalConfiguration globalConfiguration = GlobalConfiguration.getClusteredDefault();
+      amendMarshaller(globalConfiguration);
 //      amendJmx(globalConfiguration);
       Properties newTransportProps = new Properties();
       newTransportProps.put(JGroupsTransport.CONFIGURATION_STRING, JGroupsConfigBuilder.getJGroupsConfig());
@@ -41,6 +47,7 @@
     * during running tests in parallel.
     */
    public static CacheManager createCacheManager(GlobalConfiguration configuration) {
+      amendMarshaller(configuration);
       amendTransport(configuration);
 //      amendJmx(configuration);
       return new DefaultCacheManager(configuration);
@@ -52,11 +59,13 @@
     */
    public static CacheManager createCacheManager(Configuration defaultCacheConfig) {
       GlobalConfiguration globalConfiguration = GlobalConfiguration.getNonClusteredDefault();
+      amendMarshaller(globalConfiguration);
 //      amendJmx(globalConfiguration);
       return new DefaultCacheManager(globalConfiguration, defaultCacheConfig);
    }
 
    public static DefaultCacheManager createCacheManager(GlobalConfiguration configuration, Configuration defaultCfg) {
+      amendMarshaller(configuration);
       amendTransport(configuration);
 //      amendJmx(configuration);
       return new DefaultCacheManager(configuration, defaultCfg);
@@ -74,4 +83,15 @@
          configuration.setTransportProperties(newTransportProps);
       }
    }
+   
+   private static void amendMarshaller(GlobalConfiguration configuration) {
+      if (MARSHALLER != null) {
+         try {
+            Util.loadClass(MARSHALLER);
+            configuration.setMarshallerClass(MARSHALLER);
+         } catch (ClassNotFoundException e) {
+            // No-op, stick to GlobalConfiguration default.
+         }
+      }
+   }
 }

Modified: trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java	2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java	2009-04-14 18:09:18 UTC (rev 113)
@@ -13,6 +13,7 @@
  * This class makes sure that all files are being deleted after each test run. It also logs testsuite information.
  *
  * @author Mircea.Markus at jboss.com
+ * @author Galder Zamarreño
  */
 @Test(groups = "functional", testName = "test.testng.SuiteResourcesAndLogTest")
 public class SuiteResourcesAndLogTest {
@@ -53,6 +54,7 @@
       log("sun.arch.data.model = " + System.getProperty("sun.arch.data.model"));
       log("sun.cpu.endian = " + System.getProperty("sun.cpu.endian"));
       log("jgroups.stack = " + System.getProperty("jgroups.stack"));
+      log("infinispan.marshaller.class = " + System.getProperty("infinispan.marshaller.class"));
       log("~~~~~~~~~~~~~~~~~~~~~~~~~ ENVIRONMENT INFO ~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }
 




More information about the infinispan-commits mailing list