GEODE-1392: add tests for BlobHelper * create BlobHelperTest with basic unit tests * create BlobHelperWithThreadContextClassLoaderTest with TCCL related tests * remove deadcode * minor cleanup of format
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/ec1415f4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/ec1415f4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/ec1415f4 Branch: refs/heads/feature/GEODE-835-test Commit: ec1415f4ef6268c524a287a8a9cc19cd0fd9679c Parents: 46056a6 Author: Kirk Lund <kl...@pivotal.io> Authored: Tue May 17 09:38:43 2016 -0700 Committer: Kirk Lund <kl...@pivotal.io> Committed: Tue May 17 17:26:10 2016 -0700 ---------------------------------------------------------------------- .../gemfire/internal/util/BlobHelper.java | 75 ++--- .../gemfire/internal/util/BlobHelperTest.java | 179 +++++++++++ ...bHelperWithThreadContextClassLoaderTest.java | 306 +++++++++++++++++++ .../gemfire/internal/util/SerializableImpl.java | 37 --- .../util/SerializableImplWithValue.java | 56 ---- .../gemfire/internal/util/Valuable.java | 1 - 6 files changed, 509 insertions(+), 145 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ec1415f4/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java index 28252c3..45f9774 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.gemstone.gemfire.internal.util; import java.io.IOException; @@ -26,19 +25,17 @@ import com.gemstone.gemfire.internal.ByteArrayDataInput; import com.gemstone.gemfire.internal.DSCODE; import com.gemstone.gemfire.internal.HeapDataOutputStream; import com.gemstone.gemfire.internal.Version; -import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.offheap.StoredObject; import com.gemstone.gemfire.internal.offheap.annotations.Unretained; import com.gemstone.gemfire.pdx.internal.PdxInputStream; /** * A "blob" is a serialized representation of an object into a byte[]. - * BlobHelper provides utility methods for - * serializing and deserializing the object. - * - * + * BlobHelper provides utility methods for serializing and deserializing the + * object. + * + * TODO: compare performance with org.apache.commons.lang.SerializationUtils */ - public class BlobHelper { /** @@ -50,12 +47,10 @@ public class BlobHelper { } /** - * A blob is a serialized Object. This method serializes the - * object into a blob and returns the byte array that contains the blob. + * A blob is a serialized Object. This method serializes the object into a + * blob and returns the byte array that contains the blob. */ - public static byte[] serializeToBlob(Object obj, Version version) - throws IOException - { + public static byte[] serializeToBlob(Object obj, Version version) throws IOException { final long start = startSerialization(); HeapDataOutputStream hdos = new HeapDataOutputStream(version); DataSerializer.writeObject(obj, hdos); @@ -65,45 +60,32 @@ public class BlobHelper { } /** - * A blob is a serialized Object. This method serializes the - * object into the given HeapDataOutputStream. + * A blob is a serialized Object. This method serializes the object into + * the given HeapDataOutputStream. */ - public static void serializeTo(Object obj, HeapDataOutputStream hdos) - throws IOException - { + public static void serializeTo(Object obj, HeapDataOutputStream hdos) throws IOException { final int startBytes = hdos.size(); final long start = startSerialization(); DataSerializer.writeObject(obj, hdos); endSerialization(start, hdos.size()-startBytes); } - - /** - * A blob is a serialized Object. This method - * returns the deserialized object. + * A blob is a serialized Object. This method returns the deserialized + * object. */ - public static Object deserializeBlob(byte[] blob) throws IOException, - ClassNotFoundException { + public static Object deserializeBlob(byte[] blob) throws IOException, ClassNotFoundException { return deserializeBlob(blob, null, null); } /** - * A blob is a serialized Object. This method - * returns the deserialized object. + * A blob is a serialized Object. This method returns the deserialized + * object. */ - public static Object deserializeBlob(byte[] blob, Version version, - ByteArrayDataInput in) throws IOException, ClassNotFoundException { + public static Object deserializeBlob(byte[] blob, Version version, ByteArrayDataInput in) throws IOException, ClassNotFoundException { Object result; final long start = startDeserialization(); - /* - final StaticSystemCallbacks sysCb; - if (version != null && (sysCb = GemFireCacheImpl.FactoryStatics - .systemCallbacks) != null) { - // may need to change serialized shape for SQLFire - result = sysCb.fromVersion(blob, true, version, in); - } - else*/ if (blob.length > 0 && blob[0] == DSCODE.PDX) { + if (blob.length > 0 && blob[0] == DSCODE.PDX) { // If the first byte of blob indicates a pdx then wrap // blob in a PdxInputStream instead. // This will prevent us from making a copy of the byte[] @@ -121,24 +103,13 @@ public class BlobHelper { result = DataSerializer.readObject(in); } endDeserialization(start, blob.length); - // this causes a small performance drop in d-no-ack performance tests -// if (dis.available() != 0) { -// LogWriterI18n lw = InternalDistributedSystem.getLoggerI18n(); -// if (lw != null && lw.warningEnabled()) { -// lw.warning( -// LocalizedStrings.BlobHelper_DESERIALIZATION_OF_A_0_DID_NOT_READ_1_BYTES_THIS_INDICATES_A_LOGIC_ERROR_IN_THE_SERIALIZATION_CODE_FOR_THIS_CLASS, -// new Object[] {((result!=null) ? result.getClass().getName() : "NULL"), Integer.valueOf(dis.available())}); -// -// } -// } return result; } /** - * A blob is a serialized Object. This method - * returns the deserialized object. - * If a PdxInstance is returned then it will refer to Chunk's off-heap memory - * with an unretained reference. + * A blob is a serialized Object. This method returns the deserialized + * object. If a PdxInstance is returned then it will refer to Chunk's + * off-heap memory with an unretained reference. */ public static @Unretained Object deserializeOffHeapBlob(StoredObject blob) throws IOException, ClassNotFoundException { Object result; @@ -152,8 +123,10 @@ public class BlobHelper { return result; } - public static Object deserializeBuffer(ByteArrayDataInput in, int numBytes) - throws IOException, ClassNotFoundException { + /** + * Unused + */ + public static Object deserializeBuffer(ByteArrayDataInput in, int numBytes) throws IOException, ClassNotFoundException { final long start = startDeserialization(); Object result = DataSerializer.readObject(in); endDeserialization(start, numBytes); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ec1415f4/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperTest.java new file mode 100644 index 0000000..8603c31 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperTest.java @@ -0,0 +1,179 @@ +/* + * 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 com.gemstone.gemfire.internal.util; + +import static com.gemstone.gemfire.internal.util.BlobHelper.*; +import static org.assertj.core.api.Assertions.*; + +import java.io.EOFException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.DataSerializer; +import com.gemstone.gemfire.internal.ByteArrayDataInput; +import com.gemstone.gemfire.internal.HeapDataOutputStream; +import com.gemstone.gemfire.internal.Version; +import com.gemstone.gemfire.internal.offheap.StoredObject; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +/** + * Unit Tests for {@link BlobHelper}. + * + * TODO: add coverage for additional methods: + * <li>{@link BlobHelper#deserializeBlob(byte[], Version, ByteArrayDataInput)} + * <li>{@link BlobHelper#deserializeBuffer(ByteArrayDataInput, int)} + * <li>{@link BlobHelper#deserializeOffHeapBlob(StoredObject)} + * <li>{@link BlobHelper#serializeToBlob(Object, Version)} + */ +@Category(UnitTest.class) +public class BlobHelperTest { + + private static final int HDOS_ALLOC_SIZE = 32; + + private static final String CLASS_NOT_FOUND_MESSAGE = "ClassNotFoundSerialization.readObject fake exception"; + + private Map<Object, Object> mapWithTwoEntries; + + private byte[] bytesOfClassNotFoundSerialization; + private byte[] bytesOfMap; + private byte[] bytesOfNull; + private byte[] zeroBytes; + + @Before + public void setUp() throws Exception { + this.mapWithTwoEntries = new HashMap<>(); + this.mapWithTwoEntries.put("FOO", "foo"); + this.mapWithTwoEntries.put("BAR", 7); + + HeapDataOutputStream hdos = createHeapDataOutputStream(); + DataSerializer.writeObject(new ClassNotFoundSerialization(), hdos); + this.bytesOfClassNotFoundSerialization = hdos.toByteArray(); + + hdos = createHeapDataOutputStream(); + DataSerializer.writeObject(this.mapWithTwoEntries, hdos); + this.bytesOfMap = hdos.toByteArray(); + + this.bytesOfNull = serializeToBlob(null); + + this.zeroBytes = new byte[0]; + } + + @Test + public void deserializeBlobOfClassNotFoundSerializationThrowsEOFException() throws Exception { + assertThatThrownBy(() -> deserializeBlob(this.bytesOfClassNotFoundSerialization)).isExactlyInstanceOf(ClassNotFoundException.class); + } + + @Test + public void deserializeBlobOfMapReturnsCopyOfMap() throws Exception { + final Object object = deserializeBlob(this.bytesOfMap); + + assertThat(object).isNotNull(); + assertThat(object).isExactlyInstanceOf(HashMap.class); + assertThat(object).isNotSameAs(this.mapWithTwoEntries); + assertThat(object).isEqualTo(this.mapWithTwoEntries); + } + + @Test + public void deserializeBlobOfNullReturnsNull() throws Exception { + assertThat(deserializeBlob(this.bytesOfNull)).isNull(); + } + + @Test + public void deserializeBlobOfZeroBytesThrowsEOFException() throws Exception { + assertThatThrownBy(() -> deserializeBlob(this.zeroBytes)).isExactlyInstanceOf(EOFException.class); + } + + @Test + public void deserializeBlobWithNullThrowsNullPointerException() throws Exception { + assertThatThrownBy(() -> deserializeBlob(null)).isExactlyInstanceOf(NullPointerException.class); + } + + @Test + public void serializeMapToStreamWritesMapAsBytes() throws Exception { + HeapDataOutputStream hdos = createHeapDataOutputStream(); + + serializeTo(this.mapWithTwoEntries, hdos); + + assertThat(hdos.toByteArray()).isNotNull().isEqualTo(bytesOfMap); + } + + @Test + public void serializeNullToStreamWritesNullAsBytes() throws Exception { + HeapDataOutputStream hdos = createHeapDataOutputStream(); + + serializeTo(null, hdos); + + assertThat(hdos.toByteArray()).isNotNull().isEqualTo(this.bytesOfNull); + } + + @Test + public void serializeToBlobMapReturnsBytesOfMap() throws Exception { + byte[] bytes = serializeToBlob(this.mapWithTwoEntries); + + assertThat(bytes).isNotNull().isEqualTo(this.bytesOfMap); + } + + @Test + public void serializeToBlobUnserializableThrowsNotSerializableException() throws Exception { + assertThatThrownBy(() -> serializeToBlob(new Object())) + .isExactlyInstanceOf(NotSerializableException.class) + .hasMessage(Object.class.getName()); + } + + @Test + public void serializeToBlobWithNullReturnsBytesOfNull() throws Exception { + byte[] bytes = serializeToBlob(null); + + assertThat(bytes).isNotNull().isEqualTo(this.bytesOfNull); + } + + @Test + public void serializeToNullNullThrowsNullPointerException() throws Exception { + assertThatThrownBy(() -> serializeTo(null, null)).isExactlyInstanceOf(NullPointerException.class); + } + + @Test + public void serializeToNullStreamThrowsNullPointerException() throws Exception { + assertThatThrownBy(() -> serializeTo(this.mapWithTwoEntries, null)).isExactlyInstanceOf(NullPointerException.class); + } + + @Test + public void serializeUnserializableToStreamThrowsNotSerializableException() throws Exception { + HeapDataOutputStream hdos = createHeapDataOutputStream(); + + assertThatThrownBy(() -> serializeTo(new Object(), hdos)) + .isExactlyInstanceOf(NotSerializableException.class) + .hasMessage(Object.class.getName()); + } + + private HeapDataOutputStream createHeapDataOutputStream() { + return new HeapDataOutputStream(HDOS_ALLOC_SIZE, null, true); + } + + private static class ClassNotFoundSerialization implements Serializable { + private void readObject(final ObjectInputStream in) throws ClassNotFoundException { + throw new ClassNotFoundException(CLASS_NOT_FOUND_MESSAGE); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ec1415f4/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperWithThreadContextClassLoaderTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperWithThreadContextClassLoaderTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperWithThreadContextClassLoaderTest.java new file mode 100644 index 0000000..6dfcadd --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/BlobHelperWithThreadContextClassLoaderTest.java @@ -0,0 +1,306 @@ +/* + * 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 com.gemstone.gemfire.internal.util; + +import static org.assertj.core.api.Assertions.*; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.Constants; +import org.apache.bcel.classfile.Field; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.generic.ClassGen; +import org.apache.bcel.generic.ConstantPoolGen; +import org.apache.bcel.generic.FieldGen; +import org.apache.bcel.generic.InstructionFactory; +import org.apache.bcel.generic.InstructionHandle; +import org.apache.bcel.generic.InstructionList; +import org.apache.bcel.generic.MethodGen; +import org.apache.bcel.generic.Type; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +/** + * Unit tests for {@link BlobHelper} with Thread Context ClassLoader. + * + * @since 2.0.2 + */ +@Category(UnitTest.class) +public class BlobHelperWithThreadContextClassLoaderTest { + + private static final String CLASS_NAME_SERIALIZABLE_IMPL = "com.gemstone.gemfire.internal.util.SerializableImpl"; + private static final String CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE = "com.gemstone.gemfire.internal.util.SerializableImplWithValue"; + private static final String VALUE = "value"; + private static final String SET_VALUE = "setValue"; + private static final String GET_VALUE = "getValue"; + + private ClassLoader oldCCL; + + @Before + public void setUp() throws MalformedURLException { + this.oldCCL = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(new GeneratingClassLoader(this.oldCCL)); + } + + @After + public void tearDown() { + Thread.currentThread().setContextClassLoader(this.oldCCL); + } + + @Test + public void tcclLoadsSerializableImpl() throws Exception { + Class loadedClass = Class.forName(CLASS_NAME_SERIALIZABLE_IMPL, true, Thread.currentThread().getContextClassLoader()); + assertThat(loadedClass).isNotNull(); + assertThat(loadedClass.getName()).isEqualTo(CLASS_NAME_SERIALIZABLE_IMPL); + + Object instance = loadedClass.newInstance(); + assertThat(instance).isNotNull(); + assertThat(Serializable.class.isInstance(loadedClass)); + assertThat(loadedClass.getInterfaces()).contains(Serializable.class); + } + + @Test + public void tcclLoadsSerializableImplWithValue() throws Exception { + Class loadedClass = Class.forName(CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE, true, Thread.currentThread().getContextClassLoader()); + assertThat(loadedClass).isNotNull(); + assertThat(loadedClass.getName()).isEqualTo(CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE); + + Object instance = loadedClass.newInstance(); + assertThat(instance).isNotNull(); + + assertThat(loadedClass.getSuperclass().getName()).isEqualTo(CLASS_NAME_SERIALIZABLE_IMPL); + assertThat(Serializable.class.isInstance(loadedClass)); + + assertThat(Valuable.class.isInstance(loadedClass)); + assertThat(loadedClass.getInterfaces()).contains(Valuable.class); + + Method setter = loadedClass.getMethod("setValue", Object.class); + assertThat(setter).isNotNull(); + } + + /** + * Tests serializing an object loaded with the current context class + * loader (whose parent is the loader that loads GemFire and test + * classes). + */ + @Test + public void handlesClassFromOtherClassLoader() throws Exception { + Class loadedClass = Class.forName(CLASS_NAME_SERIALIZABLE_IMPL, true, Thread.currentThread().getContextClassLoader()); + + Object instance = loadedClass.newInstance(); + byte[] bytes = BlobHelper.serializeToBlob(instance); + + Object object = BlobHelper.deserializeBlob(bytes); + + assertThat(object).isNotNull(); + assertThat(object.getClass().getName()).isEqualTo(CLASS_NAME_SERIALIZABLE_IMPL); + assertThat(Serializable.class.isInstance(object)); + + Class deserializedClass = object.getClass(); + assertThat(deserializedClass.getInterfaces()).contains(Serializable.class); + } + + /** + * Tests that the deserialized object has the correct state + */ + @Test + public void handlesObjectWithStateFromOtherClassLoader() throws Exception { + Class loadedClass = Class.forName(CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE, true, Thread.currentThread().getContextClassLoader()); + + Constructor ctor = loadedClass.getConstructor(new Class[] {Object.class}); + Valuable instance = (Valuable) ctor.newInstance(new Object[] {123}); + assertThat(instance.getValue()).isEqualTo(123); + + byte[] bytes = BlobHelper.serializeToBlob(instance); + + Valuable object = (Valuable) BlobHelper.deserializeBlob(bytes); + assertThat(object.getValue()).isEqualTo(instance.getValue()); + } + + /** + * Custom class loader which uses BCEL to dynamically generate SerializableImpl or SerializableImplWithValue. + */ + private static class GeneratingClassLoader extends ClassLoader { + + private static final String GENERATED = "<generated>"; + + private final Map<String, Class<?>> classDefinitions; + + public GeneratingClassLoader(ClassLoader parent) { + super(parent); + this.classDefinitions = new HashMap<>(); + } + + public GeneratingClassLoader() { + this(null); // no parent + } + + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + Class<?> definedClass = null; + synchronized (this.classDefinitions) { + definedClass = getClass(name); + if (definedClass == null) { + definedClass = generate(name); + this.classDefinitions.put(name, definedClass); + } + } + return definedClass; + } + + @Override + protected URL findResource(String name) { + return null; + } + + @Override + protected Enumeration<URL> findResources(String name) throws IOException { + return null; + } + + private Class<?> generate(String name) throws ClassNotFoundException { + if (CLASS_NAME_SERIALIZABLE_IMPL.equals(name)) { + return generateSerializableImpl(); + } else if (CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE.equals(name)) { + return generateSerializableImplWithValue(); + } else { + return null; + //throw new Error("Unable to generate " + name); + } + } + + /** + * <pre> + * public class SerializableImpl implements Serializable { + * + * public SerializableImpl() { + * } + * + * } + * </pre> + */ + private Class<?> generateSerializableImpl() throws ClassNotFoundException { + ClassGen cg = new ClassGen(CLASS_NAME_SERIALIZABLE_IMPL, Object.class.getName(), GENERATED, Constants.ACC_PUBLIC | Constants.ACC_SUPER, new String[] {Serializable.class.getName()}); + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + JavaClass jClazz = cg.getJavaClass(); + byte[] bytes = jClazz.getBytes(); + return defineClass(jClazz.getClassName(), bytes, 0, bytes.length); + } + + /** + * <pre> + * public class SerializableImplWithValue extends SerializableImpl implements Valuable { + * + * private Object value; + * + * public SerializableImplWithValue() { + * } + * + * public SerializableImplWithValue(Object value) { + * this.value = value; + * } + * + * public Object getValue() { + * return this.value; + * } + * + * public void setValue(Object value) { + * this.value = value; + * } + * } + * </pre> + * + * @see Valuable + */ + private Class<?> generateSerializableImplWithValue() throws ClassNotFoundException { + ClassGen cg = new ClassGen(CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE, CLASS_NAME_SERIALIZABLE_IMPL, GENERATED, Constants.ACC_PUBLIC | Constants.ACC_SUPER, new String[] {Valuable.class.getName()}); + ConstantPoolGen cp = cg.getConstantPool(); + InstructionFactory fac = new InstructionFactory(cg, cp); + + // field + FieldGen fg = new FieldGen(Constants.ACC_PRIVATE, Type.OBJECT, VALUE, cp); + Field field = fg.getField(); + cg.addField(field); + + // empty constructor + cg.addEmptyConstructor(Constants.ACC_PUBLIC); + + // constructor with arg + InstructionList ctor = new InstructionList(); + MethodGen ctorMethod = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new Type[] { Type.OBJECT }, new String[] { "arg0" }, "<init>", "com.gemstone.gemfire.internal.util.bcel.SerializableImplWithValue", ctor, cp); + ctorMethod.setMaxStack(2); + + InstructionHandle ctor_ih_0 = ctor.append(fac.createLoad(Type.OBJECT, 0)); + ctor.append(fac.createInvoke(CLASS_NAME_SERIALIZABLE_IMPL, "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + InstructionHandle ctor_ih_4 = ctor.append(fac.createLoad(Type.OBJECT, 0)); + ctor.append(fac.createLoad(Type.OBJECT, 1)); + ctor.append(fac.createFieldAccess(CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE, "value", Type.OBJECT, Constants.PUTFIELD)); + InstructionHandle ctor_ih_9 = ctor.append(fac.createReturn(Type.VOID)); + + cg.addMethod(ctorMethod.getMethod()); + ctor.dispose(); + + // getter + InstructionList getter = new InstructionList(); + MethodGen getterMethod = new MethodGen(Constants.ACC_PUBLIC, Type.OBJECT, null, null, GET_VALUE, CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE, getter, cp); + getterMethod.setMaxStack(1); + + InstructionHandle getter_ih_0 = getter.append(fac.createLoad(Type.OBJECT, 0)); + InstructionHandle getter_ih_1 = getter.append(fac.createGetField(cg.getClassName(), field.getName(), Type.getType(field.getSignature()))); + InstructionHandle getter_ih_4 = getter.append(fac.createReturn(Type.OBJECT)); + + cg.addMethod(getterMethod.getMethod()); + getter.dispose(); + + // setter + InstructionList setter = new InstructionList(); + MethodGen setterMethod = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new Type[] {Type.OBJECT}, new String[] {field.getName()}, SET_VALUE, CLASS_NAME_SERIALIZABLE_IMPL_WITH_VALUE, setter, cp); + setterMethod.setMaxStack(2); + + InstructionHandle setter_ih_0 = setter.append(fac.createLoad(Type.OBJECT, 0)); + InstructionHandle setter_ih_1 = setter.append(fac.createLoad(Type.OBJECT, 1)); + InstructionHandle setter_ih_2 = setter.append(fac.createPutField(cg.getClassName(), field.getName(), Type.getType(field.getSignature()))); + InstructionHandle setter_ih_0_ih_5 = setter.append(fac.createReturn(Type.VOID)); + + cg.addMethod(setterMethod.getMethod()); + setter.dispose(); + + JavaClass jClazz = cg.getJavaClass(); + byte[] bytes = jClazz.getBytes(); + return defineClass(jClazz.getClassName(), bytes, 0, bytes.length); + } + + private Class<?> getClass(String name) { + synchronized (this.classDefinitions) { + return this.classDefinitions.get(name); + } + } + } +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ec1415f4/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImpl.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImpl.java deleted file mode 100644 index 44a8363..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 com.gemstone.gemfire.internal.util; - -import java.io.*; - -/** - * A {@link Serializable} class that is loaded by a class loader other - * than the one that is used to load test classes. - * - * - * @since 2.0.1 - */ -public class SerializableImpl implements Serializable { - - /** - * Creates a new <code>SerializableImpl</code> - */ - public SerializableImpl() { - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ec1415f4/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImplWithValue.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImplWithValue.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImplWithValue.java deleted file mode 100644 index 5727ff8..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/SerializableImplWithValue.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 com.gemstone.gemfire.internal.util; - -//import java.io.*; - -/** - * A {@link SerializableImpl} that implements an interface and has - * some object state. - * - * - * @since 2.0.3 - */ -public class SerializableImplWithValue extends SerializableImpl - implements Valuable { - - /** This object's state */ - private Object value; - - /** - * Zero-argument constructor - */ - public SerializableImplWithValue() { - - } - - /** - * Creates a new <code>SerializableImplWithValue</code> with a given - * value - */ - public SerializableImplWithValue(Object value) { - this.value = value; - } - - public Object getValue() { - return this.value; - } - - public void setValue(Object value) { - this.value = value; - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ec1415f4/geode-core/src/test/java/com/gemstone/gemfire/internal/util/Valuable.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/Valuable.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/Valuable.java index f58deb9..885b665 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/util/Valuable.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/util/Valuable.java @@ -21,7 +21,6 @@ package com.gemstone.gemfire.internal.util; * value associated with them. This interface is not considered to be * a "user class". * - * * @since 2.0.3 */ public interface Valuable {