Jackson 2 to 3 migration companion code

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.
This commit is contained in:
2026-08-04 23:29:27 +05:30
commit f0a7053fc9
43 changed files with 1665 additions and 0 deletions
@@ -0,0 +1,4 @@
output : {"id":1,"travelDate":"2026-09-15","seatPreference":"aisle"}
forked indented : { "id" : 1, "travelDate" : "2026-09-15", "seatPreference" : "aisle" }
original intact : false
set*() mutators : 0 <- mutation is impossible, not merely discouraged
@@ -0,0 +1,5 @@
JacksonException extends RuntimeException : true
JacksonException extends IOException : false
ESCAPED catch (IOException) : StreamReadException
caught by catch (Jackson...) : StreamReadException
writeValueAsString declares : [class tools.jackson.core.JacksonException] <- nothing checked
+3
View File
@@ -0,0 +1,3 @@
serialised : {"amount":19.99,"currency":"USD"}
deserialised : Money[amount=20.0, currencyCode=USD]
base classes : tools.jackson.databind.ValueSerializer / tools.jackson.databind.ValueDeserializer
@@ -0,0 +1,4 @@
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}
+7
View File
@@ -0,0 +1,7 @@
enableDefaultTyping on Jackson 3 ObjectMapper : false
activateDefaultTyping on Jackson 3 ObjectMapper : false
activateDefaultTyping on JsonMapper.Builder : true
written : {"@class":"com.ankurm.migration.after.S05DefaultTyping$Envelope","body":{"@class":"com.ankurm.migration.after.S05DefaultTyping$SafePayload","note":"ok"}}
read : SafePayload[ok]
rogue : rejected with InvalidTypeIdException
@@ -0,0 +1,9 @@
FAIL_ON_TRAILING_TOKENS : true
FAIL_ON_UNKNOWN_PROPERTIES : false
ALLOW_FINAL_FIELDS_AS_MUTATORS: false
DEFAULT_VIEW_INCLUSION : false
AUTO_DETECT_CREATORS exists : false
concatenated JSON -> rejected: MismatchedInputException
trailing garbage -> rejected: StreamReadException
unknown property -> accepted: OrderDto[orderId=1]
@@ -0,0 +1,4 @@
output : {"id":1,"travelDate":"2026-09-15","seatPreference":"aisle"}
after mutation : { "id" : 1, "travelDate" : "2026-09-15", "seatPreference" : "aisle" }
mutation stuck : true
set*() mutators : 40
@@ -0,0 +1,3 @@
JsonProcessingException extends IOException : true
caught by catch (IOException) : JsonParseException
writeValueAsString declares : [class com.fasterxml.jackson.core.JsonProcessingException]
+3
View File
@@ -0,0 +1,3 @@
serialised : {"amount":19.99,"currency":"USD"}
deserialised : Money[amount=20.0, currencyCode=USD]
base classes : com.fasterxml.jackson.databind.JsonSerializer / com.fasterxml.jackson.databind.JsonDeserializer
@@ -0,0 +1,4 @@
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
+3
View File
@@ -0,0 +1,3 @@
enableDefaultTyping on Jackson 2.22 ObjectMapper : true
written : {"@class":"com.ankurm.migration.before.S05DefaultTyping$Envelope","body":{"@class":"com.ankurm.migration.before.S05DefaultTyping$SafePayload","note":"ok"}}
read : SafePayload[ok]
@@ -0,0 +1,9 @@
FAIL_ON_TRAILING_TOKENS : false
FAIL_ON_UNKNOWN_PROPERTIES : true
ALLOW_FINAL_FIELDS_AS_MUTATORS: true
DEFAULT_VIEW_INCLUSION : true
AUTO_DETECT_CREATORS exists : true
concatenated JSON -> accepted: OrderDto[orderId=1]
trailing garbage -> accepted: OrderDto[orderId=1]
unknown property -> rejected: UnrecognizedPropertyException
@@ -0,0 +1,12 @@
jackson 2 class : com.fasterxml.jackson.databind.ObjectMapper
jackson 3 class : tools.jackson.databind.json.JsonMapper
jackson 2 output: {"booking_id":1,"travel_date":"2026-09-15"}
jackson 3 output: {"booking_id":1,"travel_date":"2026-09-15"}
wire-compatible : true
3 reads 2's JSON: Booking[id=1, travelDate=2026-09-15]
2 reads 3's JSON: Booking[id=1, travelDate=2026-09-15]
annotation from : jackson-annotations-2.22.jar
<- one jackson-annotations jar, used by both majors
@@ -0,0 +1,14 @@
plain record identical
nested list identical
map identical
java.time identical
Optional present identical
Optional empty identical
NON_NULL identical
@JsonProperty identical
@JsonFormat identical
nulls and empties identical
cases : 10
mismatches: 0
Wire format is identical across both majors for these cases.