Migrate from Jackson 2.x to Jackson 3 (tools.jackson) (#430)#431
Conversation
|
Resolves Dependabot alert #7 (CVE-2026-54515 / GHSA-5jmj-h7xm-6q6v, The default branch's This PR removes the legacy Merging this PR therefore clears alert #7. (Real-world exposure was already negligible: JSONata4Java parses JSON into a tree via |
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
…cedure.txt (#430) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
Move the codebase from com.fasterxml.jackson 2.x to tools.jackson 3.2.0. - pom.xml: use tools.jackson.core:jackson-databind and tools.jackson.dataformat:jackson-dataformat-xml 3.2.0; remove the Jackson 2.x databind and dataformat-xml deps (woodstox-core retained); bump project version 2.6.4 -> 3.0.0. - Package/class/method renames across main and test sources: com.fasterxml.jackson.* -> tools.jackson.*, TextNode -> StringNode, JsonFactory -> tools.jackson.core.json.JsonFactory, JsonProcessingException -> JacksonException, JsonMappingException -> DatabindException, immutable mapper builders. Behavior-preserving fixes for Jackson 3 default/API changes (no test assertion or expected value was changed): - MatchFunction/ReplaceFunction: guard the pattern emptiness checks so a POJONode-wrapped RegularExpression never reaches the now-throwing asText(); logic is identical to Jackson 2. - ArrayUtils.compare: pass "" default to asText() so container operands coerce to "" as they did under Jackson 2 instead of throwing. - AgnosticTestSuite: normalize whole-number doubles with (long) d, replicating Jackson 2's silent narrowing (Jackson 3's asLong() throws on out-of-long-range values). - Utils test mapper: disable FAIL_ON_TRAILING_TOKENS to restore the Jackson 2 default so existing test inputs parse identically. - catch (IOException) -> catch (JacksonException) where Jackson 3 methods no longer throw checked IOException. - README and launch scripts (tester.sh, testerui.sh, testerui.cmd): version 2.6.4 -> 3.0.0. Verified: mvn clean test green (1223 tests, 0 failures, 93 skipped); mvn package builds JSONata4Java-3.0.0.jar with an OSGi Import-Package header referencing only tools.jackson.* [3.2,4); Tester CLI evaluation and XML round-trip smoke-tested. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
- Add a "Retained Jackson 2 behaviors (as-built)" section to the design
spec listing each compatibility decision (container asText(""),
POJONode emptiness guards, (long) d narrowing, FAIL_ON_TRAILING_TOKENS,
unchecked-exception catches), plus the pre-existing Tester EOF NPE and
the acceptable transitive jackson-annotations dependency.
- Add explanatory comments at the MatchFunction/ReplaceFunction guard
sites so the isTextual()-guarded emptiness checks are self-documenting.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: wnm3 <wnm3@us.ibm.com>
…shes (#433) Jackson 3 makes asInt()/asLong()/textValue()/asBoolean() fail-fast: they throw JsonNodeException for out-of-range or wrong-type nodes where Jackson 2 silently narrowed/coerced. Several unchanged call sites therefore flipped from "return a value" to "crash with a raw Jackson exception". Fix them to use the widest-safe representation (BigInteger/double) or a controlled JSONata error, matching jsonata.org 2.2.1 where known. #433 numeric coercion: - ExpressionsVisitor.isWholeNumber(JsonNode): use the double overload instead of asInt()==asDouble() (threw for integral doubles > int range, e.g. 1e19). - Array index: only select when canConvertToInt(); out-of-int-range indices are out of bounds and select nothing (e.g. ["a","b"][3000000000] -> undefined). - Range visitSeq: compute bounds and size with BigInteger, raising the controlled "sequence too big" error for [1..1e19]/[1..3000000000] (also fixes a latent int count overflow). - Unary minus: negate an out-of-long-range BigIntegerNode exactly. - Equality (=) and ordering (< > <= >=): compare integral operands via exact bigIntegerValue(), hardening the same crash class on BigInteger operands. - SumFunction: oversized integral elements fall back to the double-sum path. - FromMillis/FromMillisZoned: convert an out-of-range magnitude to a controlled "Number out of range" error while preserving fractional-millis truncation. - FormatBase: use the full long value + Long.toString instead of a 32-bit int ($formatBase(5890840712243076) -> "5890840712243076", was "1008002948"). Related migration compatibility fixes swept in: - JoinFunction (#434): every element must be a string; error on any non-string (including nested arrays) instead of flattening, matching the reference and avoiding textValue() throwing. - BooleanUtils: return false for a BinaryNode (JSON/reference has no binary type; Jackson 3's no-arg asBoolean() throws) consistent with prior behavior. - Ordering operators: array/object operands raise "must evaluate to numeric or string values" rather than returning null. Adds BasicExpressionsTests.testOutOfRangeNumericCoercion documenting the fixed behavior. Full suite: 1223 run, 0 failures, 0 errors, 93 skipped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
- Export com.api.jsonata4java.expressions.regex so bnd no longer flags it as a private reference leaked through the public API of the com.api.jsonata4java and com.api.jsonata4java.expressions exports. - Remove empty <additionalClasspathElements/> from maven-compiler-plugin (not a valid parameter for that plugin). - Remove <excludes> from maven-assembly-plugin single goal (not a valid parameter; exclusions belong in an assembly descriptor). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
Record the pom.xml build-warning fixes (bnd private-reference exports, invalid maven-compiler-plugin/maven-assembly-plugin parameters) and note that the gpg.passphrase deprecation originates from local settings.xml, not the project pom. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: wnm3 <wnm3@us.ibm.com>
Summary
Migrates JSONata4Java from
com.fasterxml.jackson2.x totools.jackson3.2.0 and cuts the major version to3.0.0. Closes #430.pom.xml): switch totools.jackson.core:jackson-databindandtools.jackson.dataformat:jackson-dataformat-xml3.2.0; remove the Jackson 2.xjackson-databindandjackson-dataformat-xmlblocks (woodstox-coreretained); bump project version2.6.4→3.0.0.com.fasterxml.jackson.*→tools.jackson.*,TextNode→StringNode,JsonFactory→tools.jackson.core.json.JsonFactory,JsonProcessingException→JacksonException,JsonMappingException→DatabindException, immutableJsonMapper/XmlMapperbuilders.README.md(×3) and the launch scriptstester.sh,testerui.sh,testerui.cmd.Behavior-preserving fixes for Jackson 3 default/API changes
No test assertion or expected value was changed — every fix restores the Jackson 2 behavior at its source:
MatchFunction/ReplaceFunction: guard the pattern emptiness checks so aPOJONode-wrappedRegularExpressionnever reaches the now-throwingasText(); the boolean logic is identical to Jackson 2.ArrayUtils.compare: pass""as theasText()default so container operands coerce to""(Jackson 2 behavior) instead of throwing.AgnosticTestSuite: normalize whole-number doubles with(long) d, replicating Jackson 2's silent narrowing (Jackson 3'sasLong()throws on out-of-long-range values).Utilstest mapper: disableFAIL_ON_TRAILING_TOKENSto restore the Jackson 2 default so existing test inputs parse identically.catch (IOException)→catch (JacksonException)where Jackson 3 methods no longer throw checkedIOException.Documentation
docs/specs/Jackson-3-Migration-Design.mdrecording each compatibility decision above (with how to reverse it if the project later adopts the stricter Jackson 3 semantics), plus the pre-existingTesterEOF NPE, the intentionally-tolerated"[\"h11\", \"h21\"]]"trailing-]test-data typo, and the acceptable transitivejackson-annotationsdependency.MatchFunction/ReplaceFunctionguard sites so theisTextual()-guarded emptiness checks are self-documenting.Maven build-warning cleanup (unrelated to Jackson)
Fixed three pre-existing
pom.xmlwarnings that appeared on every build:com.api.jsonata4java.expressions.regextoExport-Package— the exportedcom.api.jsonata4java/com.api.jsonata4java.expressionspackages exposeregextypes (RegexEngine,RegexPattern, …) in their public API, so that sub-package must be exported too.additionalClasspathElementsunknown (×2): removed the empty element frommaven-compiler-plugin(not a valid parameter).excludesunknown: removed from themaven-assembly-pluginsinglegoal (not a valid parameter; silently ignored — no effect on the produced jar).A separate
gpg.passphrasedeprecation warning originates from the developer’s local~/.m2/settings.xml, not this repo, and is resolved locally viagpg-agent.Verification
mvn clean test→ BUILD SUCCESS, 1223 tests, 0 failures, 93 skipped.mvn package→ buildsJSONata4Java-3.0.0.jar; OSGiImport-Packageheader references onlytools.jackson.* [3.2,4)(nocom.fasterxml.jackson.*).dependency:treeshows onlytools.jackson.*:3.2.0plus the acceptable transitivejackson-annotations.$sort([3,1,2])→[1,2,3]); XML round-trip smoke-tested viaXmlMapper.builder().Notes
TesterREPLNullPointerExceptionon stdin EOF atTester.java:156was left as-is (now recorded in the design spec's known-items section).🤖 Generated with Claude Code