Skip to content

Commit 712905e

Browse files
committed
Improve JDK serialization handling of inner-non-static class properties
1 parent 9b530bf commit 712905e

File tree

2 files changed

+56
-23
lines changed

2 files changed

+56
-23
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/impl/FieldProperty.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ protected FieldProperty(FieldProperty src, PropertyName newName) {
5858
/**
5959
* Constructor used for JDK Serialization when reading persisted object
6060
*/
61-
protected FieldProperty(FieldProperty src, Field f)
61+
protected FieldProperty(FieldProperty src)
6262
{
6363
super(src);
6464
_annotated = src._annotated;
65+
Field f = _annotated.getAnnotated();
6566
if (f == null) {
66-
throw new IllegalArgumentException("No Field passed for property '"+src.getName()
67-
+"' (class "+src.getDeclaringClass().getName()+")");
67+
throw new IllegalArgumentException("Missing field (broken JDK (de)serialization?)");
6868
}
6969
_field = f;
7070
}
@@ -144,6 +144,6 @@ public Object setAndReturn(Object instance, Object value)
144144
*/
145145

146146
Object readResolve() {
147-
return new FieldProperty(this, _annotated.getAnnotated());
147+
return new FieldProperty(this);
148148
}
149149
}

src/main/java/com/fasterxml/jackson/databind/deser/impl/InnerClassProperty.java

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@
44
import java.lang.annotation.Annotation;
55
import java.lang.reflect.Constructor;
66

7-
import com.fasterxml.jackson.core.JsonParser;
8-
import com.fasterxml.jackson.core.JsonProcessingException;
9-
import com.fasterxml.jackson.core.JsonToken;
10-
import com.fasterxml.jackson.databind.DeserializationContext;
11-
import com.fasterxml.jackson.databind.JsonDeserializer;
12-
import com.fasterxml.jackson.databind.PropertyName;
7+
import com.fasterxml.jackson.core.*;
8+
import com.fasterxml.jackson.databind.*;
139
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
14-
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
10+
import com.fasterxml.jackson.databind.introspect.*;
1511
import com.fasterxml.jackson.databind.util.ClassUtil;
1612

1713
/**
@@ -31,10 +27,17 @@ public final class InnerClassProperty
3127
protected final SettableBeanProperty _delegate;
3228

3329
/**
34-
* Single-arg constructor we use for value instantiation.
30+
* Constructor used when deserializing this property.
31+
* Transient since there is no need to persist; only needed during
32+
* construction of objects.
3533
*/
36-
protected final Constructor<?> _creator;
34+
final protected transient Constructor<?> _creator;
3735

36+
/**
37+
* Serializable version of single-arg constructor we use for value instantiation.
38+
*/
39+
protected AnnotatedConstructor _annotated;
40+
3841
public InnerClassProperty(SettableBeanProperty delegate,
3942
Constructor<?> ctor)
4043
{
@@ -43,6 +46,21 @@ public InnerClassProperty(SettableBeanProperty delegate,
4346
_creator = ctor;
4447
}
4548

49+
/**
50+
* Constructor used with JDK Serialization; needed to handle transient
51+
* Constructor, wrap/unwrap in/out-of Annotated variant.
52+
*/
53+
protected InnerClassProperty(InnerClassProperty src, AnnotatedConstructor ann)
54+
{
55+
super(src);
56+
_delegate = src._delegate;
57+
_annotated = ann;
58+
_creator = (_annotated == null) ? null : _annotated.getAnnotated();
59+
if (_creator == null) {
60+
throw new IllegalArgumentException("Missing constructor (broken JDK (de)serialization?)");
61+
}
62+
}
63+
4664
protected InnerClassProperty(InnerClassProperty src, JsonDeserializer<?> deser)
4765
{
4866
super(src, deser);
@@ -82,9 +100,8 @@ public <A extends Annotation> A getAnnotation(Class<A> acls) {
82100
*/
83101

84102
@Override
85-
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
86-
Object bean)
87-
throws IOException, JsonProcessingException
103+
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object bean)
104+
throws IOException
88105
{
89106
JsonToken t = jp.getCurrentToken();
90107
Object value;
@@ -107,21 +124,37 @@ public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
107124
@Override
108125
public Object deserializeSetAndReturn(JsonParser jp,
109126
DeserializationContext ctxt, Object instance)
110-
throws IOException, JsonProcessingException
127+
throws IOException
111128
{
112129
return setAndReturn(instance, deserialize(jp, ctxt));
113130
}
114131

115132
@Override
116-
public final void set(Object instance, Object value) throws IOException
117-
{
133+
public final void set(Object instance, Object value) throws IOException {
118134
_delegate.set(instance, value);
119135
}
120136

121137
@Override
122-
public Object setAndReturn(Object instance, Object value)
123-
throws IOException
124-
{
125-
return _delegate.setAndReturn(instance, value);
138+
public Object setAndReturn(Object instance, Object value) throws IOException {
139+
return _delegate.setAndReturn(instance, value);
140+
}
141+
142+
/*
143+
/**********************************************************
144+
/* JDK serialization handling
145+
/**********************************************************
146+
*/
147+
148+
// When reading things back,
149+
Object readResolve() {
150+
return new InnerClassProperty(this, _annotated);
151+
}
152+
153+
Object writeReplace() {
154+
// need to construct a fake instance to support serialization
155+
if (_annotated != null) {
156+
return this;
157+
}
158+
return new InnerClassProperty(this, new AnnotatedConstructor(_creator, null, null));
126159
}
127160
}

0 commit comments

Comments
 (0)