Skip to content

Commit a1674bd

Browse files
committed
A fix for #1498 implementation to prevent regression failures wrt Exception deserialization
1 parent c0cba51 commit a1674bd

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

src/main/java/com/fasterxml/jackson/databind/cfg/ConstructorDetector.java

+22-3
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public ConstructorDetector withRequireAnnotation(boolean state) {
155155
state, _allowJDKTypeCtors);
156156
}
157157

158-
public ConstructorDetector withAllowJDKTypes(boolean state) {
158+
public ConstructorDetector withAllowJDKTypeConstructors(boolean state) {
159159
return new ConstructorDetector(_singleArgMode,
160160
_requireCtorAnnotation, state);
161161
}
@@ -186,12 +186,31 @@ public boolean singleArgCreatorDefaultsToProperties() {
186186
return _singleArgMode == SingleArgConstructor.PROPERTIES;
187187
}
188188

189-
public boolean allowImplicitCreators(Class<?> rawType) {
189+
/**
190+
* Accessor that combines calls to {@link #allowImplicitCreators} and
191+
* {@link #allowJDKTypeConstructors} to determine whether implicit constructor
192+
* detection should be enabled or not.
193+
*
194+
* @param rawType Value type to consider
195+
*
196+
* @return True if implicit constructor detection should be enabled; false if not
197+
*/
198+
public boolean shouldIntrospectorImplicitConstructors(Class<?> rawType) {
190199
// May not allow implicit creator introspection at all:
191200
if (_requireCtorAnnotation) {
192201
return false;
193202
}
194203
// But if it is allowed, may further limit use for JDK types
195-
return _allowJDKTypeCtors || !ClassUtil.isJDKClass(rawType);
204+
if (!_allowJDKTypeCtors) {
205+
if (ClassUtil.isJDKClass(rawType)) {
206+
// 18-Sep-2020, tatu: Looks like must make an exception for Exception
207+
// types (ha!) -- at this point, single-String-arg constructor
208+
// is to be auto-detected
209+
if (!Throwable.class.isAssignableFrom(rawType)) {
210+
return false;
211+
}
212+
}
213+
}
214+
return true;
196215
}
197216
}

src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,14 @@ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationCo
252252
throws JsonMappingException
253253
{
254254
final CreatorCollectionState ccState;
255-
final boolean findImplicit;
255+
final ConstructorDetector ctorDetector;
256256

257257
{
258258
final DeserializationConfig config = ctxt.getConfig();
259259
// need to construct suitable visibility checker:
260260
final VisibilityChecker<?> vchecker = config.getDefaultVisibilityChecker(beanDesc.getBeanClass(),
261261
beanDesc.getClassInfo());
262-
// 18-Sep-2020, tatu: Although by default implicit introspection is allowed, 2.12
263-
// has settings to prevent that either generally, or at least for JDK types
264-
findImplicit = config.getConstructorDetector().allowImplicitCreators(beanDesc.getBeanClass());
262+
ctorDetector = config.getConstructorDetector();
265263

266264
// 24-Sep-2014, tatu: Tricky part first; need to merge resolved property information
267265
// (which has creator parameters sprinkled around) with actual creator
@@ -278,7 +276,7 @@ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationCo
278276
}
279277

280278
// Start with explicitly annotated factory methods
281-
_addExplicitFactoryCreators(ctxt, ccState, findImplicit);
279+
_addExplicitFactoryCreators(ctxt, ccState, !ctorDetector.requireCtorAnnotation());
282280

283281
// constructors only usable on concrete types:
284282
if (beanDesc.getType().isConcrete()) {
@@ -300,6 +298,9 @@ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationCo
300298
// TODO: look for `@JsonCreator` annotated ones, throw explicit exception?
301299
;
302300
} else {
301+
// 18-Sep-2020, tatu: Although by default implicit introspection is allowed, 2.12
302+
// has settings to prevent that either generally, or at least for JDK types
303+
final boolean findImplicit = ctorDetector.shouldIntrospectorImplicitConstructors(beanDesc.getBeanClass());
303304
_addExplicitConstructorCreators(ctxt, ccState, findImplicit);
304305
if (ccState.hasImplicitConstructorCandidates()
305306
&& !ccState.hasExplicitFactories() && !ccState.hasExplicitConstructors()) {

src/test/java/com/fasterxml/jackson/databind/exc/ExceptionDeserializationTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ static class MyNoArgException extends Exception
5656
public void testIOException() throws IOException
5757
{
5858
IOException ioe = new IOException("TEST");
59-
String json = MAPPER.writeValueAsString(ioe);
59+
String json = MAPPER.writerWithDefaultPrettyPrinter()
60+
.writeValueAsString(ioe);
6061
IOException result = MAPPER.readValue(json, IOException.class);
6162
assertEquals(ioe.getMessage(), result.getMessage());
6263
}

0 commit comments

Comments
 (0)