Skip to content

Commit 93391ac

Browse files
Merge branch '3.x' into feature/512-json-wrapped-annotation
2 parents bc7b5f9 + 4e0110d commit 93391ac

6 files changed

Lines changed: 113 additions & 31 deletions

File tree

pom.xml

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
<parent>
1010
<groupId>tools.jackson</groupId>
1111
<artifactId>jackson-base</artifactId>
12-
<version>3.1.0-SNAPSHOT</version>
12+
<version>3.2.0-SNAPSHOT</version>
1313
</parent>
1414
<groupId>tools.jackson.core</groupId>
1515
<artifactId>jackson-databind</artifactId>
16-
<version>3.1.0-SNAPSHOT</version>
16+
<version>3.2.0-SNAPSHOT</version>
1717
<name>jackson-databind</name>
1818
<description>General data-binding functionality for Jackson: works on core streaming API</description>
1919
<url>https://github.com/FasterXML/jackson</url>
@@ -45,21 +45,6 @@
4545
--add-opens=java.base/java.util=tools.jackson.databind
4646
</argLine>
4747

48-
<!-- 12-Nov-2022, tatu: [databind#3659] Verify Android SDK compatibility.
49-
50-
Baseline compatibility:
51-
52-
* Jackson 2.13: compatible with Android SDK 24 and up
53-
* Jackson 2.14 - 2.18: compatible with Android SDK 26 and up
54-
* Jackson 3.0: compatible with Android SDK 34 and up (need Record access)
55-
-->
56-
57-
<version.android.sdk>34</version.android.sdk>
58-
<!-- 24-Mar-2025, tatu: Latest as of now:
59-
https://mvnrepository.com/artifact/com.toasttab.android/gummy-bears-api-34
60-
-->
61-
<version.android.sdk.signature>0.12.0</version.android.sdk.signature>
62-
6348
<version.bytebuddy>1.18.4</version.bytebuddy>
6449
<version.mockito>5.21.0</version.mockito>
6550

@@ -81,7 +66,7 @@
8166
<packageVersion.package>tools.jackson.databind.cfg</packageVersion.package>
8267

8368
<!-- for Reproducible Builds -->
84-
<project.build.outputTimestamp>2026-01-28T04:14:04Z</project.build.outputTimestamp>
69+
<project.build.outputTimestamp>2026-02-23T21:12:24Z</project.build.outputTimestamp>
8570
</properties>
8671

8772
<dependencyManagement>
@@ -271,20 +256,12 @@
271256

272257
<!-- 12-Nov-2022, tatu: [databind#3659] add verification of compatibility
273258
wrt Android SDK versions using AnimalSniffer with "gummy bears" signatures.
274-
To be run from CI, but manually with:
275-
276-
mvn animal-sniffer:check
277259
-->
260+
<!-- 24-Feb-2026, tatu: Starting with 3.2, use common defaults for ASDK level -->
278261
<plugin>
279262
<groupId>org.codehaus.mojo</groupId>
280263
<artifactId>animal-sniffer-maven-plugin</artifactId>
281-
<version>1.27</version>
282264
<configuration>
283-
<signature>
284-
<groupId>com.toasttab.android</groupId>
285-
<artifactId>gummy-bears-api-${version.android.sdk}</artifactId>
286-
<version>${version.android.sdk.signature}</version>
287-
</signature>
288265
<ignores>
289266
<!-- These are only accessed (safely) via "Java7SupportImpl.java" so ignore
290267
-->

release-notes/CREDITS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,9 @@ Flinter (@jhan0121)
265265
Brandon Schmitt (@BrandonSchmitt)
266266
* Reported #5616: `ObjectWriter` serializes `Optional`s with subtypes incompletely
267267
[3.1.0]
268-
268+
* Reported #5710: `ObjectWriter` transforms polymorphic types into a tree incompletely
269+
[3.1.1]
270+
269271
Matthew Luckam (@mluckam)
270272
* Contributed #5630: Add `DelegatingSerializer`
271273

release-notes/VERSION

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,18 @@ Versions: 3.x (for earlier see VERSION-2.x)
55
=== Releases ===
66
------------------------------------------------------------------------
77

8-
3.1.0 (not yet released)
8+
3.2.0 (not yet released)
9+
10+
- Remove project-specific Android SDK compatibility level, use shared;
11+
no change level itself (stillAndroid SDK 34)
12+
13+
3.1.1 (not yet released)
14+
15+
#5710: `ObjectWriter` transforms polymorphic types into a tree incompletely
16+
(reported by Brandon S)
17+
(fix by @cowtowncoder, w/ Claude code)
18+
19+
3.1.0 (23-Feb-2026)
920

1021
#221: Support alternate radixes when writing numeric values as strings
1122
(requested by Christopher C)

release-notes/VERSION-2.x

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Project: jackson-databind
1010
(requested by @SaiKrishna369)
1111
(contributed by Lee Jiwon)
1212

13-
2.21.1 (not yet released)
13+
2.21.1 (22-Feb-2026)
1414

1515
#5184: `@JsonIgnore` on record method applied to record matching
1616
field at deserialization
@@ -239,6 +239,7 @@ No changes since 2.19.2
239239
#5069: Add copy-constructor for `MappingIterator`
240240
(contributed by @wrongwrong)
241241

242+
2.18.6 (22-Feb-2026)
242243
2.18.5 (27-Oct-2025)
243244

244245
No changes since 2.18.4

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import tools.jackson.databind.node.ArrayNode;
2323
import tools.jackson.databind.node.JsonNodeFactory;
2424
import tools.jackson.databind.node.ObjectNode;
25+
import tools.jackson.databind.node.TreeBuildingGenerator;
2526
import tools.jackson.databind.ser.*;
2627
import tools.jackson.databind.ser.impl.TypeWrappedSerializer;
2728
import tools.jackson.databind.type.TypeFactory;
@@ -1186,10 +1187,20 @@ private final void _writeCloseable(JsonGenerator gen, Object value)
11861187
*
11871188
* @since 3.0
11881189
*/
1190+
@SuppressWarnings("unchecked")
11891191
public <T extends JsonNode> T valueToTree(Object fromValue)
11901192
throws JacksonException
11911193
{
1192-
return _serializationContext().valueToTree(fromValue);
1194+
// 25-Feb-2026, tatu: [databind#5710] Must use _prefetch (same as writeValueAsString())
1195+
// so that configured root type info is used, not just runtime type.
1196+
if (fromValue == null) {
1197+
return (T) _config.getNodeFactory().nullNode();
1198+
}
1199+
final SerializationContextExt ctxt = _serializationContext();
1200+
final TreeBuildingGenerator gen = TreeBuildingGenerator.forSerialization(ctxt,
1201+
_config.getNodeFactory());
1202+
_configAndWriteValue(ctxt, gen, fromValue);
1203+
return (T) gen.treeBuilt();
11931204
}
11941205

11951206
/*
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package tools.jackson.databind;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
import com.fasterxml.jackson.annotation.JsonSubTypes;
9+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
10+
import com.fasterxml.jackson.annotation.JsonTypeName;
11+
12+
import tools.jackson.core.type.TypeReference;
13+
14+
import tools.jackson.databind.testutil.DatabindTestUtil;
15+
16+
import static org.junit.jupiter.api.Assertions.*;
17+
18+
// [databind#5710]: ObjectWriter.valueToTree() generates incomplete tree model
19+
// for polymorphic types when wrapped in container/reference types
20+
class ObjectWriterValueToTree5710Test extends DatabindTestUtil
21+
{
22+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
23+
@JsonSubTypes({
24+
@JsonSubTypes.Type(name = "subtype", value = Subtype.class)
25+
})
26+
interface Supertype {}
27+
28+
@JsonTypeName("subtype")
29+
static class Subtype implements Supertype {
30+
public String content = "hello";
31+
}
32+
33+
private final ObjectMapper MAPPER = newJsonMapper();
34+
35+
// Direct polymorphic type: valueToTree() should include "@type" property
36+
@Test
37+
void valueToTreeDirectPolymorphicType() throws Exception
38+
{
39+
ObjectWriter writer = MAPPER.writerFor(new TypeReference<Supertype>() {});
40+
Subtype value = new Subtype();
41+
42+
JsonNode tree = writer.valueToTree(value);
43+
44+
assertTrue(tree.has("@type"), "Expected '@type' property in tree for direct polymorphic type");
45+
assertEquals("subtype", tree.get("@type").asString());
46+
assertEquals("hello", tree.get("content").asString());
47+
}
48+
49+
// List-wrapped polymorphic type: valueToTree() should include "@type" in array elements
50+
@Test
51+
void valueToTreeListWrappedPolymorphicType() throws Exception
52+
{
53+
ObjectWriter writer = MAPPER.writerFor(new TypeReference<List<Supertype>>() {});
54+
List<Subtype> value = List.of(new Subtype());
55+
56+
// writeValueAsString() works correctly
57+
String json = writer.writeValueAsString(value);
58+
assertTrue(json.contains("\"@type\""), "writeValueAsString() should include '@type': " + json);
59+
60+
// valueToTree() should match writeValueAsString()
61+
assertEquals(MAPPER.readTree(json), writer.valueToTree(value),
62+
"valueToTree() should match writeValueAsString() for List<Supertype>");
63+
}
64+
65+
// Optional-wrapped polymorphic type: valueToTree() should include "@type" property
66+
@Test
67+
void valueToTreeOptionalWrappedPolymorphicType() throws Exception
68+
{
69+
ObjectWriter writer = MAPPER.writerFor(new TypeReference<Optional<Supertype>>() {});
70+
Optional<Subtype> value = Optional.of(new Subtype());
71+
72+
// writeValueAsString() works correctly
73+
String json = writer.writeValueAsString(value);
74+
assertTrue(json.contains("\"@type\""), "writeValueAsString() should include '@type': " + json);
75+
76+
// valueToTree() should match writeValueAsString()
77+
assertEquals(MAPPER.readTree(json), writer.valueToTree(value),
78+
"valueToTree() should match writeValueAsString() for Optional<Supertype>");
79+
}
80+
}

0 commit comments

Comments
 (0)