1 package com.fasterxml.jackson.databind.exc; 2 3 import java.io.IOException; 4 import java.util.*; 5 6 import com.fasterxml.jackson.annotation.*; 7 8 import com.fasterxml.jackson.databind.*; 9 10 /** 11 * Unit tests for verifying that simple exceptions can be deserialized. 12 */ 13 public class ExceptionDeserializationTest 14 extends BaseMapTest 15 { 16 @SuppressWarnings("serial") 17 static class MyException extends Exception 18 { 19 protected int value; 20 21 protected String myMessage; 22 protected HashMap<String,Object> stuff = new HashMap<String, Object>(); 23 24 @JsonCreator MyException(@sonProperty"message") String msg, @JsonProperty("value") int v)25 MyException(@JsonProperty("message") String msg, @JsonProperty("value") int v) 26 { 27 super(msg); 28 myMessage = msg; 29 value = v; 30 } 31 getValue()32 public int getValue() { return value; } 33 getFoo()34 public String getFoo() { return "bar"; } 35 setter(String key, Object value)36 @JsonAnySetter public void setter(String key, Object value) 37 { 38 stuff.put(key, value); 39 } 40 } 41 42 @SuppressWarnings("serial") 43 static class MyNoArgException extends Exception 44 { MyNoArgException()45 @JsonCreator MyNoArgException() { } 46 } 47 48 /* 49 /********************************************************** 50 /* Tests 51 /********************************************************** 52 */ 53 54 private final ObjectMapper MAPPER = new ObjectMapper(); 55 testIOException()56 public void testIOException() throws IOException 57 { 58 IOException ioe = new IOException("TEST"); 59 String json = MAPPER.writeValueAsString(ioe); 60 IOException result = MAPPER.readValue(json, IOException.class); 61 assertEquals(ioe.getMessage(), result.getMessage()); 62 } 63 testWithCreator()64 public void testWithCreator() throws IOException 65 { 66 final String MSG = "the message"; 67 String json = MAPPER.writeValueAsString(new MyException(MSG, 3)); 68 69 MyException result = MAPPER.readValue(json, MyException.class); 70 assertEquals(MSG, result.getMessage()); 71 assertEquals(3, result.value); 72 assertEquals(1, result.stuff.size()); 73 assertEquals(result.getFoo(), result.stuff.get("foo")); 74 } 75 testWithNullMessage()76 public void testWithNullMessage() throws IOException 77 { 78 final ObjectMapper mapper = new ObjectMapper(); 79 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 80 String json = mapper.writeValueAsString(new IOException((String) null)); 81 IOException result = mapper.readValue(json, IOException.class); 82 assertNotNull(result); 83 assertNull(result.getMessage()); 84 } 85 testNoArgsException()86 public void testNoArgsException() throws IOException 87 { 88 MyNoArgException exc = MAPPER.readValue("{}", MyNoArgException.class); 89 assertNotNull(exc); 90 } 91 92 // try simulating JDK 7 behavior testJDK7SuppressionProperty()93 public void testJDK7SuppressionProperty() throws IOException 94 { 95 Exception exc = MAPPER.readValue("{\"suppressed\":[]}", IOException.class); 96 assertNotNull(exc); 97 } 98 99 // [databind#381] testSingleValueArrayDeserialization()100 public void testSingleValueArrayDeserialization() throws Exception { 101 final ObjectMapper mapper = new ObjectMapper(); 102 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS); 103 final IOException exp; 104 try { 105 throw new IOException("testing"); 106 } catch (IOException internal) { 107 exp = internal; 108 } 109 final String value = "[" + mapper.writeValueAsString(exp) + "]"; 110 111 final IOException cloned = mapper.readValue(value, IOException.class); 112 assertEquals(exp.getMessage(), cloned.getMessage()); 113 114 assertEquals(exp.getStackTrace().length, cloned.getStackTrace().length); 115 for (int i = 0; i < exp.getStackTrace().length; i ++) { 116 _assertEquality(i, exp.getStackTrace()[i], cloned.getStackTrace()[i]); 117 } 118 } 119 _assertEquality(int ix, StackTraceElement exp, StackTraceElement act)120 protected void _assertEquality(int ix, StackTraceElement exp, StackTraceElement act) 121 { 122 _assertEquality(ix, "className", exp.getClassName(), act.getClassName()); 123 _assertEquality(ix, "methodName", exp.getMethodName(), act.getMethodName()); 124 _assertEquality(ix, "fileName", exp.getFileName(), act.getFileName()); 125 _assertEquality(ix, "lineNumber", exp.getLineNumber(), act.getLineNumber()); 126 } 127 _assertEquality(int ix, String prop, Object exp, Object act)128 protected void _assertEquality(int ix, String prop, 129 Object exp, Object act) 130 { 131 if (exp == null) { 132 if (act == null) { 133 return; 134 } 135 } else { 136 if (exp.equals(act)) { 137 return; 138 } 139 } 140 fail(String.format("StackTraceElement #%d, property '%s' differs: expected %s, actual %s", 141 ix, prop, exp, act)); 142 } 143 testSingleValueArrayDeserializationException()144 public void testSingleValueArrayDeserializationException() throws Exception { 145 final ObjectMapper mapper = new ObjectMapper(); 146 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS); 147 148 final IOException exp; 149 try { 150 throw new IOException("testing"); 151 } catch (IOException internal) { 152 exp = internal; 153 } 154 final String value = "[" + mapper.writeValueAsString(exp) + "]"; 155 156 try { 157 mapper.readValue(value, IOException.class); 158 fail("Exception not thrown when attempting to deserialize an IOException wrapped in a single value array with UNWRAP_SINGLE_VALUE_ARRAYS disabled"); 159 } catch (JsonMappingException exp2) { 160 verifyException(exp2, "from Array value (token `JsonToken.START_ARRAY`)"); 161 } 162 } 163 164 // mostly to help with XML module (and perhaps CSV) testLineNumberAsString()165 public void testLineNumberAsString() throws IOException 166 { 167 Exception exc = MAPPER.readValue(aposToQuotes( 168 "{'message':'Test',\n'stackTrace': " 169 +"[ { 'lineNumber':'50' } ] }" 170 ), IOException.class); 171 assertNotNull(exc); 172 } 173 174 // [databind#1842]: testNullAsMessage()175 public void testNullAsMessage() throws IOException 176 { 177 Exception exc = MAPPER.readValue(aposToQuotes( 178 "{'message':null, 'localizedMessage':null }" 179 ), IOException.class); 180 assertNotNull(exc); 181 assertNull(exc.getMessage()); 182 assertNull(exc.getLocalizedMessage()); 183 } 184 } 185