You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by mm...@apache.org on 2020/12/03 23:33:22 UTC

[geode-native] branch develop updated: GEODE-8754: Fix uninitialized variable in DataInput::ReadInternalObject (#704)

This is an automated email from the ASF dual-hosted git repository.

mmartell pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-native.git


The following commit(s) were added to refs/heads/develop by this push:
     new 03f6031  GEODE-8754: Fix uninitialized variable in DataInput::ReadInternalObject (#704)
03f6031 is described below

commit 03f6031cbf9aa2dde46216cfebbaa8a4b46d4182
Author: Michael Martell <mm...@pivotal.io>
AuthorDate: Thu Dec 3 15:33:12 2020 -0800

    GEODE-8754: Fix uninitialized variable in DataInput::ReadInternalObject (#704)
    
    * Initialize compId in DataInput::ReadInternalObject
    * Add new test for ReadInternalObject: CompositeClassWithClassAsKey
    * Add java classes to support new cli tests and update instantiators for new classes
    * Add ClassAsKey test
---
 clicache/integration-test2/CMakeLists.txt          |   1 +
 clicache/integration-test2/PositionKey.cs          | 100 +++++
 clicache/integration-test2/SerializationTests.cs   | 482 ++++++++++++++++++++-
 clicache/src/DataInput.cpp                         |   2 +-
 tests/javaobject/cli/CompositeClass.java           | 109 +++++
 .../cli/InstantiateDataSerializable.java           |  31 ++
 tests/javaobject/cli/PositionKey.java              |  77 ++++
 tests/javaobject/cli/TestClassA.java               |  93 ++++
 tests/javaobject/cli/TestClassB.java               |  93 ++++
 tests/javaobject/cli/TestClassC.java               |  94 ++++
 10 files changed, 1078 insertions(+), 4 deletions(-)

diff --git a/clicache/integration-test2/CMakeLists.txt b/clicache/integration-test2/CMakeLists.txt
index f355472..725ebde 100644
--- a/clicache/integration-test2/CMakeLists.txt
+++ b/clicache/integration-test2/CMakeLists.txt
@@ -42,6 +42,7 @@ add_library( ${PROJECT_NAME} SHARED
   RegionTest.cs
   RegionSSLTest.cs
   Position.cs
+  PositionKey.cs
   TestBase.cs
   cache.xml
   geode.properties
diff --git a/clicache/integration-test2/PositionKey.cs b/clicache/integration-test2/PositionKey.cs
new file mode 100644
index 0000000..02c6163
--- /dev/null
+++ b/clicache/integration-test2/PositionKey.cs
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Apache.Geode.Client.IntegrationTests
+{
+  using Apache.Geode.Client;
+  public class PositionKey : ICacheableKey, IDataSerializable
+  {
+    private long m_positionId;
+
+	public PositionKey() { }
+	public PositionKey(long positionId)
+	{
+		m_positionId = positionId;
+	}
+	public long PositionId
+	{
+		get
+		{
+			return m_positionId;
+		}
+		set
+		{
+			m_positionId = value;
+		}
+	}
+
+	public void FromData(DataInput input)
+	{
+		m_positionId = input.ReadInt64();
+	}
+
+	public void ToData(DataOutput output)
+    {
+      output.WriteInt64(m_positionId);
+    }
+
+    public UInt64 ObjectSize
+    {
+      get
+      {
+		return 8;
+	  }
+    }
+
+	public static IDataSerializable CreateDeserializable()
+	{
+		return new PositionKey();
+	}
+
+	public static int GetClassID()
+	{
+		return 77;
+	}
+
+	public bool Equals(ICacheableKey other)
+	{
+	  return Equals((Object)other);
+	}
+
+	public override bool Equals(object obj)
+	{
+		if (this == obj)
+		{
+			return true;
+		}
+
+		if (GetType() != obj.GetType())
+		{
+			return false;
+		}
+
+		PositionKey otherKey = (PositionKey)obj;
+		return (m_positionId == otherKey.m_positionId);
+	}
+
+	public override int GetHashCode()
+	{
+	  int hash = 11;
+	  hash = 31 * hash + (int)m_positionId;
+	  return hash;
+	}
+  }
+}
diff --git a/clicache/integration-test2/SerializationTests.cs b/clicache/integration-test2/SerializationTests.cs
index 47dd405..bce822d 100644
--- a/clicache/integration-test2/SerializationTests.cs
+++ b/clicache/integration-test2/SerializationTests.cs
@@ -17,6 +17,7 @@
 
 using System;
 using System.IO;
+using System.Linq;
 using Xunit;
 using PdxTests;
 using System.Collections;
@@ -25,7 +26,305 @@ using Xunit.Abstractions;
 
 namespace Apache.Geode.Client.IntegrationTests
 {
-    public class Order : IDataSerializable
+	public class TestClassA : IDataSerializable
+	{
+		public int Id { get; set; }
+		public string Name { get; set; }
+		public short NumSides { get; set; }
+
+		// A default constructor is required for deserialization
+		public TestClassA() { }
+
+		public TestClassA(int id, string name, short numSides)
+		{
+			Id = id;
+			Name = name;
+			NumSides = numSides;
+		}
+
+		public override string ToString()
+		{
+			return string.Format("TestClassA: [{0}, {1}, {2}]", Id, Name, NumSides);
+		}
+
+		public void ToData(DataOutput output)
+		{
+			output.WriteInt32(Id);
+			output.WriteUTF(Name);
+			output.WriteInt16(NumSides);
+		}
+
+		public void FromData(DataInput input)
+		{
+			Id = input.ReadInt32();
+			Name = input.ReadUTF();
+			NumSides = input.ReadInt16();
+		}
+
+		public ulong ObjectSize
+		{
+			get { return 0; }
+		}
+
+		public static ISerializable CreateDeserializable()
+		{
+			return new TestClassA();
+		}
+
+		public override bool Equals(object obj)
+		{
+            TestClassA other = (TestClassA)obj;
+
+            if (other != null) {
+			    if (Id == other.Id &&
+				    Name == other.Name &&
+				    NumSides == other.NumSides)
+				    return true;
+                else
+                    return false;
+            }
+			else
+				return false;
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+	}
+
+	public class TestClassB : IDataSerializable
+	{
+		public int Width { get; set; }
+		public int Height { get; set; }
+		public string Name { get; set; }
+
+		// A default constructor is required for deserialization
+		public TestClassB() { }
+
+		public TestClassB(int width, int height, string name)
+		{
+			Width = width;
+			Height = height;
+			Name = name;
+		}
+
+		public override string ToString()
+		{
+			return string.Format("TestClassB: [{0}, {1}, {2}]", Width, Height, Name);
+		}
+
+		public void ToData(DataOutput output)
+		{
+			output.WriteInt32(Width);
+			output.WriteInt32(Height);
+			output.WriteUTF(Name);
+		}
+
+		public void FromData(DataInput input)
+		{
+			Width = input.ReadInt32();
+			Height = input.ReadInt32();
+			Name = input.ReadUTF();
+		}
+
+		public ulong ObjectSize
+		{
+			get { return 0; }
+		}
+
+		public static ISerializable CreateDeserializable()
+		{
+			return new TestClassB();
+		}
+
+		public override bool Equals(object obj)
+		{
+			var other = (TestClassB)obj;
+
+            if (other != null) {
+			    if (Width == other.Width &&
+				    Name == other.Name &&
+				    Height == other.Height)
+				    return true;
+                else
+                    return false;
+            }
+			else
+				return false;
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+	}
+
+	public class TestClassC : IDataSerializable
+	{
+		public string Color { get; set; }
+		public string Make { get; set; }
+		public int Year { get; set; }
+
+		// A default constructor is required for deserialization
+		public TestClassC() { }
+
+		public TestClassC(string color, string make, int year)
+		{
+			Color = color;
+			Make = make;
+			Year = year;
+		}
+
+		public override string ToString()
+		{
+			return string.Format("TestClassC: [{0}, {1}, {2}]", Color, Make, Year);
+		}
+
+		public void ToData(DataOutput output)
+		{
+			output.WriteUTF(Color);
+			output.WriteUTF(Make);
+			output.WriteInt32(Year);
+		}
+
+		public void FromData(DataInput input)
+		{
+			Color = input.ReadUTF();
+			Make = input.ReadUTF();
+			Year = input.ReadInt32();
+		}
+
+		public ulong ObjectSize
+		{
+			get { return 0; }
+		}
+
+		public static ISerializable CreateDeserializable()
+		{
+			return new TestClassC();
+		}
+
+		public override bool Equals(object obj)
+		{
+			var other = (TestClassC)obj;
+
+			if (Color == other.Color &&
+				Make == other.Make &&
+				Year == other.Year)
+				return true;
+			else
+				return false;
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+	}
+
+	public class CompositeClass : IDataSerializable
+    {
+        private TestClassA testclassA;
+		private List<TestClassB> testclassBs;
+		private List<TestClassC> testclassCs;
+
+		public CompositeClass()
+		{
+			testclassA = new TestClassA();
+			testclassBs = new List<TestClassB>();
+			testclassCs = new List<TestClassC>();
+		}
+
+		public TestClassA A
+		{
+			get
+			{
+				return testclassA;
+			}
+			set
+			{
+				testclassA = value;
+			}
+		}
+
+		public List<TestClassB> Bs
+		{
+			get
+			{
+				return testclassBs;
+			}
+			set
+			{
+				testclassBs = value;
+			}
+		}
+
+		public List<TestClassC> Cs
+		{
+			get
+			{
+				return testclassCs;
+			}
+			set
+			{
+				testclassCs = value;
+			}
+		}
+
+		public void ToData(DataOutput output)
+		{
+			testclassA.ToData(output);
+			output.WriteObject(testclassBs);
+			output.WriteObject(testclassCs);
+		}
+
+		public void FromData(DataInput input)
+		{
+			testclassA.FromData(input);
+
+			List<object> bs = (List<object>)input.ReadObject();
+			foreach (var obj in bs)
+			{
+				Bs.Add(obj as TestClassB);
+			}
+				
+			List<object> cs = (List<object>)input.ReadObject();
+			foreach (var obj in cs)
+			{
+				Cs.Add(obj as TestClassC);
+			}
+		}
+
+		public ulong ObjectSize
+		{
+			get { return 0; }
+		}
+
+		public static ISerializable CreateDeserializable()
+		{
+			return new CompositeClass();
+		}
+
+		public override bool Equals(object obj)
+		{
+			var other = (CompositeClass)obj;
+
+			if (testclassA.Equals(other.testclassA)
+				&& testclassBs.Equals(other.testclassBs)
+				&& testclassCs.Equals(other.testclassCs))
+				return true;
+			else
+				return false;
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+    }
+
+	public class Order : IDataSerializable
     {
         public int OrderId { get; set; }
         public string Name { get; set; }
@@ -140,6 +439,7 @@ namespace Apache.Geode.Client.IntegrationTests
             return m_first.GetHashCode() ^ m_second.GetHashCode();
         }
     };
+
     public class OtherType : IDataSerializable
     {
         private CData m_struct;
@@ -401,6 +701,7 @@ namespace Apache.Geode.Client.IntegrationTests
     public class SerializationTests : TestBase
     {
         public SerializationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
+
         {
         }
 
@@ -510,5 +811,180 @@ namespace Apache.Geode.Client.IntegrationTests
                 cache.Close();
             }
         }
-    }
-}
+
+        [Fact]
+        public void ClassAsKey()
+        {
+            using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1))
+            {
+                Assert.Equal(cluster.Start(), true);
+                Assert.Equal(0, cluster.Gfsh.deploy()
+                    .withJar(Config.JavaobjectJarPath)
+                    .execute());
+
+                Assert.Equal(0, cluster.Gfsh.create()
+                    .region()
+                    .withName("testRegion")
+                    .withType("REPLICATE")
+                    .execute());
+
+                Assert.Equal(0, cluster.Gfsh.executeFunction()
+                    .withId("InstantiateDataSerializable")
+                    .withMember("ClassAsKey_server_0")
+                    .execute());
+
+                var cache = cluster.CreateCache();
+
+                cache.TypeRegistry.RegisterType(PositionKey.CreateDeserializable, 77);
+                cache.TypeRegistry.RegisterType(Position.CreateDeserializable, 22);
+
+                var region = cache.CreateRegionFactory(RegionShortcut.PROXY)
+                  .SetPoolName("default")
+                  .Create<PositionKey, Position>("testRegion");
+                Assert.NotNull(region);
+
+                var key1 = new PositionKey(1000);
+                var key2 = new PositionKey(1000000);
+                var key3 = new PositionKey(1000000000);
+
+                var pos1 = new Position("GOOG", 23);
+                var pos2 = new Position("IBM", 37);
+                var pos3 = new Position("PVTL", 101);
+
+                region.Put(key1, pos1);
+                region.Put(key2, pos2);
+                region.Put(key3, pos3);
+
+                var res1 = region.Get(key1);
+                var res2 = region.Get(key2);
+                var res3 = region.Get(key3);
+
+                Assert.True(
+                    res1.SecId == pos1.SecId &&
+                    res1.SharesOutstanding == pos1.SharesOutstanding);
+                Assert.True(
+                    res2.SecId == pos2.SecId &&
+                    res2.SharesOutstanding == pos2.SharesOutstanding);
+                Assert.True(
+                    res3.SecId == pos3.SecId &&
+                    res3.SharesOutstanding == pos3.SharesOutstanding);
+
+                cache.Close();
+            }
+        }
+
+        [Fact]
+		public void CompositeClassWithClassAsKey()
+		{
+			using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1))
+			{
+				Assert.Equal(cluster.Start(), true);
+				Assert.Equal(0, cluster.Gfsh.deploy()
+					.withJar(Config.JavaobjectJarPath)
+					.execute());
+
+				Assert.Equal(0, cluster.Gfsh.create()
+					.region()
+					.withName("testRegion")
+					.withType("REPLICATE")
+					.execute());
+
+				Assert.Equal(0, cluster.Gfsh.executeFunction()
+					.withId("InstantiateDataSerializable")
+					.withMember("CompositeClassWithClassAsKey_server_0")
+					.execute());
+
+				var cache = cluster.CreateCache();
+
+				cache.TypeRegistry.RegisterType(PositionKey.CreateDeserializable, 77);
+				cache.TypeRegistry.RegisterType(TestClassA.CreateDeserializable, 100);
+				cache.TypeRegistry.RegisterType(TestClassB.CreateDeserializable, 101);
+				cache.TypeRegistry.RegisterType(TestClassC.CreateDeserializable, 102);
+				cache.TypeRegistry.RegisterType(CompositeClass.CreateDeserializable, 125);
+
+				var region = cache.CreateRegionFactory(RegionShortcut.PROXY)
+				  .SetPoolName("default")
+				  .Create<PositionKey, CompositeClass>("testRegion");
+				Assert.NotNull(region);
+
+				var key1 = new PositionKey(23);
+				var key2 = new PositionKey(37);
+				var key3 = new PositionKey(38);
+
+                ICollection<PositionKey> keys = new List<PositionKey>();
+				keys.Add(key1);
+				keys.Add(key2);
+				keys.Add(key3);
+
+                // First CompositeClass
+
+                var cc1 = new CompositeClass();
+
+				cc1.A = new TestClassA(1, "Square", 4);
+
+				cc1.Bs = new List<TestClassB>() {
+					new TestClassB(10, 20, "Brick"),
+					new TestClassB(11, 21, "Block"),
+					new TestClassB(100, 200, "Stone")};
+
+				cc1.Cs = new List<TestClassC>() {
+					new TestClassC("Red", "Volvo", 2010),
+					new TestClassC("White", "Toyota", 2011),
+					new TestClassC("Blue", "Nissan", 2012)};
+
+                // Second CompositeClass
+
+                var cc2 = new CompositeClass();
+
+				cc2.A = new TestClassA(1, "Triangle", 3);
+
+				cc2.Bs = new List<TestClassB>() {
+					new TestClassB(100, 200, "BiggerBrick"),
+					new TestClassB(110, 210, "BiggerBlock"),
+					new TestClassB(1000, 2000, "BiggerStone")};
+
+				cc2.Cs = new List<TestClassC>() {
+				new TestClassC("Gray", "Volvo", 2010),
+				new TestClassC("Silver", "Toyota", 2011),
+				new TestClassC("Black", "Nissan", 2012)};
+
+                // Third CompositeClass
+
+                var cc3 = new CompositeClass();
+
+                cc3.A = new TestClassA(1, "Hexagon", 6);
+
+                cc3.Bs = new List<TestClassB>() {
+                new TestClassB(1000, 2000, "BiggestBrick"),
+                new TestClassB(1100, 2100, "BiggestBlock"),
+                new TestClassB(10000, 20000, "BiggestStone")};
+
+                cc3.Cs = new List<TestClassC>() {
+                new TestClassC("Orange", "Volvo", 2010),
+                new TestClassC("Yellow", "Toyota", 2011),
+                new TestClassC("Purple", "Nissan", 2012)};
+
+                region.Put(key1, cc1);
+				region.Put(key2, cc2);
+				region.Put(key3, cc3);
+
+                Dictionary<PositionKey, CompositeClass> ccs = new Dictionary<PositionKey, CompositeClass>();
+				Dictionary<PositionKey, Exception> exceptions = new Dictionary<PositionKey, Exception>();
+
+				region.GetAll(keys, ccs, exceptions, false);
+
+				Assert.True(cc1.A.Equals(ccs[key1].A) &&
+							Enumerable.SequenceEqual(cc1.Bs, ccs[key1].Bs) &&
+							Enumerable.SequenceEqual(cc1.Cs, ccs[key1].Cs));
+				Assert.True(cc2.A.Equals(ccs[key2].A) &&
+							Enumerable.SequenceEqual(cc2.Bs, ccs[key2].Bs) &&
+							Enumerable.SequenceEqual(cc2.Cs, ccs[key2].Cs));
+                Assert.True(cc3.A.Equals(ccs[key3].A) &&
+                            Enumerable.SequenceEqual(cc3.Bs, ccs[key3].Bs) &&
+                            Enumerable.SequenceEqual(cc3.Cs, ccs[key3].Cs));
+
+                cache.Close();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/clicache/src/DataInput.cpp b/clicache/src/DataInput.cpp
index ef06cd4..e307293 100644
--- a/clicache/src/DataInput.cpp
+++ b/clicache/src/DataInput.cpp
@@ -657,7 +657,7 @@ namespace Apache
           //Log::Debug("DataInput::ReadInternalObject m_cursor " + m_cursor);
           bool findinternal = false;
           int8_t typeId = ReadByte();
-          System::Int64 compId;
+          System::Int64 compId = 0;
           TypeFactoryMethod^ createType = nullptr;
 
           switch (static_cast<DSCode>(typeId)) 
diff --git a/tests/javaobject/cli/CompositeClass.java b/tests/javaobject/cli/CompositeClass.java
new file mode 100644
index 0000000..2979c4e
--- /dev/null
+++ b/tests/javaobject/cli/CompositeClass.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javaobject.cli;
+
+import java.util.*;
+import java.io.*;
+import org.apache.geode.*;
+import org.apache.geode.cache.Declarable;
+
+public class CompositeClass implements Declarable, Serializable, DataSerializable {
+  private TestClassA testclassA;
+  private List<TestClassB> testclassBs;
+  private List<TestClassC> testclassCs;
+
+  static {
+     Instantiator.register(new Instantiator(javaobject.cli.CompositeClass.class, (byte) 125) {
+     public DataSerializable newInstance() {
+        return new CompositeClass();
+     }
+   });
+  }
+
+  /* public no-arg constructor required for DataSerializable */  
+  public CompositeClass() {
+	
+  }
+  
+  public TestClassA getA() {
+	return testclassA;
+  }
+
+  public void setA(TestClassA a) {
+	this.testclassA = a;
+  }
+
+  public List<TestClassB> getBs() {
+	return testclassBs;
+  }
+
+  public void setBs(List<TestClassB> bs) {
+	this.testclassBs = bs;
+  }
+
+  public List<TestClassC> getCs() {
+	return testclassCs;
+  }
+
+  public void setCs(List<TestClassC> cs) {
+	this.testclassCs = cs;
+  }
+
+  @Override
+  public void fromData(DataInput input) throws IOException, ClassNotFoundException {
+    setA((TestClassA) DataSerializer.readObject(input));
+    setBs((List<TestClassB>) DataSerializer.readObject(input));
+    setCs((List<TestClassC>) DataSerializer.readObject(input));
+  }
+  
+  @Override
+  public void toData(DataOutput output) throws IOException {
+	try {
+	  DataSerializer.writeObject(getA(), output);
+	  DataSerializer.writeObject(getBs(), output);
+	  DataSerializer.writeObject(getCs(), output);
+	}
+	catch (Exception e) {
+	  e.printStackTrace();
+	  throw new IOException(e);
+	}
+  } 
+
+  @Override
+  public boolean equals(Object other) {
+    if (other==null) return false;
+    if (!(other instanceof CompositeClass)) return false;
+    
+    CompositeClass testclass = (CompositeClass) other;
+    
+    if (this.testclassA != testclass.testclassA) return false;
+    if (this.testclassBs != testclass.testclassBs) return false;
+    if (this.testclassCs != testclass.testclassCs) return false;
+
+    return true;    
+  }
+  
+  public int hashCode() {
+     final int prime = 31;
+     int result = 1;
+     result = prime * result + testclassA.hashCode();
+     result = prime * result + testclassBs.hashCode();
+     result = prime * result + testclassCs.hashCode();
+    
+    return result;
+  }
+}
diff --git a/tests/javaobject/cli/InstantiateDataSerializable.java b/tests/javaobject/cli/InstantiateDataSerializable.java
index 99dff29..14b7c1f 100644
--- a/tests/javaobject/cli/InstantiateDataSerializable.java
+++ b/tests/javaobject/cli/InstantiateDataSerializable.java
@@ -38,6 +38,37 @@ public void execute(FunctionContext context) {
     }
   });
 
+  Instantiator.register(new Instantiator(javaobject.cli.PositionKey.class, 77) {
+    public DataSerializable newInstance() {
+      return new javaobject.cli.PositionKey();
+    }
+  });
+
+  Instantiator.register(new Instantiator(javaobject.cli.TestClassA.class, 100) {
+    public DataSerializable newInstance() {
+      return new javaobject.cli.TestClassA();
+    }
+  });
+
+  Instantiator.register(new Instantiator(javaobject.cli.TestClassB.class, 101) {
+    public DataSerializable newInstance() {
+      return new javaobject.cli.TestClassB();
+    }
+  });
+
+  Instantiator.register(new Instantiator(javaobject.cli.TestClassC.class, 102) {
+    public DataSerializable newInstance() {
+      return new javaobject.cli.TestClassC();
+    }
+  });
+
+  Instantiator.register(new Instantiator(javaobject.cli.CompositeClass.class, 125) {
+    public DataSerializable newInstance() {
+      return new javaobject.cli.CompositeClass();
+    }
+  });
+
+
   ResultSender sender = context.getResultSender();
     sender.lastResult(0);
   } 
diff --git a/tests/javaobject/cli/PositionKey.java b/tests/javaobject/cli/PositionKey.java
new file mode 100644
index 0000000..b0ece8e
--- /dev/null
+++ b/tests/javaobject/cli/PositionKey.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javaobject.cli;
+
+import java.util.*;
+import java.io.*;
+import org.apache.geode.*;
+import org.apache.geode.cache.Declarable;
+
+
+public class PositionKey implements DataSerializable {
+  private long positionId;
+
+  static {
+     Instantiator.register(new Instantiator(javaobject.cli.PositionKey.class, (byte) 77) {
+     public DataSerializable newInstance() {
+        return new PositionKey();
+     }
+   });
+  }
+
+  /* public no-arg constructor required for DataSerializable */  
+  public PositionKey() {}
+
+  public PositionKey(long id){
+    positionId = id;
+  }
+  
+  public String toString(){
+    return "PositionKey [positionId=" + positionId + "]";
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.positionId = in.readLong();
+  }
+  
+  public void toData(DataOutput out) throws IOException {
+    out.writeLong(this.positionId);
+  } 
+  
+  public int hashCode()
+  {
+      final int prime = 31;
+      int result = prime * (int)positionId;
+      return result;
+  }
+
+  public boolean equals(final Object obj)
+  {
+      if (this == obj)
+          return true;
+      if (obj == null)
+          return false;
+      if (getClass() != obj.getClass())
+          return false;
+      final PositionKey other = (PositionKey) obj;
+
+      if (positionId != other.positionId)
+          return false;
+
+      return true;
+  }
+}
diff --git a/tests/javaobject/cli/TestClassA.java b/tests/javaobject/cli/TestClassA.java
new file mode 100644
index 0000000..e3523b9
--- /dev/null
+++ b/tests/javaobject/cli/TestClassA.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javaobject.cli;
+
+import java.util.*;
+import java.io.*;
+import org.apache.geode.*;
+import org.apache.geode.cache.Declarable;
+
+public class TestClassA implements Declarable, Serializable, DataSerializable {
+  private int Id;
+  private String Name;
+  private short NumSides;
+
+  static {
+     Instantiator.register(new Instantiator(javaobject.cli.TestClassA.class, (byte) 100) {
+     public DataSerializable newInstance() {
+        return new TestClassA();
+     }
+   });
+  }
+
+  /* public no-arg constructor required for DataSerializable */  
+  public TestClassA() {}
+
+  public TestClassA(int id, String name, short numSides){
+    Id = id;
+    Name = name;;
+    NumSides = numSides;
+  }
+  
+  public String toString(){
+    return "TestClassA [Id="+Id+" Name="+Name+ " NumSides="+NumSides +"]";
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.Id = in.readInt();
+    this.Name = in.readUTF();
+    this.NumSides = in.readShort();
+  }
+  
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(this.Id);
+    out.writeUTF(this.Name);
+    out.writeShort(this.NumSides);
+  } 
+  
+  public static boolean compareForEquals(Object first, Object second) {
+    if (first == null && second == null) return true;
+    if (first != null && first.equals(second)) return true;
+    return false;
+  }
+  
+  public boolean equals(Object other) {
+    if (other==null) return false;
+    if (!(other instanceof Position)) return false;
+    
+    TestClassA testclass = (TestClassA) other;
+    
+    if (this.Id != testclass.Id) return false;
+    if (this.Name != testclass.Name) return false;
+    if (this.NumSides != testclass.NumSides) return false;
+
+    return true;    
+  }
+  
+  public int hashCode() {
+    Integer i = new Integer(Id);
+    String name = new String(Name);
+    Short numSides = new Short(NumSides);
+
+    int hashcode =
+	  i.hashCode() ^
+	  name.hashCode() ^
+	  numSides.hashCode();
+    
+    return hashcode;
+  }
+}
diff --git a/tests/javaobject/cli/TestClassB.java b/tests/javaobject/cli/TestClassB.java
new file mode 100644
index 0000000..753138f
--- /dev/null
+++ b/tests/javaobject/cli/TestClassB.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javaobject.cli;
+
+import java.util.*;
+import java.io.*;
+import org.apache.geode.*;
+import org.apache.geode.cache.Declarable;
+
+public class TestClassB implements Declarable, Serializable, DataSerializable {
+  private int Width;
+  private int Height;
+  private String Name;
+
+  static {
+     Instantiator.register(new Instantiator(javaobject.cli.TestClassB.class, (byte) 101) {
+     public DataSerializable newInstance() {
+        return new TestClassB();
+     }
+   });
+  }
+
+  /* public no-arg constructor required for DataSerializable */  
+  public TestClassB() {}
+
+  public TestClassB(int width, int height, String name){
+    Width = width;
+    Height = height;
+    Name = name;
+  }
+  
+  public String toString(){
+    return "TestClassB [Width="+Width+" Name="+Name+ " Height="+Height+"]";
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.Width = in.readInt();
+    this.Height = in.readInt();
+    this.Name = in.readUTF();
+  }
+  
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(this.Width);
+    out.writeInt(this.Height);
+    out.writeUTF(this.Name);
+  } 
+  
+  public static boolean compareForEquals(Object first, Object second) {
+    if (first == null && second == null) return true;
+    if (first != null && first.equals(second)) return true;
+    return false;
+  }
+  
+  public boolean equals(Object other) {
+    if (other==null) return false;
+    if (!(other instanceof TestClassB)) return false;
+    
+    TestClassB testclass = (TestClassB) other;
+    
+    if (this.Width != testclass.Width) return false;
+    if (this.Name != testclass.Name) return false;
+    if (this.Height != testclass.Height) return false;
+
+    return true;    
+  }
+  
+  public int hashCode() {
+    Integer width = new Integer(Width);
+    Integer height = new Integer(Height);
+    String name = new String(Name);
+
+    int hashcode =
+	  width.hashCode() ^
+	  name.hashCode() ^
+	  height.hashCode();
+    
+    return hashcode;
+  }
+}
diff --git a/tests/javaobject/cli/TestClassC.java b/tests/javaobject/cli/TestClassC.java
new file mode 100644
index 0000000..08619a7
--- /dev/null
+++ b/tests/javaobject/cli/TestClassC.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package javaobject.cli;
+
+import java.util.*;
+import java.io.*;
+import org.apache.geode.*;
+import org.apache.geode.cache.Declarable;
+
+public class TestClassC implements Declarable, Serializable, DataSerializable {
+  private String Color;
+  private String Make;
+  private int Year;
+
+  static {
+     Instantiator.register(new Instantiator(javaobject.cli.TestClassC.class, (byte) 102) {
+     public DataSerializable newInstance() {
+        return new TestClassC();
+     }
+   });
+  }
+
+  /* public no-arg constructor required for DataSerializable */  
+  public TestClassC() {}
+
+  public TestClassC(String color, String make, int year){
+    Color = color;
+    Make = make;
+    Year = year;
+  }
+  
+  public String toString(){
+    return "TestClassC [Color="+Color+" Make="+Make+ " Year="+Year +"]";
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.Color = in.readUTF();
+    this.Make = in.readUTF();
+    this.Year = in.readInt();
+  }
+  
+  public void toData(DataOutput out) throws IOException {
+    out.writeUTF(this.Color);
+    out.writeUTF(this.Make);
+    out.writeInt(this.Year);
+
+  } 
+  
+  public static boolean compareForEquals(Object first, Object second) {
+    if (first == null && second == null) return true;
+    if (first != null && first.equals(second)) return true;
+    return false;
+  }
+  
+  public boolean equals(Object other) {
+    if (other==null) return false;
+    if (!(other instanceof TestClassC)) return false;
+    
+    TestClassC testclass = (TestClassC) other;
+    
+    if (this.Color != testclass.Color) return false;
+    if (this.Make != testclass.Make) return false;
+    if (this.Year != testclass.Year) return false;
+
+    return true;    
+  }
+  
+  public int hashCode() {
+    String color = new String(Color);
+    String make = new String(Make);
+    Integer year = new Integer(Year);
+
+    int hashcode =
+	  color.hashCode() ^
+	  make.hashCode() ^
+	  year.hashCode();
+    
+    return hashcode;
+  }
+}