Skip to content

Commit

Permalink
Properly construct unmodifiable collections within other collections …
Browse files Browse the repository at this point in the history
…in BytecodeRecorderImpl. Fixes #4151
  • Loading branch information
jmartisk authored and gsmet committed Sep 25, 2019
1 parent 2a48499 commit 6343172
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
Expand All @@ -29,6 +30,8 @@
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -1231,12 +1234,16 @@ ResultHandle createValue(MethodContext context, MethodCreator method, ResultHand
out = method.newInstance(ofConstructor(param.getClass()));
} catch (NoSuchMethodException e) {
//fallback for collection types, such as unmodifiableMap
if (expectedType == Map.class) {
if (SortedMap.class.isAssignableFrom(expectedType)) {
out = method.newInstance(ofConstructor(TreeMap.class));
} else if (Map.class.isAssignableFrom(expectedType)) {
out = method.newInstance(ofConstructor(LinkedHashMap.class));
} else if (expectedType == List.class) {
} else if (List.class.isAssignableFrom(expectedType)) {
out = method.newInstance(ofConstructor(ArrayList.class));
} else if (expectedType == Set.class) {
out = method.newInstance(ofConstructor(Set.class));
} else if (SortedSet.class.isAssignableFrom(expectedType)) {
out = method.newInstance(ofConstructor(TreeSet.class));
} else if (Set.class.isAssignableFrom(expectedType)) {
out = method.newInstance(ofConstructor(LinkedHashSet.class));
} else {
throw new RuntimeException("Unable to serialize objects of type " + param.getClass()
+ " to bytecode as it has no default constructor");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Consumer;
Expand Down Expand Up @@ -143,6 +145,40 @@ public void testLargeCollection() throws Exception {
}, beans);
}

@Test
public void testUnmodifiableMapWithinAMap() throws Exception {
Map<Integer, Map<Integer, TestJavaBean>> outerMap = new HashMap<>();
outerMap.put(1, Collections.unmodifiableMap(
Collections.singletonMap(1, new TestJavaBean())));

runTest(generator -> {
TestRecorder recorder = generator.getRecordingProxy(TestRecorder.class);
recorder.map(outerMap);
}, outerMap);
}

@Test
public void testUnmodifiableListWithinAMap() throws Exception {
Map<Integer, List<TestJavaBean>> map = new HashMap<>();
map.put(1, Collections.unmodifiableList(Collections.singletonList(new TestJavaBean())));

runTest(generator -> {
TestRecorder recorder = generator.getRecordingProxy(TestRecorder.class);
recorder.map(map);
}, map);
}

@Test
public void testUnmodifiableSetWithinAMap() throws Exception {
Map<Integer, Set<TestJavaBean>> map = new HashMap<>();
map.put(1, Collections.unmodifiableSet(Collections.singleton(new TestJavaBean())));

runTest(generator -> {
TestRecorder recorder = generator.getRecordingProxy(TestRecorder.class);
recorder.map(map);
}, map);
}

@Test
public void testLargeArray() throws Exception {

Expand Down

0 comments on commit 6343172

Please sign in to comment.