Skip to content

Commit 66bfe66

Browse files
committed
Fix #609, Fix #728
1 parent 66e8ac6 commit 66bfe66

File tree

7 files changed

+97
-69
lines changed

7 files changed

+97
-69
lines changed

release-notes/VERSION

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ Project: jackson-databind
66

77
2.5.2 (not yet released)
88

9+
#609: Problem resolving locally declared generic type
10+
(repoted by Hal H)
911
#691: NullSerializer for MapProperty failing when using polymorphic handling
1012
(reported by Antibrumm@github)
1113
#703: Multiple calls to ObjectMapper#canSerialize(Object.class) returns different values
1214
(reported by flexfrank@github)
1315
#705: JsonAnyGetter doesn't work with JsonSerialize (except with keyUsing)
1416
(reported by natnan@github)
17+
#728: TypeFactory#_fromVariable returns unknownType() even though it has enough information
18+
to provide a more specific type
19+
(reported by jkochaniak@github)
1520
- Improvement to handling of custom `ValueInstantiator` for delegating mode; no more NPE
1621
if `getDelegateCreator()` returns null
1722

src/main/java/com/fasterxml/jackson/databind/type/TypeBindings.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,13 @@ public int getBindingCount() {
114114
}
115115
return _bindings.size();
116116
}
117+
118+
@Deprecated // since 2.6, remove from 2.7
119+
public JavaType findType(String name) {
120+
return findType(name, true);
121+
}
117122

118-
public JavaType findType(String name)
123+
public JavaType findType(String name, boolean mustFind)
119124
{
120125
if (_bindings == null) {
121126
_resolve();
@@ -158,6 +163,10 @@ public JavaType findType(String name)
158163
*/
159164
}
160165
}
166+
167+
if (!mustFind) {
168+
return null;
169+
}
161170

