Skip to content

Commit 58bb8ad

Browse files
committed
Fix #1829: change JsonNode.deepCopy() return type to safer
1 parent 6701b43 commit 58bb8ad

15 files changed

+29
-14
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Versions: 3.x (for earlier see VERSION-2.x)
2222
(reported by timo-schmid@github)
2323
#1789: Add `createGenerator` methods in `ObjectMapper`, `ObjectWriter`
2424
#1790: Add `createParser` methods in `ObjectMapper`, `ObjectReader`
25+
#1829: `JsonNode.deepCopy() `ClassCastException`s
26+
(reported by @D3v01dZA)
2527
#1883: Add "abstract type mapping" for deserialization from `Map<ENUMTYPE,V>`
2628
into `EnumMap` (and `Set<ENUMTYPE>` to `EnumSet<EnumType>`)
2729
#1888: Merge `ResolvableSerializer` into `JsonSerializer`, `ResolvableDeserializer`

src/main/java/tools/jackson/databind/JsonNode.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ protected JsonNode() { }
102102
* @return Node that is either a copy of this node (and all non-leaf
103103
* children); or, for immutable leaf nodes, node itself.
104104
*/
105-
public abstract <T extends JsonNode> T deepCopy();
105+
public abstract JsonNode deepCopy();
106106

107107
/*
108108
/**********************************************************************

src/main/java/tools/jackson/databind/deser/jdk/JDKFromStringDeserializer.java

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ protected int _firstHyphenOrUnderscore(String str)
267267
return -1;
268268
}
269269

270+
@SuppressWarnings("deprecation") // Locale constructors deprecated in JDK 19
270271
private Locale _deserializeLocale(String fullValue, DeserializationContext ctxt)
271272
throws JacksonException
272273
{

src/main/java/tools/jackson/databind/node/ArrayNode.java

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ protected JsonNode _at(JsonPointer ptr) {
4747
}
4848

4949
// note: co-variant to allow caller-side type safety
50-
@SuppressWarnings("unchecked")
5150
@Override
5251
public ArrayNode deepCopy()
5352
{

src/main/java/tools/jackson/databind/node/BooleanNode.java

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ public JsonNodeType getNodeType() {
5353
return _value ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE;
5454
}
5555

56+
@Override
57+
public BooleanNode deepCopy() { return this; }
58+
5659
@Override
5760
public boolean booleanValue() {
5861
return _value;

src/main/java/tools/jackson/databind/node/MissingNode.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ protected Object readResolve() {
3434
}
3535

3636
// Immutable: no need to copy
37-
@SuppressWarnings("unchecked")
3837
@Override
39-
public <T extends JsonNode> T deepCopy() { return (T) this; }
38+
public MissingNode deepCopy() { return this; }
4039

4140
public static MissingNode getInstance() { return instance; }
4241

src/main/java/tools/jackson/databind/node/NullNode.java

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ public JsonNodeType getNodeType() {
3333

3434
@Override public JsonToken asToken() { return JsonToken.VALUE_NULL; }
3535

36+
@Override
37+
public NullNode deepCopy() { return this; }
38+
3639
@Override
3740
public String asText(String defaultValue) { return defaultValue; }
3841

src/main/java/tools/jackson/databind/node/NumericNode.java

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public final JsonNodeType getNodeType()
2121
return JsonNodeType.NUMBER;
2222
}
2323

24+
// Overridden for type co-variance
25+
@Override
26+
public NumericNode deepCopy() { return this; }
27+
2428
// // // Let's re-abstract so sub-classes handle them
2529

2630
@Override

src/main/java/tools/jackson/databind/node/ObjectNode.java

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ protected JsonNode _at(JsonPointer ptr) {
4545
* have to, as long as sub-types override the method but...
4646
*/
4747
// note: co-variant for type safety
48-
@SuppressWarnings("unchecked")
4948
@Override
5049
public ObjectNode deepCopy()
5150
{

src/main/java/tools/jackson/databind/node/TextNode.java

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ public JsonNodeType getNodeType() {
5252

5353
@Override public JsonToken asToken() { return JsonToken.VALUE_STRING; }
5454

55+
@Override
56+
public TextNode deepCopy() { return this; }
57+
5558
@Override
5659
public String textValue() {
5760
return _value;

src/main/java/tools/jackson/databind/node/ValueNode.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ protected JsonNode _at(JsonPointer ptr) {
3333
* All current value nodes are immutable, so we can just return
3434
* them as is.
3535
*/
36-
@SuppressWarnings("unchecked")
3736
@Override
38-
public <T extends JsonNode> T deepCopy() { return (T) this; }
37+
public ValueNode deepCopy() { return this; }
3938

4039
@Override public abstract JsonToken asToken();
4140

src/test/java/tools/jackson/databind/ObjectReaderTest.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,8 @@ public void serializeWithType(JsonGenerator g, SerializationContext ctxt, TypeSe
554554
}
555555

556556
@Override
557-
@SuppressWarnings("unchecked")
558-
public <T extends JsonNode> T deepCopy() {
559-
return (T) new CustomObjectNode(_delegate);
557+
public CustomObjectNode deepCopy() {
558+
return new CustomObjectNode(_delegate);
560559
}
561560

562561
@Override
@@ -675,9 +674,8 @@ public void serializeWithType(JsonGenerator g, SerializationContext ctxt, TypeSe
675674
}
676675

677676
@Override
678-
@SuppressWarnings("unchecked")
679-
public <T extends JsonNode> T deepCopy() {
680-
return (T) new DelegatingArrayNode(_delegate);
677+
public DelegatingArrayNode deepCopy() {
678+
return new DelegatingArrayNode(_delegate);
681679
}
682680

683681
@Override

src/test/java/tools/jackson/databind/deser/jdk/LocaleDeserTest.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
import static tools.jackson.databind.testutil.DatabindTestUtil.newJsonMapper;
1616
import static tools.jackson.databind.testutil.DatabindTestUtil.q;
1717

18-
// Tests for `java.util.Locale`
18+
// Tests for `java.util.Locale`.
19+
// NOTE: warnings are due to JDK 19 deprecating Locale constructors
20+
@SuppressWarnings("deprecation")
1921
public class LocaleDeserTest
2022
{
2123
private final Locale[] LOCALES = new Locale[]

src/test/java/tools/jackson/databind/misc/CaseInsensitiveDeser953Test.java

+2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ static class Id953 {
1818
public int someId;
1919
}
2020

21+
@SuppressWarnings("deprecation") // Locale constructors deprecated in JDK 19
2122
private final Locale LOCALE_EN = new Locale("en", "US");
2223

2324
private final ObjectMapper INSENSITIVE_MAPPER_EN = jsonMapperBuilder()
2425
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
2526
.defaultLocale(LOCALE_EN)
2627
.build();
2728

29+
@SuppressWarnings("deprecation") // Locale constructors deprecated in JDK 19
2830
private final Locale LOCALE_TR = new Locale("tr", "TR");
2931

3032
private final ObjectMapper INSENSITIVE_MAPPER_TR = jsonMapperBuilder()

src/test/java/tools/jackson/databind/ser/jdk/JDKTypeSerializationTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public void testCurrency() throws IOException
9595
assertEquals(q("USD"), MAPPER.writeValueAsString(usd));
9696
}
9797

98+
@SuppressWarnings("deprecation")
9899
@Test
99100
public void testLocale() throws IOException
100101
{

0 commit comments

Comments
 (0)