Skip to content

Commit

Permalink
Fix #938
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Sep 23, 2015
1 parent e9ea56c commit b4eac54
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
5 changes: 5 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Project: jackson-databind
=== Releases ===
------------------------------------------------------------------------

2.6.3 (not yet released)

#938: Regression: StackOverflowError with with 2.6.x (2.5.4 works fine)
(reported by jloisel@github)

2.6.2 (14-Sep-2015)

#894: When using withFactory on ObjectMapper, the created Factory has a TypeParser
Expand Down
32 changes: 28 additions & 4 deletions src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,24 @@ public JavaType[] findTypeParameters(JavaType type, Class<?> expType)
return findTypeParameters(raw, expType, new TypeBindings(this, type));
}

/**
* @since 2.7
*/
public JavaType[] findTypeParameters(JavaType type, Class<?> expType, TypeBindings bindings)
{
if (expType == type.getParameterSource()) {
int count = type.containedTypeCount();
if (count == 0) return null;
JavaType[] result = new JavaType[count];
for (int i = 0; i < count; ++i) {
result[i] = type.containedType(i);
}
return result;
}
Class<?> raw = type.getRawClass();
return findTypeParameters(raw, expType, bindings);
}

public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType) {
return findTypeParameters(clz, expType, new TypeBindings(this, clz));
}
Expand Down Expand Up @@ -989,6 +1007,8 @@ protected JavaType _fromParamType(ParameterizedType type, TypeBindings context)
if (Map.class.isAssignableFrom(rawType)) {
// 19-Mar-2015, tatu: Looks like 2nd arg ought to be Map.class, but that causes fails
JavaType subtype = constructSimpleType(rawType, rawType, pt);
// 23-Sep-2015, tatu: and why do we not pass 3rd arg of 'context'? Won't help, it seems,
// plus causes other issues. Sigh.
JavaType[] mapParams = findTypeParameters(subtype, Map.class);
if (mapParams.length != 2) {
throw new IllegalArgumentException("Could not find 2 type parameters for Map class "+rawType.getName()+" (found "+mapParams.length+")");
Expand All @@ -1013,8 +1033,9 @@ protected JavaType _fromParamType(ParameterizedType type, TypeBindings context)
rt = pt[0];
}
} else {
JavaType[] pts = findTypeParameters(rawType, AtomicReference.class);
if (pts != null && pts.length != 1) {
JavaType subtype = constructSimpleType(rawType, rawType, pt);
JavaType[] pts = findTypeParameters(subtype, AtomicReference.class, context);
if (pts != null && pts.length == 1) {
rt = pts[0];
}
}
Expand All @@ -1029,8 +1050,11 @@ protected JavaType _fromParamType(ParameterizedType type, TypeBindings context)
vt = pt[1];
}
} else {
JavaType[] pts = findTypeParameters(rawType, Map.Entry.class);
if (pts != null && pts.length != 2) {
// 23-Sep-2015, tatu: Must be careful here; type resolution can NOT be done
// directly quite yet. Instead, need to do indirectly...
JavaType subtype = constructSimpleType(rawType, rawType, pt);
JavaType[] pts = findTypeParameters(subtype, Map.Entry.class, context);
if (pts != null && pts.length == 2) {
kt = pts[0];
vt = pts[1];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.fasterxml.jackson.databind.type;

import java.util.*;

import com.fasterxml.jackson.databind.*;

// for [databind#938]
public class RecursiveType938Test extends BaseMapTest
{
public static interface Ability<T> { }

public static final class ImmutablePair<L, R> implements Map.Entry<L, R>, Ability<ImmutablePair<L, R>> {
public final L key;
public final R value;

public ImmutablePair(final L key, final R value) {
this.key = key;
this.value = value;
}

@Override
public L getKey() {
return key;
}

@Override
public R getValue() {
return value;
}

@Override
public R setValue(final R value) {
throw new UnsupportedOperationException();
}

static <L, R> ImmutablePair<L, R> of(final L left, final R right) {
return new ImmutablePair<L, R>(left, right);
}
}

private final ObjectMapper MAPPER = new ObjectMapper();

public void testRecursivePair() throws Exception
{
JavaType t = MAPPER.constructType(ImmutablePair.class);

assertNotNull(t);
assertEquals(ImmutablePair.class, t.getRawClass());

/*
List<ImmutablePair<String, Double>> list = new ArrayList<ImmutablePair<String, Double>>();
list.add(ImmutablePair.of("Hello World!", 123d));
String json = MAPPER.writeValueAsString(list);
assertNotNull(json);
*/
}
}

0 comments on commit b4eac54

Please sign in to comment.