Skip to content

Commit eae6759

Browse files
committed
Fix #1195
1 parent 9e2f76e commit eae6759

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Project: jackson-databind
1313
(reported by carrino@github)
1414
#1191: Non-matching quotes used in error message for date parsing
1515
#1194: Incorrect signature for generic type via `JavaType.getGenericSignature
16+
#1195: `JsonMappingException` not Serializable due to 2.7 reference to source (parser)
17+
(reported by mjustin@github)
1618
#1198: Problem with `@JsonTypeInfo.As.EXTERNAL_PROPERTY`, `defaultImpl`, missing type id, NPE
1719
- Improve handling of custom content (de)serializers for `AtomicReference`
1820

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

+27-2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ public Reference(Object from, int index) {
8989
_index = index;
9090
}
9191

92+
private Reference(Reference src, Object newFrom) {
93+
_from = newFrom;
94+
_fieldName = src._fieldName;
95+
_index = src._index;
96+
}
97+
9298
public void setFrom(Object o) { _from = o; }
9399
public void setFieldName(String n) { _fieldName = n; }
94100
public void setIndex(int ix) { _index = ix; }
@@ -124,7 +130,24 @@ public Reference(Object from, int index) {
124130
sb.append(']');
125131
return sb.toString();
126132
}
127-
}
133+
134+
/**
135+
* May need some cleaning here, given that `from` may or may not be serializable.
136+
*
137+
* since 2.7.4
138+
*/
139+
Object writeReplace() {
140+
// as per [databind#1195], reference may cause trouble, if non-serializable
141+
// instance. What to replace it with is trickier; Class is most natural, but
142+
// would recipient have that available? Assume this is the case, for now, because
143+
//
144+
if ((_from != null) && !(_from instanceof Serializable)) {
145+
Object from = _from.getClass();
146+
return new Reference(this, from);
147+
}
148+
return this;
149+
}
150+
}
128151

129152
/*
130153
/**********************************************************
@@ -141,10 +164,12 @@ public Reference(Object from, int index) {
141164
/**
142165
* Underlying processor ({@link JsonParser} or {@link JsonGenerator}),
143166
* if known.
167+
*<p>
168+
* NOTE: typically not serializable hence <code>transient</code>
144169
*
145170
* @since 2.7
146171
*/
147-
protected Closeable _processor;
172+
protected transient Closeable _processor;
148173

149174
/*
150175
/**********************************************************

src/test/java/com/fasterxml/jackson/databind/TestJDKSerialization.java

-1
Original file line numberDiff line numberDiff line change
@@ -194,5 +194,4 @@ protected <T> T jdkDeserialize(byte[] raw) throws IOException
194194
objIn.close();
195195
}
196196
}
197-
198197
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.fasterxml.jackson.databind.interop;
2+
3+
import java.io.*;
4+
5+
import com.fasterxml.jackson.databind.*;
6+
7+
public class ExceptionSerializableTest1195 extends BaseMapTest
8+
{
9+
abstract static class ClassToRead {
10+
public int x;
11+
}
12+
13+
static class ContainerClassToRead {
14+
public ClassToRead classToRead;
15+
}
16+
17+
public void testExceptionSerializability() throws Exception
18+
{
19+
final ObjectMapper mapper = new ObjectMapper();
20+
try {
21+
mapper.readValue("{\"type\": \"B\"}", ClassToRead.class);
22+
fail("Should not have passed");
23+
} catch (JsonMappingException e) {
24+
ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream());
25+
try {
26+
stream.writeObject(e);
27+
stream.close();
28+
} catch (Exception e2) {
29+
fail("Failed to serialize "+e.getClass().getName()+": "+e2);
30+
}
31+
}
32+
try {
33+
mapper.readValue("{\"classToRead\": {\"type\": \"B\"}}", ContainerClassToRead.class);
34+
fail("Should not have passed");
35+
} catch (JsonMappingException e) {
36+
ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream());
37+
try {
38+
stream.writeObject(e);
39+
stream.close();
40+
} catch (Exception e2) {
41+
fail("Failed to serialize "+e.getClass().getName()+": "+e2);
42+
}
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)