Skip to content

Commit 56deb4c

Browse files
committed
Fix #216 (deprecate Jdk8Module.configureAbsentsAsNulls())
1 parent a68160b commit 56deb4c

File tree

11 files changed

+53
-47
lines changed

11 files changed

+53
-47
lines changed

datatypes/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Module.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public Version version() {
4444

4545
/**
4646
* Configuration method that may be used to change configuration setting
47-
* <code>_cfgHandleAbsentAsNull</code>: enabling means that `Optional.empty()` values
47+
* {@code _cfgHandleAbsentAsNull}: enabling means that `Optional.empty()` values
4848
* are handled like Java nulls (wrt filtering on serialization); disabling that
4949
* they are only treated as "empty" values, but not like native Java nulls.
5050
* Recommended setting for this value is `false`. For compatibility with older versions
@@ -55,11 +55,14 @@ public Version version() {
5555
* criteria for filtering out absent optionals; this setting is mostly useful for
5656
* legacy use cases that predate version 2.6.
5757
*
58-
*
5958
* @return This module instance, useful for chaining calls
6059
*
6160
* @since 2.6
61+
*
62+
* @deprecated Since 2.13, no replacement, will be removed from Jackson 3.0
63+
* (when optional types will be part of core databind)
6264
*/
65+
@Deprecated
6366
public Jdk8Module configureAbsentsAsNulls(boolean state) {
6467
_cfgHandleAbsentAsNull = state;
6568
return this;

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/ContextualOptional17Test.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void testContextualOptionals() throws Exception
4242
input.date2 = Optional.ofNullable(new Date(0L));
4343
final String json = mapper.writeValueAsString(input);
4444
//System.err.println("JSON:\n"+json);
45-
assertEquals(aposToQuotes(
45+
assertEquals(a2q(
4646
"{'date':'1970/01/01','date1':'1970+01+01','date2':'1970*01*01'}"),
4747
json);
4848
}

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/CreatorTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public CreatorWithOptionalStrings(@JsonProperty("a") Optional<String> a,
3737
public void testCreatorWithOptional() throws Exception
3838
{
3939
CreatorWithOptionalStrings bean = MAPPER.readValue(
40-
aposToQuotes("{'a':'foo'}"), CreatorWithOptionalStrings.class);
40+
a2q("{'a':'foo'}"), CreatorWithOptionalStrings.class);
4141
assertNotNull(bean);
4242
assertNotNull(bean.a);
4343
assertNotNull(bean.b);

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/ModuleTestBase.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static ObjectMapper mapperWithModule() {
3232
return mapper;
3333
}
3434

35+
@SuppressWarnings("deprecation")
3536
static ObjectMapper mapperWithModule(boolean absentsAsNulls) {
3637
ObjectMapper mapper = new ObjectMapper();
3738
Jdk8Module module = new Jdk8Module();
@@ -59,11 +60,11 @@ protected void verifyException(Throwable e, String... matches) {
5960
+ msg + "\"");
6061
}
6162

62-
protected String quote(String str) {
63+
protected String q(String str) {
6364
return '"' + str + '"';
6465
}
6566

66-
protected String aposToQuotes(String json) {
67+
protected String a2q(String json) {
6768
return json.replace("'", "\"");
6869
}
6970
}

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalBooleanTest.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,30 @@ public void testBoolean() throws Exception
2222
{
2323
// First, serialization
2424
String json = MAPPER.writeValueAsString(new BooleanBean(true));
25-
assertEquals(aposToQuotes("{'value':true}"), json);
25+
assertEquals(a2q("{'value':true}"), json);
2626
json = MAPPER.writeValueAsString(new BooleanBean());
27-
assertEquals(aposToQuotes("{'value':null}"), json);
27+
assertEquals(a2q("{'value':null}"), json);
2828
json = MAPPER.writeValueAsString(new BooleanBean(null));
29-
assertEquals(aposToQuotes("{'value':null}"), json);
29+
assertEquals(a2q("{'value':null}"), json);
3030

3131
// then deser
32-
BooleanBean b = MAPPER.readValue(aposToQuotes("{'value':null}"), BooleanBean.class);
32+
BooleanBean b = MAPPER.readValue(a2q("{'value':null}"), BooleanBean.class);
3333
assertNotNull(b.value);
3434
assertFalse(b.value.isPresent());
3535

36-
b = MAPPER.readValue(aposToQuotes("{'value':false}"), BooleanBean.class);
36+
b = MAPPER.readValue(a2q("{'value':false}"), BooleanBean.class);
3737
assertNotNull(b.value);
3838
assertTrue(b.value.isPresent());
3939
assertFalse(b.value.get().booleanValue());
4040

41-
b = MAPPER.readValue(aposToQuotes("{'value':true}"), BooleanBean.class);
41+
b = MAPPER.readValue(a2q("{'value':true}"), BooleanBean.class);
4242
assertNotNull(b.value);
4343
assertTrue(b.value.isPresent());
4444
assertTrue(b.value.get().booleanValue());
4545

4646
// and looks like a special, somewhat non-conforming case is what a user had
4747
// issues with
48-
b = MAPPER.readValue(aposToQuotes("{'value':''}"), BooleanBean.class);
48+
b = MAPPER.readValue(a2q("{'value':''}"), BooleanBean.class);
4949
assertNotNull(b.value);
5050
assertFalse(b.value.isPresent());
5151
}

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalNumbersTest.java

+19-19
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,18 @@ public void testOptionalIntPresent() throws Exception
7171

7272
public void testOptionalIntCoerceFromString() throws Exception
7373
{
74-
OptionalInt opt = MAPPER.readValue(quote("123"), OptionalInt.class);
74+
OptionalInt opt = MAPPER.readValue(q("123"), OptionalInt.class);
7575
assertEquals(123, opt.getAsInt());
7676
opt = MAPPER.readValue("\"\"", OptionalInt.class);
7777
assertNotNull(opt);
7878
assertFalse(opt.isPresent());
7979

80-
OptionalIntBean bean = MAPPER.readValue(aposToQuotes("{'value':null}"),
80+
OptionalIntBean bean = MAPPER.readValue(a2q("{'value':null}"),
8181
OptionalIntBean.class);
8282
assertNotNull(bean.value);
8383
assertFalse(bean.value.isPresent());
8484

85-
bean = MAPPER.readValue(aposToQuotes("{'value':'-37'}"), OptionalIntBean.class);
85+
bean = MAPPER.readValue(a2q("{'value':'-37'}"), OptionalIntBean.class);
8686
assertNotNull(bean.value);
8787
assertEquals(-37L, bean.value.getAsInt());
8888
}
@@ -113,20 +113,20 @@ public void testOptionalLongPresent() throws Exception
113113

114114
public void testOptionalLongCoerceFromString() throws Exception
115115
{
116-
OptionalLong opt = MAPPER.readValue(quote("123"), OptionalLong.class);
116+
OptionalLong opt = MAPPER.readValue(q("123"), OptionalLong.class);
117117
assertEquals(123L, opt.getAsLong());
118118

119119
// should coerce from empty String too (by default)
120120
opt = MAPPER.readValue("\"\"", OptionalLong.class);
121121
assertNotNull(opt);
122122
assertFalse(opt.isPresent());
123123

124-
OptionalLongBean bean = MAPPER.readValue(aposToQuotes("{'value':null}"),
124+
OptionalLongBean bean = MAPPER.readValue(a2q("{'value':null}"),
125125
OptionalLongBean.class);
126126
assertNotNull(bean.value);
127127
assertFalse(bean.value.isPresent());
128128

129-
bean = MAPPER.readValue(aposToQuotes("{'value':'19'}"), OptionalLongBean.class);
129+
bean = MAPPER.readValue(a2q("{'value':'19'}"), OptionalLongBean.class);
130130
assertNotNull(bean.value);
131131
assertEquals(19L, bean.value.getAsLong());
132132
}
@@ -135,18 +135,18 @@ public void testOptionalLongSerializeFilter() throws Exception
135135
{
136136
ObjectMapper mapper = mapperWithModule()
137137
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
138-
assertEquals(aposToQuotes("{'value':123}"),
138+
assertEquals(a2q("{'value':123}"),
139139
mapper.writeValueAsString(new OptionalLongBean(123L)));
140140
// absent is not strictly null so
141-
assertEquals(aposToQuotes("{'value':null}"),
141+
assertEquals(a2q("{'value':null}"),
142142
mapper.writeValueAsString(new OptionalLongBean()));
143143

144144
// however:
145145
mapper = mapperWithModule()
146146
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
147-
assertEquals(aposToQuotes("{'value':456}"),
147+
assertEquals(a2q("{'value':456}"),
148148
mapper.writeValueAsString(new OptionalLongBean(456L)));
149-
assertEquals(aposToQuotes("{}"),
149+
assertEquals(a2q("{}"),
150150
mapper.writeValueAsString(new OptionalLongBean()));
151151
}
152152

@@ -176,20 +176,20 @@ public void testOptionalDoublePresent() throws Exception
176176

177177
public void testOptionalDoubleCoerceFromString() throws Exception
178178
{
179-
OptionalDouble opt = MAPPER.readValue(quote("0.25"), OptionalDouble.class);
179+
OptionalDouble opt = MAPPER.readValue(q("0.25"), OptionalDouble.class);
180180
assertEquals(0.25, opt.getAsDouble());
181181

182182
// should coerce from empty String too (by default)
183183
opt = MAPPER.readValue("\"\"", OptionalDouble.class);
184184
assertNotNull(opt);
185185
assertFalse(opt.isPresent());
186186

187-
OptionalDoubleBean bean = MAPPER.readValue(aposToQuotes("{'value':null}"),
187+
OptionalDoubleBean bean = MAPPER.readValue(a2q("{'value':null}"),
188188
OptionalDoubleBean.class);
189189
assertNotNull(bean.value);
190190
assertFalse(bean.value.isPresent());
191191

192-
bean = MAPPER.readValue(aposToQuotes("{'value':'0.5'}"), OptionalDoubleBean.class);
192+
bean = MAPPER.readValue(a2q("{'value':'0.5'}"), OptionalDoubleBean.class);
193193
assertNotNull(bean.value);
194194
assertEquals(0.5, bean.value.getAsDouble());
195195
}
@@ -213,7 +213,7 @@ public void testOptionalDoubleInArraySpecialValues() throws Exception
213213
public void testOptionalDoubleInArraySpecialValuesWithoutCoercion() throws Exception
214214
{
215215
OptionalDouble[] actual = MAPPER_WITHOUT_COERCION.readValue(
216-
aposToQuotes("[null,'NaN','Infinity','-Infinity',1]"),
216+
a2q("[null,'NaN','Infinity','-Infinity',1]"),
217217
OptionalDouble[].class);
218218
OptionalDouble[] expected = new OptionalDouble[] {
219219
OptionalDouble.empty(),
@@ -228,34 +228,34 @@ public void testOptionalDoubleInArraySpecialValuesWithoutCoercion() throws Excep
228228
public void testQuotedOptionalDoubleWithoutCoercion()
229229
{
230230
assertThrows(MismatchedInputException.class,
231-
() -> MAPPER_WITHOUT_COERCION.readValue(aposToQuotes("['1']"), OptionalDouble[].class));
231+
() -> MAPPER_WITHOUT_COERCION.readValue(a2q("['1']"), OptionalDouble[].class));
232232
}
233233

234234
public void testOptionalDoubleBeanSpecialValuesWithoutCoercion_null() throws Exception
235235
{
236236
OptionalDoubleBean bean = MAPPER_WITHOUT_COERCION.readValue(
237-
aposToQuotes("{'value':null}"), OptionalDoubleBean.class);
237+
a2q("{'value':null}"), OptionalDoubleBean.class);
238238
assertEquals(OptionalDouble.empty(), bean.value);
239239
}
240240

241241
public void testOptionalDoubleBeanSpecialValuesWithoutCoercion_nan() throws Exception
242242
{
243243
OptionalDoubleBean bean = MAPPER_WITHOUT_COERCION.readValue(
244-
aposToQuotes("{'value':'NaN'}"), OptionalDoubleBean.class);
244+
a2q("{'value':'NaN'}"), OptionalDoubleBean.class);
245245
assertEquals(OptionalDouble.of(Double.NaN), bean.value);
246246
}
247247

248248
public void testOptionalDoubleBeanSpecialValuesWithoutCoercion_positiveInfinity() throws Exception
249249
{
250250
OptionalDoubleBean bean = MAPPER_WITHOUT_COERCION.readValue(
251-
aposToQuotes("{'value':'Infinity'}"), OptionalDoubleBean.class);
251+
a2q("{'value':'Infinity'}"), OptionalDoubleBean.class);
252252
assertEquals(OptionalDouble.of(Double.POSITIVE_INFINITY), bean.value);
253253
}
254254

255255
public void testOptionalDoubleBeanSpecialValuesWithoutCoercion_negativeInfinity() throws Exception
256256
{
257257
OptionalDoubleBean bean = MAPPER_WITHOUT_COERCION.readValue(
258-
aposToQuotes("{'value':'-Infinity'}"), OptionalDoubleBean.class);
258+
a2q("{'value':'-Infinity'}"), OptionalDoubleBean.class);
259259
assertEquals(OptionalDouble.of(Double.NEGATIVE_INFINITY), bean.value);
260260
}
261261
}

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalTest.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -179,24 +179,24 @@ public void testExcludeIfOptionalAbsent() throws Exception
179179
{
180180
ObjectMapper mapper = mapperWithModule()
181181
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
182-
assertEquals(aposToQuotes("{'value':'foo'}"),
182+
assertEquals(a2q("{'value':'foo'}"),
183183
mapper.writeValueAsString(new OptionalStringBean("foo")));
184184
// absent is not strictly null so
185-
assertEquals(aposToQuotes("{'value':null}"),
185+
assertEquals(a2q("{'value':null}"),
186186
mapper.writeValueAsString(new OptionalStringBean(null)));
187187

188188
// however:
189189
mapper = mapperWithModule()
190190
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
191-
assertEquals(aposToQuotes("{'value':'foo'}"),
191+
assertEquals(a2q("{'value':'foo'}"),
192192
mapper.writeValueAsString(new OptionalStringBean("foo")));
193-
assertEquals(aposToQuotes("{}"),
193+
assertEquals(a2q("{}"),
194194
mapper.writeValueAsString(new OptionalStringBean(null)));
195195
}
196196

197197
public void testWithCustomDeserializer() throws Exception
198198
{
199-
CaseChangingStringWrapper w = MAPPER.readValue(aposToQuotes("{'value':'FoobaR'}"),
199+
CaseChangingStringWrapper w = MAPPER.readValue(a2q("{'value':'FoobaR'}"),
200200
CaseChangingStringWrapper.class);
201201
assertEquals("foobar", w.value.get());
202202
}
@@ -211,41 +211,41 @@ public void testWithCustomDeserializerIfOptionalAbsent() throws Exception
211211
CaseChangingStringWrapper.class).value);
212212
*/
213213

214-
assertEquals(Optional.empty(), MAPPER.readValue(aposToQuotes("{'value':null}"),
214+
assertEquals(Optional.empty(), MAPPER.readValue(a2q("{'value':null}"),
215215
CaseChangingStringWrapper.class).value);
216216
}
217217

218218
public void testCustomSerializer() throws Exception
219219
{
220220
final String VALUE = "fooBAR";
221221
String json = MAPPER.writeValueAsString(new CaseChangingStringWrapper(VALUE));
222-
assertEquals(json, aposToQuotes("{'value':'FOOBAR'}"));
222+
assertEquals(json, a2q("{'value':'FOOBAR'}"));
223223
}
224224

225225
public void testCustomSerializerIfOptionalAbsent() throws Exception
226226
{
227227
ObjectMapper mapper = mapperWithModule()
228228
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
229-
assertEquals(aposToQuotes("{'value':'FOO'}"),
229+
assertEquals(a2q("{'value':'FOO'}"),
230230
mapper.writeValueAsString(new CaseChangingStringWrapper("foo")));
231231
// absent is not strictly null so
232-
assertEquals(aposToQuotes("{'value':null}"),
232+
assertEquals(a2q("{'value':null}"),
233233
mapper.writeValueAsString(new CaseChangingStringWrapper(null)));
234234

235235
// however:
236236
mapper = mapperWithModule()
237237
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
238-
assertEquals(aposToQuotes("{'value':'FOO'}"),
238+
assertEquals(a2q("{'value':'FOO'}"),
239239
mapper.writeValueAsString(new CaseChangingStringWrapper("foo")));
240-
assertEquals(aposToQuotes("{}"),
240+
assertEquals(a2q("{}"),
241241
mapper.writeValueAsString(new CaseChangingStringWrapper(null)));
242242
}
243243

244244
// [modules-java8#33]: Verify against regression...
245245
public void testOtherRefSerializers() throws Exception
246246
{
247247
String json = MAPPER.writeValueAsString(new AtomicReference<String>("foo"));
248-
assertEquals(quote("foo"), json);
248+
assertEquals(q("foo"), json);
249249
}
250250

251251
// Check [databind#2796] here too

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalUnwrappedTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static class Bean2 {
4949
public void testUntypedWithOptionalsNotNulls() throws Exception
5050
{
5151
final ObjectMapper mapper = mapperWithModule(false);
52-
String jsonExp = aposToQuotes("{'XX.name':'Bob'}");
52+
String jsonExp = a2q("{'XX.name':'Bob'}");
5353
String jsonAct = mapper.writeValueAsString(new OptionalParent());
5454
assertEquals(jsonExp, jsonAct);
5555
}

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalWithEmptyTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public BooleanBean(Boolean b) {
1919
}
2020

2121
public void testOptionalFromEmpty() throws Exception {
22-
Optional<?> value = MAPPER.readValue(quote(""), new TypeReference<Optional<Integer>>() {});
22+
Optional<?> value = MAPPER.readValue(q(""), new TypeReference<Optional<Integer>>() {});
2323
assertEquals(false, value.isPresent());
2424
}
2525

@@ -28,7 +28,7 @@ public void testBooleanWithEmpty() throws Exception
2828
{
2929
// and looks like a special, somewhat non-conforming case is what a user had
3030
// issues with
31-
BooleanBean b = MAPPER.readValue(aposToQuotes("{'value':''}"), BooleanBean.class);
31+
BooleanBean b = MAPPER.readValue(a2q("{'value':''}"), BooleanBean.class);
3232
assertNotNull(b.value);
3333

3434
assertEquals(false, b.value.isPresent());

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/TestConfigureAbsentsAsNulls.java

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.fasterxml.jackson.annotation.JsonInclude;
1111
import com.fasterxml.jackson.databind.ObjectMapper;
1212

13+
@SuppressWarnings("deprecation")
1314
public class TestConfigureAbsentsAsNulls extends ModuleTestBase
1415
{
1516
@JsonAutoDetect(fieldVisibility=Visibility.ANY)

release-notes/VERSION-2.x

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Modules:
1414
(contributed by Øystein H)
1515
#212: Make LocalDateDeserializer consider strict/lenient on accepting (or not)
1616
of "time" part
17+
#216: Deprecate method Jdk8Module.configureAbsentsAsNulls() (to be removed from Jackson 3)
1718

1819
2.12.3 (12-Apr-2021)
1920

0 commit comments

Comments
 (0)