Fixed [JACKSON-778]
diff --git a/release-notes/CREDITS b/release-notes/CREDITS index df78995..4d1bea8 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS
@@ -864,5 +864,10 @@ [1.9.5] Alexander Klauer: - * Reported [JACKSON-779]: Problems with multi-byte UTF-8 chars in JSON comments + * Reported [JACKSON-779]: Problems with multi-byte UTF-8 chars in JSON comments + [1.9.5] + +Vladimir Petrukhin: + * Reported [JACKSON-778], provided test case: Incorrect detection of generic + types with TypeReference [1.9.5]
diff --git a/release-notes/VERSION b/release-notes/VERSION index eb49238..9eb8efd 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION
@@ -15,6 +15,8 @@ (reported by Nathaniel B) * [JACKSON-775]: MissingNode.asText() should return "", not null (reported by Ittai Z) + * [JACKSON-778]: Incorrect detection of generic types with TypeReference + (reported by Vladimir P) * [JACKSON-779]: Problems with multi-byte UTF-8 chars in JSON comments (reported by Alexander K) * [JACKSON-789]: Add support for 'java.nio.charset.Charset'
diff --git a/src/mapper/java/org/codehaus/jackson/map/type/TypeBindings.java b/src/mapper/java/org/codehaus/jackson/map/type/TypeBindings.java index be593b9..2145897 100644 --- a/src/mapper/java/org/codehaus/jackson/map/type/TypeBindings.java +++ b/src/mapper/java/org/codehaus/jackson/map/type/TypeBindings.java
@@ -293,7 +293,15 @@ */ TypeVariable<?>[] vars = raw.getTypeParameters(); if (vars != null && vars.length > 0) { - for (TypeVariable<?> var : vars) { + JavaType[] typeParams = null; + + if (_contextType != null && raw.isAssignableFrom(_contextType.getRawClass())) { + typeParams = _typeFactory.findTypeParameters(_contextType, raw); + } + + for (int i = 0; i < vars.length; i++) { + TypeVariable<?> var = vars[i]; + String name = var.getName(); Type varType = var.getBounds()[0]; if (varType != null) { @@ -303,7 +311,12 @@ if (_bindings.containsKey(name)) continue; } _addPlaceholder(name); // to prevent infinite loops - _bindings.put(name, _typeFactory._constructType(varType, this)); + + if (typeParams != null) { + _bindings.put(name, typeParams[i]); + } else { + _bindings.put(name, _typeFactory._constructType(varType, this)); + } } } }
diff --git a/src/test/org/codehaus/jackson/map/deser/TestGenericSubTyping.java b/src/test/org/codehaus/jackson/map/deser/TestGenericSubTyping.java new file mode 100644 index 0000000..bea268d --- /dev/null +++ b/src/test/org/codehaus/jackson/map/deser/TestGenericSubTyping.java
@@ -0,0 +1,45 @@ +package org.codehaus.jackson.map.deser; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.type.TypeReference; + +import org.codehaus.jackson.map.*; + +public class TestGenericSubTyping extends BaseMapTest +{ + // Types for [JACKSON-778] + + static class Document {} + static class Row {} + static class RowWithDoc<D extends Document> extends Row { + @JsonProperty("d") D d; + } + static class ResultSet<R extends Row> { + @JsonProperty("rows") List<R> rows; + } + static class ResultSetWithDoc<D extends Document> extends ResultSet<RowWithDoc<D>> {} + + static class MyDoc extends Document {} + + /* + /******************************************************* + /* Unit tests + /******************************************************* + */ + + public void testIssue778() throws Exception + { + final ObjectMapper mapper = new ObjectMapper(); + String json = "{\"rows\":[{\"d\":{}}]}"; + + final TypeReference<?> type = new TypeReference<ResultSetWithDoc<MyDoc>>() {}; + + // type passed is correct, but somehow it gets mangled when passed... + ResultSetWithDoc<MyDoc> rs = mapper.readValue(json, type); + Document d = rs.rows.iterator().next().d; + + assertEquals(MyDoc.class, d.getClass()); //expected MyDoc but was Document + } +}