Skip to content

Commit 39294f9

Browse files
committed
Fixed #2126
1 parent b42dfc4 commit 39294f9

File tree

6 files changed

+97
-24
lines changed

6 files changed

+97
-24
lines changed

release-notes/VERSION-2.x

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Project: jackson-databind
1313
(requested by Christopher S)
1414
#2116: Make NumberSerializers.Base public and its inherited classes not final
1515
(requested by Édouard M)
16+
#2126: `DeserializationContext.instantiationException()` throws `InvalidDefinitionException`
1617

1718
2.9.7 (not yet released)
1819

src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
2323
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
2424
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
25+
import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
2526
import com.fasterxml.jackson.databind.introspect.Annotated;
2627
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
2728
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
@@ -1594,8 +1595,6 @@ public JsonMappingException weirdNativeValueException(Object value, Class<?> ins
15941595
* if necessary.
15951596
*/
15961597
public JsonMappingException instantiationException(Class<?> instClass, Throwable cause) {
1597-
// Most likely problem with Creator definition, right?
1598-
final JavaType type = constructType(instClass);
15991598
String excMsg;
16001599
if (cause == null) {
16011600
excMsg = "N/A";
@@ -1604,9 +1603,9 @@ public JsonMappingException instantiationException(Class<?> instClass, Throwable
16041603
}
16051604
String msg = String.format("Cannot construct instance of %s, problem: %s",
16061605
ClassUtil.nameOf(instClass), excMsg);
1607-
InvalidDefinitionException e = InvalidDefinitionException.from(_parser, msg, type);
1608-
e.initCause(cause);
1609-
return e;
1606+
// [databind#2162]: use specific exception type as we don't know if it's
1607+
// due to type definition, input, or neither
1608+
return ValueInstantiationException.from(_parser, msg, constructType(instClass), cause);
16101609
}
16111610

16121611
/**
@@ -1619,11 +1618,12 @@ public JsonMappingException instantiationException(Class<?> instClass, Throwable
16191618
* if necessary.
16201619
*/
16211620
public JsonMappingException instantiationException(Class<?> instClass, String msg0) {
1622-
// Most likely problem with Creator definition, right?
1623-
JavaType type = constructType(instClass);
1624-
String msg = String.format("Cannot construct instance of %s: %s",
1625-
ClassUtil.nameOf(instClass), msg0);
1626-
return InvalidDefinitionException.from(_parser, msg, type);
1621+
// [databind#2162]: use specific exception type as we don't know if it's
1622+
// due to type definition, input, or neither
1623+
return ValueInstantiationException.from(_parser,
1624+
String.format("Cannot construct instance of %s: %s",
1625+
ClassUtil.nameOf(instClass), msg0),
1626+
constructType(instClass));
16271627
}
16281628

16291629
@Override

src/main/java/com/fasterxml/jackson/databind/deser/std/StdValueInstantiator.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ public AnnotatedParameter getIncompleteParameter() {
439439
*/
440440

441441
/**
442-
* @deprecated Since 2.7 call either {@link #unwrapAndWrapException} or
442+
* @deprecated Since 2.7 call either {@link #rewrapCtorProblem} or
443443
* {@link #wrapAsJsonMappingException}
444444
*/
445445
@Deprecated // since 2.7
@@ -457,8 +457,10 @@ protected JsonMappingException wrapException(Throwable t)
457457
}
458458

459459
/**
460-
* @since 2.7
460+
* @deprecated Since 2.7 call either {@link #rewrapCtorProblem} or
461+
* {@link #wrapAsJsonMappingException}
461462
*/
463+
@Deprecated // since 2.10
462464
protected JsonMappingException unwrapAndWrapException(DeserializationContext ctxt, Throwable t)
463465
{
464466
// 05-Nov-2015, tatu: This used to always unwrap the whole exception, but now only
@@ -472,6 +474,11 @@ protected JsonMappingException unwrapAndWrapException(DeserializationContext ctx
472474
}
473475

474476
/**
477+
* Helper method that will return given {@link Throwable} case as
478+
* a {@link JsonMappingException} (if it is of that type), or call
479+
* {@link DeserializationContext#instantiationException(Class, Throwable)} to
480+
* produce and return suitable {@link JsonMappingException}.
481+
*
475482
* @since 2.7
476483
*/
477484
protected JsonMappingException wrapAsJsonMappingException(DeserializationContext ctxt,
@@ -485,6 +492,10 @@ protected JsonMappingException wrapAsJsonMappingException(DeserializationContext
485492
}
486493

487494
/**
495+
* Method that subclasses may call for standard handling of an exception thrown when
496+
* calling constructor or factory method. Will unwrap {@link ExceptionInInitializerError}
497+
* and {@link InvocationTargetException}s, then call {@link #wrapAsJsonMappingException}.
498+
*
488499
* @since 2.7
489500
*/
490501
protected JsonMappingException rewrapCtorProblem(DeserializationContext ctxt,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.fasterxml.jackson.databind.exc;
2+
3+
import com.fasterxml.jackson.core.JsonParser;
4+
5+
import com.fasterxml.jackson.databind.JavaType;
6+
import com.fasterxml.jackson.databind.JsonMappingException;
7+
8+
/**
9+
* Exception type used for generic failures during processing by
10+
* {@link com.fasterxml.jackson.databind.deser.ValueInstantiator}:
11+
* commonly used to wrap exceptions thrown by constructor or factory
12+
* method.
13+
*<p>
14+
* Note that this type is sibling of {@link MismatchedInputException} and
15+
* {@link InvalidDefinitionException} since it is not clear if problem is
16+
* with input, or type definition (or possibly neither).
17+
* It is recommended that if either specific input, or type definition problem
18+
* is known, a more accurate exception is used instead.
19+
*
20+
* @since 2.10
21+
*/
22+
@SuppressWarnings("serial")
23+
public class ValueInstantiationException
24+
extends JsonMappingException
25+
{
26+
protected final JavaType _type;
27+
28+
protected ValueInstantiationException(JsonParser p, String msg,
29+
JavaType type, Throwable cause) {
30+
super(p, msg, cause);
31+
_type = type;
32+
}
33+
34+
protected ValueInstantiationException(JsonParser p, String msg,
35+
JavaType type) {
36+
super(p, msg);
37+
_type = type;
38+
}
39+
40+
public static ValueInstantiationException from(JsonParser p, String msg,
41+
JavaType type) {
42+
return new ValueInstantiationException(p, msg, type);
43+
}
44+
45+
public static ValueInstantiationException from(JsonParser p, String msg,
46+
JavaType type, Throwable cause) {
47+
return new ValueInstantiationException(p, msg, type, cause);
48+
}
49+
50+
/**
51+
* Accessor for type fully resolved type that had the problem; this should always
52+
* known and available, never <code>null</code>
53+
*/
54+
public JavaType getType() {
55+
return _type;
56+
}
57+
}

src/test/java/com/fasterxml/jackson/databind/deser/creators/TestCreators2.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import com.fasterxml.jackson.core.*;
1010
import com.fasterxml.jackson.databind.*;
1111
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
12+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
13+
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
14+
import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
1215

1316
public class TestCreators2 extends BaseMapTest
1417
{
@@ -190,7 +193,7 @@ public void testExceptionFromConstructor() throws Exception
190193
try {
191194
MAPPER.readValue("{}", BustedCtor.class);
192195
fail("Expected exception");
193-
} catch (JsonMappingException e) {
196+
} catch (ValueInstantiationException e) {
194197
verifyException(e, ": foobar");
195198
// also: should have nested exception
196199
Throwable t = e.getCause();
@@ -200,6 +203,8 @@ public void testExceptionFromConstructor() throws Exception
200203
assertNotNull(t);
201204
assertEquals(IllegalArgumentException.class, t.getClass());
202205
assertEquals("foobar", t.getMessage());
206+
} catch (Exception e) {
207+
fail("Should have caught ValueInstantiationException, got: "+e);
203208
}
204209
}
205210

@@ -210,7 +215,6 @@ public void testSimpleConstructor() throws Exception
210215
assertEquals("abc", new String(test.bytes, "UTF-8"));
211216
}
212217

213-
// Test for [JACKSON-372]
214218
public void testMissingPrimitives() throws Exception
215219
{
216220
Primitives p = MAPPER.readValue("{}", Primitives.class);
@@ -238,11 +242,11 @@ public void testJackson438() throws Exception
238242
try {
239243
MAPPER.readValue("{ \"name\":\"foobar\" }", BeanFor438.class);
240244
fail("Should have failed");
241-
} catch (Exception e0) {
245+
} catch (JsonMappingException e0) {
242246
e = e0;
243247
}
244-
if (!(e instanceof JsonMappingException)) {
245-
fail("Should have received JsonMappingException, caught "+e.getClass().getName());
248+
if (!(e instanceof ValueInstantiationException)) {
249+
fail("Should have received ValueInstantiationException, caught "+e.getClass().getName());
246250
}
247251
verifyException(e, "don't like that name");
248252
// Ok: also, let's ensure root cause is directly linked, without other extra wrapping:
@@ -259,7 +263,7 @@ public void testCreatorWithDupNames() throws Exception
259263
try {
260264
MAPPER.readValue("{\"bar\":\"x\"}", BrokenCreatorBean.class);
261265
fail("Should have caught duplicate creator parameters");
262-
} catch (JsonMappingException e) {
266+
} catch (InvalidDefinitionException e) {
263267
verifyException(e, "duplicate creator property \"bar\"");
264268
verifyException(e, "for type `com.fasterxml.jackson.databind.");
265269
verifyException(e, "$BrokenCreatorBean`");
@@ -278,7 +282,7 @@ public void testIgnoredSingleArgCtor() throws Exception
278282
try {
279283
MAPPER.readValue(quote("abc"), IgnoredCtor.class);
280284
fail("Should have caught missing constructor problem");
281-
} catch (JsonMappingException e) {
285+
} catch (MismatchedInputException e) {
282286
verifyException(e, "no String-argument constructor/factory method");
283287
}
284288
}

src/test/java/com/fasterxml/jackson/databind/deser/filter/ProblemHandlerTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import com.fasterxml.jackson.databind.*;
1111
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
1212
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
13-
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
1413
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
14+
import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
1515
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
1616

1717
/**
@@ -92,14 +92,14 @@ static class InstantiationProblemHandler
9292
public InstantiationProblemHandler(Object v0) {
9393
value = v0;
9494
}
95-
95+
9696
@Override
9797
public Object handleInstantiationProblem(DeserializationContext ctxt,
9898
Class<?> instClass, Object argument, Throwable t)
9999
throws IOException
100100
{
101-
if (!(t instanceof InvalidDefinitionException)) {
102-
throw new IllegalArgumentException("Should have gotten `InvalidDefinitionException`, instead got: "+t);
101+
if (!(t instanceof ValueInstantiationException)) {
102+
throw new IllegalArgumentException("Should have gotten `ValueInstantiationException`, instead got: "+t);
103103
}
104104
return value;
105105
}
@@ -109,7 +109,7 @@ static class MissingInstantiationHandler
109109
extends DeserializationProblemHandler
110110
{
111111
protected final Object value;
112-
112+
113113
public MissingInstantiationHandler(Object v0) {
114114
value = v0;
115115
}

0 commit comments

Comments
 (0)