Three Maven modules - jackson2-before (2.22.1), jackson3-after (3.2.1) and a coexistence module with BOTH majors on one classpath - so every claim in the two migration guides is executed rather than asserted. Paired class names make the before/after outputs directly diffable via run-all.sh. Confirms the guides on wire-format equivalence (10-case suite, zero mismatches), classpath coexistence and the collapse of four artifacts into one. Corrects nine points, including that enableDefaultTyping() is still present in Jackson 2.22.1 rather than removed in 2.16, and that the published "after" mapper snippet does not compile.
57 lines
2.2 KiB
Markdown
57 lines
2.2 KiB
Markdown
# S04 — Modules, records, Optional and dates
|
|
|
|
Guide: <https://ankurm.com/jackson-3-migration-guide/> (Step 5) and the "Dependency Footprint" table
|
|
|
|
[`before/S04ModulesAndRecords.java`](../jackson2-before/src/main/java/com/ankurm/migration/before/S04ModulesAndRecords.java) ·
|
|
[`after/S04ModulesAndRecords.java`](../jackson3-after/src/main/java/com/ankurm/migration/after/S04ModulesAndRecords.java)
|
|
|
|
The clearest win in the whole migration. Compare the two poms:
|
|
|
|
**[`jackson2-before/pom.xml`](../jackson2-before/pom.xml)** — four artifacts plus a compiler flag:
|
|
|
|
```xml
|
|
com.fasterxml.jackson.core:jackson-databind
|
|
com.fasterxml.jackson.datatype:jackson-datatype-jsr310 <!-- java.time -->
|
|
com.fasterxml.jackson.datatype:jackson-datatype-jdk8 <!-- Optional -->
|
|
com.fasterxml.jackson.module:jackson-module-parameter-names <!-- records -->
|
|
...
|
|
<compilerArgs><arg>-parameters</arg></compilerArgs>
|
|
```
|
|
|
|
**[`jackson3-after/pom.xml`](../jackson3-after/pom.xml)** — one artifact, no compiler args:
|
|
|
|
```xml
|
|
tools.jackson.core:jackson-databind
|
|
```
|
|
|
|
The three module classes have no `tools.jackson` equivalent, so leaving the
|
|
`registerModule` calls in place is a compile error, not a no-op. Delete them.
|
|
|
|
## Output
|
|
|
|
**Jackson 2 — `jackson2-before`**
|
|
|
|
```
|
|
with modules : {"id":1,"departure":"2026-09-15","seat":"12A"}
|
|
round-trip : TravelPlan[id=1, departure=2026-09-15, seat=Optional[12A]]
|
|
bare mapper : FAILS -> InvalidDefinitionException
|
|
bare, dates only: FAILS -> InvalidDefinitionException
|
|
```
|
|
|
|
**Jackson 3 — `jackson3-after`**
|
|
|
|
```
|
|
no modules : {"id":1,"departure":"2026-09-15","seat":"12A"}
|
|
round-trip : TravelPlan[id=1, departure=2026-09-15, seat=Optional[12A]]
|
|
dates : {"d":"2026-09-15"}
|
|
empty Optional : {"id":2,"departure":"2026-09-16","seat":null}
|
|
```
|
|
|
|
The first two lines are byte-identical across versions. The difference is everything
|
|
that had to be set up to get there.
|
|
|
|
The `bare mapper` lines in the Jackson 2 output are the point: without the modules, a
|
|
Jackson 2 mapper cannot serialise `Optional` or `LocalDate` at all — it throws
|
|
`InvalidDefinitionException`. The Jackson 3 mapper in the "after" file has no modules
|
|
registered because there are none to register.
|