162171
String className;
163172
if (_contextClass != null) {

src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ protected JavaType _fromClass(Class<?> clz, TypeBindings context)
755755
context = new TypeBindings(this, cls);
756756
}
757757
*/
758-
758+
759759
// First: do we have an array type?
760760
if (clz.isArray()) {
761761
result = ArrayType.construct(_constructType(clz.getComponentType(), null), null, null);
@@ -858,15 +858,15 @@ protected JavaType _fromParamType(ParameterizedType type, TypeBindings context)
858858

859859
// Ok: Map or Collection?
860860
if (Map.class.isAssignableFrom(rawType)) {
861-
JavaType subtype = constructSimpleType(rawType, pt);
861+
JavaType subtype = constructSimpleType(rawType, rawType, pt);
862862
JavaType[] mapParams = findTypeParameters(subtype, Map.class);
863863
if (mapParams.length != 2) {
864864
throw new IllegalArgumentException("Could not find 2 type parameters for Map class "+rawType.getName()+" (found "+mapParams.length+")");
865865
}
866866
return MapType.construct(rawType, mapParams[0], mapParams[1]);
867867
}
868868
if (Collection.class.isAssignableFrom(rawType)) {
869-
JavaType subtype = constructSimpleType(rawType, pt);
869+
JavaType subtype = constructSimpleType(rawType, rawType, pt);
870870
JavaType[] collectionParams = findTypeParameters(subtype, Collection.class);
871871
if (collectionParams.length != 1) {
872872
throw new IllegalArgumentException("Could not find 1 type parameter for Collection class "+rawType.getName()+" (found "+collectionParams.length+")");
@@ -888,19 +888,21 @@ protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
888888

889889
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
890890
{
891-
/* 26-Sep-2009, tatus: It should be possible to try "partial"
892-
* resolution; meaning that it is ok not to find bindings.
893-
* For now this is indicated by passing null context.
894-
*/
891+
final String name = type.getName();
892+
// 19-Mar-2015: Without context, all we can check are bounds.
895893
if (context == null) {
896-
return _unknownType();
897-
}
898-
899-
// Ok: here's where context might come in handy!
900-
String name = type.getName();
901-
JavaType actualType = context.findType(name);
902-
if (actualType != null) {
903-
return actualType;
894+
// And to prevent infinite loops, now need this:
895+
context = new TypeBindings(this, (Class<?>) null);
896+
} else {
897+
// Ok: here's where context might come in handy!
898+
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
899+
* unresolved type variables to handle some cases where bounds
900+
* are enough. Let's hope it does not hide real fail cases.
901+
*/
902+
JavaType actualType = context.findType(name, false);
903+
if (actualType != null) {
904+
return actualType;
905+
}
904906
}
905907

906908
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
@@ -923,7 +925,7 @@ protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
923925
* (T extends Comparable<T>). Need to add "placeholder"
924926
* for resolution to catch those.
925927
*/
926-
context._addPlaceholder(name);
928+
context._addPlaceholder(name);
927929
return _constructType(bounds[0], context);
928930
}
929931

src/test/java/com/fasterxml/jackson/databind/ser/TestMapSerialization.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@
44
import java.util.*;
55
import java.util.concurrent.ConcurrentHashMap;
66

7-
import com.fasterxml.jackson.annotation.JsonInclude;
8-
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
9-
import com.fasterxml.jackson.annotation.JsonTypeInfo;
7+
import com.fasterxml.jackson.annotation.*;
108
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
11-
import com.fasterxml.jackson.annotation.JsonTypeName;
129
import com.fasterxml.jackson.core.*;
1310
import com.fasterxml.jackson.databind.*;
1411
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@@ -128,6 +125,32 @@ static class MapWithTypedValues extends LinkedHashMap<String,String> { }
128125
@JsonTypeInfo(use = Id.CLASS)
129126
public static class Mixin691 { }
130127

128+
// For [databind#47]
129+
130+
public static class Wat
131+
{
132+
private final String wat;
133+
134+
@JsonCreator
135+
Wat(String wat) {
136+
this.wat = wat;
137+
}
138+
139+
@JsonValue
140+
public String getWat() {
141+
return wat;
142+
}
143+
144+
@Override
145+
public String toString() {
146+
return "(String)[Wat: " + wat + "]";
147+
}
148+
}
149+
150+
// For [databind#47]
151+
@SuppressWarnings("serial")
152+
static class WatMap extends HashMap<Wat,Boolean> { }
153+
131154
/*
132155
/**********************************************************
133156
/* Test methods
@@ -290,5 +313,14 @@ public void testNullJsonInTypedMap691() throws Exception {
290313
String json = mapper.writeValueAsString(map);
291314
assertEquals("{\"@class\":\"java.util.HashMap\",\"NULL\":null}", json);
292315
}
293-
}
294316

317+
public void testMapJsonValueKey47() throws Exception
318+
{
319+
WatMap input = new WatMap();
320+
input.put(new Wat("3"), true);
321+
322+
ObjectMapper mapper = new ObjectMapper();
323+
String json = mapper.writeValueAsString(input);
324+
assertEquals(aposToQuotes("{'3':true}"), json);
325+
}
326+
}

src/test/java/com/fasterxml/jackson/databind/type/TestJavaType.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.databind.type;
22

3+
import java.lang.reflect.Method;
34
import java.util.*;
45

56
import com.fasterxml.jackson.databind.BaseMapTest;
@@ -23,6 +24,31 @@ static enum MyEnum2 {
2324
private MyEnum2(int value) { }
2425
}
2526

27+
// [databind#728]
28+
static class Issue728 {
29+
public <C extends CharSequence> C method(C input) { return null; }
30+
}
31+
public void testLocalType728() throws Exception
32+
{
33+
TypeFactory tf = TypeFactory.defaultInstance();
34+
Method m = Issue728.class.getMethod("method", CharSequence.class);
35+
assertNotNull(m);
36+
37+
// Start with return type
38+
// first type-erased
39+
JavaType t = tf.constructType(m.getReturnType());
40+
assertEquals(CharSequence.class, t.getRawClass());
41+
// then generic
42+
t = tf.constructType(m.getGenericReturnType());
43+
assertEquals(CharSequence.class, t.getRawClass());
44+
45+
// then parameter type
46+
t = tf.constructType(m.getParameterTypes()[0]);
47+
assertEquals(CharSequence.class, t.getRawClass());
48+
t = tf.constructType(m.getGenericParameterTypes()[0]);
49+
assertEquals(CharSequence.class, t.getRawClass());
50+
}
51+
2652
/*
2753
/**********************************************************
2854
/* Test methods

src/test/java/com/fasterxml/jackson/failing/TestLocalType609.java renamed to src/test/java/com/fasterxml/jackson/databind/type/TestLocalType609.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.failing;
1+
package com.fasterxml.jackson.databind.type;
22

33
import com.fasterxml.jackson.databind.*;
44

src/test/java/com/fasterxml/jackson/failing/TestMapJsonValueKey47.java

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)