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:
4
docs/output/after-S01MapperConstruction.txt
Normal file
4
docs/output/after-S01MapperConstruction.txt
Normal file
@@ -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
|
||||
5
docs/output/after-S02ExceptionHierarchy.txt
Normal file
5
docs/output/after-S02ExceptionHierarchy.txt
Normal file
@@ -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
docs/output/after-S03CustomHandlers.txt
Normal file
3
docs/output/after-S03CustomHandlers.txt
Normal 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
|
||||
4
docs/output/after-S04ModulesAndRecords.txt
Normal file
4
docs/output/after-S04ModulesAndRecords.txt
Normal file
@@ -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
docs/output/after-S05DefaultTyping.txt
Normal file
7
docs/output/after-S05DefaultTyping.txt
Normal 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
|
||||
9
docs/output/after-S07DefaultsThatFlipped.txt
Normal file
9
docs/output/after-S07DefaultsThatFlipped.txt
Normal file
@@ -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]
|
||||
4
docs/output/before-S01MapperConstruction.txt
Normal file
4
docs/output/before-S01MapperConstruction.txt
Normal file
@@ -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
|
||||
3
docs/output/before-S02ExceptionHierarchy.txt
Normal file
3
docs/output/before-S02ExceptionHierarchy.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
JsonProcessingException extends IOException : true
|
||||
caught by catch (IOException) : JsonParseException
|
||||
writeValueAsString declares : [class com.fasterxml.jackson.core.JsonProcessingException]
|
||||
3
docs/output/before-S03CustomHandlers.txt
Normal file
3
docs/output/before-S03CustomHandlers.txt
Normal 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
|
||||
4
docs/output/before-S04ModulesAndRecords.txt
Normal file
4
docs/output/before-S04ModulesAndRecords.txt
Normal file
@@ -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
docs/output/before-S05DefaultTyping.txt
Normal file
3
docs/output/before-S05DefaultTyping.txt
Normal 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]
|
||||
9
docs/output/before-S07DefaultsThatFlipped.txt
Normal file
9
docs/output/before-S07DefaultsThatFlipped.txt
Normal file
@@ -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
|
||||
12
docs/output/coexistence-S06BothOnOneClasspath.txt
Normal file
12
docs/output/coexistence-S06BothOnOneClasspath.txt
Normal file
@@ -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
|
||||
14
docs/output/coexistence-S08WireFormatEquivalence.txt
Normal file
14
docs/output/coexistence-S08WireFormatEquivalence.txt
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user