Skip to content

Commit

Permalink
JBMAR-128 - fix issue with River protocol with subclasses of known cl…
Browse files Browse the repository at this point in the history
…asses
  • Loading branch information
dmlloyd committed Feb 4, 2012
1 parent 517a449 commit 5428567
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
import java.security.PrivilegedAction;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.AbstractMap;
import java.util.AbstractQueue;
import java.util.AbstractSequentialList;
import java.util.AbstractSet;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
Expand Down Expand Up @@ -93,32 +95,39 @@ public final class ClassDescriptors {
public static final ClassDescriptor ABSTRACT_QUEUE = new SimpleClassDescriptor(AbstractQueue.class, Protocol.ID_ABSTRACT_QUEUE);
public static final ClassDescriptor ABSTRACT_SEQUENTIAL_LIST = new SimpleClassDescriptor(AbstractSequentialList.class, Protocol.ID_ABSTRACT_SEQUENTIAL_LIST);
public static final ClassDescriptor ABSTRACT_SET = new SimpleClassDescriptor(AbstractSet.class, Protocol.ID_ABSTRACT_SET);
// TODO - this should be a protocol byte
public static final ClassDescriptor ABSTRACT_MAP =new SimpleClassDescriptor(AbstractMap.class, Protocol.ID_PLAIN_CLASS);
public static final ClassDescriptor PAIR = new SimpleClassDescriptor(Pair.class, Protocol.ID_PAIR);

// These classes are final
static final ClassDescriptor SINGLETON_MAP = getSerializableClassDescriptor(Protocol.singletonMapClass);
static final ClassDescriptor SINGLETON_SET = getSerializableClassDescriptor(Protocol.singletonSetClass);
static final ClassDescriptor SINGLETON_LIST = getSerializableClassDescriptor(Protocol.singletonListClass);
static final ClassDescriptor EMPTY_MAP = getSerializableClassDescriptor(Protocol.emptyMapClass);
static final ClassDescriptor EMPTY_SET = getSerializableClassDescriptor(Protocol.emptySetClass);
static final ClassDescriptor EMPTY_LIST = getSerializableClassDescriptor(Protocol.emptyListClass);
static final ClassDescriptor CC_ARRAY_LIST = getSerializableClassDescriptor(ArrayList.class);
static final ClassDescriptor CC_LINKED_LIST = getSerializableClassDescriptor(LinkedList.class);
static final ClassDescriptor CC_HASH_SET = getSerializableClassDescriptor(HashSet.class);
static final ClassDescriptor CC_LINKED_HASH_SET = getSerializableClassDescriptor(LinkedHashSet.class);
static final ClassDescriptor CC_TREE_SET = getSerializableClassDescriptor(TreeSet.class);
static final ClassDescriptor CC_IDENTITY_HASH_MAP = getSerializableClassDescriptor(IdentityHashMap.class);
static final ClassDescriptor CC_HASH_MAP = getSerializableClassDescriptor(HashMap.class);
static final ClassDescriptor CC_HASHTABLE = getSerializableClassDescriptor(Hashtable.class);
static final ClassDescriptor CC_LINKED_HASH_MAP = getSerializableClassDescriptor(LinkedHashMap.class);
static final ClassDescriptor CC_TREE_MAP = getSerializableClassDescriptor(TreeMap.class);
static final ClassDescriptor CC_ENUM_SET = getSerializableClassDescriptor(EnumSet.class);
static final ClassDescriptor CC_ENUM_MAP = getSerializableClassDescriptor(EnumMap.class);
static final ClassDescriptor CONCURRENT_HASH_MAP = getSerializableClassDescriptor(ConcurrentHashMap.class);
static final ClassDescriptor COPY_ON_WRITE_ARRAY_LIST = getSerializableClassDescriptor(CopyOnWriteArrayList.class);
static final ClassDescriptor COPY_ON_WRITE_ARRAY_SET = getSerializableClassDescriptor(CopyOnWriteArraySet.class);
static final ClassDescriptor VECTOR = getSerializableClassDescriptor(Vector.class);
static final ClassDescriptor STACK = getSerializableClassDescriptor(Stack.class);
static final ClassDescriptor ARRAY_DEQUE = getSerializableClassDescriptor(ArrayDeque.class);

// Non-final classes
static final ClassDescriptor CC_ARRAY_LIST = getSerializableClassDescriptor(ArrayList.class, ABSTRACT_LIST);
static final ClassDescriptor CC_LINKED_LIST = getSerializableClassDescriptor(LinkedList.class, ABSTRACT_SEQUENTIAL_LIST);
static final ClassDescriptor CC_HASH_SET = getSerializableClassDescriptor(HashSet.class, ABSTRACT_SET);
static final ClassDescriptor CC_LINKED_HASH_SET = getSerializableClassDescriptor(LinkedHashSet.class, CC_HASH_SET);
static final ClassDescriptor CC_TREE_SET = getSerializableClassDescriptor(TreeSet.class, ABSTRACT_SET);
static final ClassDescriptor CC_IDENTITY_HASH_MAP = getSerializableClassDescriptor(IdentityHashMap.class, ABSTRACT_MAP);
static final ClassDescriptor CC_HASH_MAP = getSerializableClassDescriptor(HashMap.class, ABSTRACT_MAP);
static final ClassDescriptor CC_HASHTABLE = getSerializableClassDescriptor(Hashtable.class, new SimpleClassDescriptor(Dictionary.class, Protocol.ID_PLAIN_CLASS));
static final ClassDescriptor CC_LINKED_HASH_MAP = getSerializableClassDescriptor(LinkedHashMap.class, CC_HASH_MAP);
static final ClassDescriptor CC_TREE_MAP = getSerializableClassDescriptor(TreeMap.class, ABSTRACT_MAP);
static final ClassDescriptor CC_ENUM_SET = getSerializableClassDescriptor(EnumSet.class, ABSTRACT_SET);
static final ClassDescriptor CC_ENUM_MAP = getSerializableClassDescriptor(EnumMap.class, ABSTRACT_MAP);
static final ClassDescriptor CONCURRENT_HASH_MAP = getSerializableClassDescriptor(ConcurrentHashMap.class, ABSTRACT_MAP);
static final ClassDescriptor COPY_ON_WRITE_ARRAY_LIST = getSerializableClassDescriptor(CopyOnWriteArrayList.class, OBJECT_DESCRIPTOR);
static final ClassDescriptor COPY_ON_WRITE_ARRAY_SET = getSerializableClassDescriptor(CopyOnWriteArraySet.class, ABSTRACT_SET);
static final ClassDescriptor VECTOR = getSerializableClassDescriptor(Vector.class, ABSTRACT_LIST);
static final ClassDescriptor STACK = getSerializableClassDescriptor(Stack.class, VECTOR);
static final ClassDescriptor ARRAY_DEQUE = getSerializableClassDescriptor(ArrayDeque.class, ABSTRACT_COLLECTION);

// These classes are final
static final ClassDescriptor REVERSE_ORDER = getSerializableClassDescriptor(Protocol.reverseOrderClass);
static final ClassDescriptor REVERSE_ORDER2 = getSerializableClassDescriptor(Protocol.reverseOrder2Class);
static final ClassDescriptor NCOPIES = getSerializableClassDescriptor(Protocol.nCopiesClass);
Expand All @@ -127,14 +136,18 @@ private ClassDescriptors() {
}

private static SerializableClassDescriptor getSerializableClassDescriptor(final Class<?> subject) {
return getSerializableClassDescriptor(subject, null);
}

private static SerializableClassDescriptor getSerializableClassDescriptor(final Class<?> subject, final ClassDescriptor superDescriptor) {
return AccessController.doPrivileged(new PrivilegedAction<SerializableClassDescriptor>() {
public SerializableClassDescriptor run() {
final SerializableClassRegistry reg = SerializableClassRegistry.getInstance();
final SerializableClass serializableClass = reg.lookup(subject);
final SerializableField[] fields = serializableClass.getFields();
final boolean hasWriteObject = serializableClass.hasWriteObject();
try {
return new BasicSerializableClassDescriptor(serializableClass, null, fields, Externalizable.class.isAssignableFrom(subject) ? Protocol.ID_EXTERNALIZABLE_CLASS : hasWriteObject ? Protocol.ID_WRITE_OBJECT_CLASS : Protocol.ID_SERIALIZABLE_CLASS);
return new BasicSerializableClassDescriptor(serializableClass, superDescriptor, fields, Externalizable.class.isAssignableFrom(subject) ? Protocol.ID_EXTERNALIZABLE_CLASS : hasWriteObject ? Protocol.ID_WRITE_OBJECT_CLASS : Protocol.ID_SERIALIZABLE_CLASS);
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.jboss.marshalling.Marshaller;
import org.jboss.marshalling.Marshalling;
import org.jboss.marshalling.Unmarshaller;
import org.jboss.marshalling.reflect.ReflectiveCreator;
import org.jboss.marshalling.reflect.SunReflectiveCreator;
import org.jboss.marshalling.MarshallingConfiguration;
import java.io.ByteArrayOutputStream;
Expand All @@ -38,7 +39,8 @@ public abstract class ReadWriteTest {
public void run() throws Throwable {
final MarshallerFactory factory = new RiverMarshallerFactory();
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setCreator(new SunReflectiveCreator());
configuration.setSerializedCreator(new SunReflectiveCreator());
configuration.setExternalizerCreator(new ReflectiveCreator());
configure(configuration);
final Marshaller marshaller = factory.createMarshaller(configuration);
final ByteArrayOutputStream baos = new ByteArrayOutputStream(10240);
Expand Down
45 changes: 45 additions & 0 deletions tests/src/test/java/org/jboss/test/marshalling/LRUMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., 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.jboss.test.marshalling;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
public class LRUMap<K, V> extends LinkedHashMap<K, V> {

private static final long serialVersionUID = -4085177629568085771L;

private int maxCapacity;

public LRUMap(int maxCapacity) {
super(maxCapacity, 0.8f, true);
this.maxCapacity = maxCapacity;
}

protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return (size() > maxCapacity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.jboss.marshalling.Externalizer;
import org.jboss.marshalling.FieldSetter;
import org.jboss.marshalling.Marshaller;
import org.jboss.marshalling.MarshallerFactory;
import org.jboss.marshalling.Marshalling;
import org.jboss.marshalling.MarshallingConfiguration;
import org.jboss.marshalling.ObjectInputStreamUnmarshaller;
Expand All @@ -80,6 +81,9 @@
import org.jboss.marshalling.SimpleClassResolver;
import org.jboss.marshalling.StreamHeader;
import org.jboss.marshalling.Unmarshaller;
import org.jboss.marshalling.reflect.ReflectiveCreator;
import org.jboss.marshalling.reflect.SunReflectiveCreator;
import org.jboss.marshalling.river.RiverMarshallerFactory;
import org.jboss.marshalling.river.RiverUnmarshaller;
import org.testng.SkipException;
import org.testng.annotations.Test;
Expand All @@ -94,6 +98,23 @@ public SimpleMarshallerTests(TestMarshallerProvider testMarshallerProvider, Test
super(testMarshallerProvider, testUnmarshallerProvider, configuration);
}

/**
* Simple constructor for running one test at a time from an IDE.
*/
public SimpleMarshallerTests() {
super(new MarshallerFactoryTestMarshallerProvider(new RiverMarshallerFactory(), 3),
new MarshallerFactoryTestUnmarshallerProvider(new RiverMarshallerFactory(), 3),
getOneTestMarshallingConfiguration());
}

private static MarshallingConfiguration getOneTestMarshallingConfiguration() {
final MarshallingConfiguration marshallingConfiguration = new MarshallingConfiguration();
marshallingConfiguration.setExternalizerCreator(new ReflectiveCreator());
marshallingConfiguration.setSerializedCreator(new SunReflectiveCreator());
marshallingConfiguration.setVersion(3);
return marshallingConfiguration;
}

@Test
public void testNull() throws Throwable {
runReadWriteTest(new ReadWriteTest() {
Expand Down Expand Up @@ -2795,4 +2816,20 @@ public void runRead(final Unmarshaller unmarshaller) throws Throwable {
}
});
}

@Test
public void testHierarchyLikeLinkedHashMapSubclass() throws Throwable {
final LRUMap test = new LRUMap(64);
runReadWriteTest(new ReadWriteTest() {
public void runWrite(final Marshaller marshaller) throws Throwable {
marshaller.writeObject(test);
marshaller.writeObject(test);
}

public void runRead(final Unmarshaller unmarshaller) throws Throwable {
final LRUMap map = unmarshaller.readObject(LRUMap.class);
assertSame(map, unmarshaller.readObject());
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ private static void populateAllMaps(List<Object> list) {
populateAllMapSizes(list, identityHashMapMaker);
populateAllMapSizes(list, treeMapMaker);
populateAllMapSizes(list, treeMapCompMaker);
populateAllMapSizes(list, lruMapMaker);
}

private static void populateAllCollections(List<Object> list) {
Expand Down Expand Up @@ -275,6 +276,12 @@ public Map<Integer, Object> make() {
}
};

private static final Maker<Map<Integer,Object>> lruMapMaker = new Maker<Map<Integer, Object>>() {
public Map<Integer, Object> make() {
return new LRUMap<Integer, Object>(60);
}
};

private static final Maker<Map<Integer,Object>> identityHashMapMaker = new Maker<Map<Integer,Object>>() {
public Map<Integer, Object> make() {
return new IdentityHashMap<Integer, Object>();
Expand Down

0 comments on commit 5428567

Please sign in to comment.