Skip to content

Add Jackson 3 support as org.msgpack.jackson3:jackson-dataformat-msgpack - #1012

Open
xerial wants to merge 9 commits into
mainfrom
jackson3-migration
Open

Add Jackson 3 support as org.msgpack.jackson3:jackson-dataformat-msgpack#1012
xerial wants to merge 9 commits into
mainfrom
jackson3-migration

Conversation

@xerial

@xerial xerial commented Jul 28, 2026

Copy link
Copy Markdown
Member

Summary

This PR builds on #987 (thanks @komamitsu — all the Jackson 3 port code here is from that PR) and adds Jackson 3 support as a new artifact, keeping the existing Jackson 2 artifact untouched.

Following the review discussion (JLBP-6), the Maven coordinates and the Java package are renamed together, mirroring Jackson's own 2→3 groupId change (com.fasterxml.jackson.dataformattools.jackson.dataformat):

Module Jackson groupId artifactId Java package Requirements
msgpack-jackson 2.x org.msgpack jackson-dataformat-msgpack org.msgpack.jackson.dataformat Java 8+
msgpack-jackson3 3.x org.msgpack.jackson3 jackson-dataformat-msgpack org.msgpack.jackson3.dataformat Java 17+
  • Jackson 2 users need no changes: coordinates, package, and code are identical to the current 0.9.x line (JLBP-6 Case 1 for existing users). The module is maintenance-mode: Jackson 2.x bumps and bug fixes only.
  • Jackson 3 is a new artifact under the org.msgpack.jackson3 groupId with a new Java package (JLBP-6 Case 4: Maven ID and Java package renamed together). No two artifacts ever share fully-qualified class names, so both can coexist on one classpath for incremental Jackson 2→3 migration, and dependency resolution can never silently swap one for the other.
  • No 1.0.0 version bump is needed; the 0.9.x line continues.
  • CI: JDK 8/11 lanes test msgpack-core + msgpack-jackson (Jackson 2); JDK 17+ lanes test everything. Release publishes core/jackson (Jackson 2) with JDK 8 and msgpack-jackson3 with JDK 17.
  • sbt note: both subprojects share the artifactId jackson-dataformat-msgpack, so the Jackson 3 project overrides outputPath to keep sbt 2 build output directories from overlapping.

Pre-existing test issues found and fixed along the way

  1. The Jackson 2 module's JUnit 5 tests have been silently skipped on main: sbt has no Jupiter test interface, so ./sbt msgpack-jackson/test detects 0 tests and CI passes vacuously. Added sbt-jupiter-interface so they actually run (77 tests).
  2. MessagePackDataformatTestBase used JUnit 4 @Before/@After on JUnit 5 tests, so setup never ran → converted to @BeforeEach/@AfterEach.
  3. With the tests running again, one real regression surfaced: Fix Jackson deprecation warnings in MessagePackFactory #903 replaced a deprecated JsonLocation constructor in MessagePackParser and silently dropped the byte offset reported via getColumnNr(). Restored using the non-deprecated 5-arg constructor, matching the Jackson 3 port's behavior (byte offset as columnNr).

Test results

  • msgpack-core: 193 passed
  • msgpack-jackson (Jackson 2): 77 passed (previously 0 executed)
  • msgpack-jackson3 (Jackson 3): 123 passed
  • checkstyle and scalafmt clean

Closes #933. Supersedes #987 (includes all of its commits).

🤖 Generated with Claude Code

https://claude.ai/code/session_014ZZUaHusAjVx6SNu4sA42s

komamitsu and others added 7 commits May 31, 2026 23:10
Address PR #987 feedback asking for a clear artifact-name mapping
between jackson-dataformat-msgpack (Jackson 2) and
jackson-dataformat-msgpack-jackson3 (Jackson 3) to reduce upgrade
confusion.
main migrated the build to sbt 2 (feb87ef) without sbt-jmh, since
sbt-jmh 0.4.7 has no sbt-2-compatible artifact. This branch's
msgpack-jackson3 JMH benchmarks depend on sbt-jmh, so after merging
main the plugin fails to resolve. 0.4.8 publishes an sbt_2_3 build.
…3 to msgpack-jackson

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ZZUaHusAjVx6SNu4sA42s
…format-msgpack

- msgpack-jackson now hosts the Jackson 3.x integration (artifact
  jackson-dataformat-msgpack, package org.msgpack.jackson3.dataformat,
  Java 17+)
- msgpack-jackson2 hosts the Jackson 2.x integration in maintenance mode
  (artifact jackson2-dataformat-msgpack, package org.msgpack.jackson.dataformat
  unchanged, Java 8+)
- Distinct packages and artifactIds let both integrations coexist on one
  classpath for incremental migration
- Add sbt-jupiter-interface so the Jackson 2 module's JUnit 5 tests actually
  run; they had been silently skipped (0 tests detected) on main
- Fix MessagePackDataformatTestBase lifecycle annotations (JUnit 4 @Before/
  @after on JUnit 5 tests meant setup never ran)
- Restore byte-offset-as-columnNr in Jackson 2 MessagePackParser locations,
  regressed unnoticed in #903 when the deprecated JsonLocation constructor
  was replaced

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ZZUaHusAjVx6SNu4sA42s
0.17+ upgrades to JUnit 6, which requires Java 17; the JDK 8 CI lane failed
compiling msgpack-jackson2 tests against junit-jupiter-api 6.0.3 (class file
version 61). 0.15.2 stays on JUnit 5.14, and the module's explicit
junit-jupiter 5.14.4 dependency wins resolution. Verified by forking the
tests onto a real JDK 8.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ZZUaHusAjVx6SNu4sA42s
@komamitsu

Copy link
Copy Markdown
Member

@xerial Thanks for building on the PR. I understand the goal of giving Jackson 3 the unqualified jackson-dataformat-msgpack artifact ID, but I have three concerns.

  1. jackson2-dataformat-msgpack and jackson-dataformat-msgpack:0.9.x publish classes with the same fully qualified names. Maven and Gradle treat them as unrelated artifacts, so both JARs can appear on the classpath. This is a realistic case because fluency-fluentd:2.7.4 still has a runtime dependency on jackson-dataformat-msgpack:0.9.11.

    Whichever org.msgpack.jackson.dataformat.MessagePackFactory is found first is loaded. If jackson2-dataformat-msgpack later adds a method, for example a new option accompanying a bug fix, an application could compile against it and then fail with NoSuchMethodError because the 0.9.x class was loaded. Even without any API change, a bug fix could be silently ignored for the same reason.

    This is JLBP-6 Case 2, marked "NEVER DO THIS":

    https://jlbp.dev/JLBP-6

  2. jackson-dataformat-msgpack changes from Jackson 2 with org.msgpack.jackson.dataformat in 0.9.x to Jackson 3 with org.msgpack.jackson3.dataformat in 1.0.0.

    Because both versions have the same Maven ID, only one can remain after dependency resolution. An application directly using 1.0.0 with Fluency will not retain Fluency's 0.9.11 dependency. Fluency's compiled code instantiates org.msgpack.jackson.dataformat.MessagePackFactory, which is absent from 1.0.0, causing NoClassDefFoundError at runtime. Its runtime-scoped dependency means ordinary application compilation will not detect this.

    This is JLBP-6 Case 3. The issue is not simply that 1.0.0 contains breaking changes, but that the Jackson 2 and Jackson 3 packages cannot coexist under the same Maven ID.

  3. jackson2-dataformat-msgpack does not follow the established jackson-dataformat-* naming pattern.

Could we instead give Jackson 3 a new group ID?

groupId artifactId package
Jackson 3 org.msgpack.jackson3 jackson-dataformat-msgpack org.msgpack.jackson3.dataformat
Jackson 2 org.msgpack jackson-dataformat-msgpack org.msgpack.jackson.dataformat

This is JLBP-6 Case 4: the Maven ID and Java package are renamed together. Existing Jackson 2 users do not need to change coordinates, both modules keep the jackson-dataformat-* name, and the two can coexist.

Jackson used a similar structure for its XML module:

  • Jackson 2: com.fasterxml.jackson.dataformat:jackson-dataformat-xml
  • Jackson 3: tools.jackson.dataformat:jackson-dataformat-xml

Would this structure work here?

@xerial

xerial commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

Good catch. We need to add a new group ID to fully isolate modules. In that sense, a 1.0.0 version bump is unnecessary. A tricky part is that users need to specify a different group ID for msgpack-core and jackson3, but jackson3 is a new module, so this group naming should be acceptable.

Restructure the module layout per PR review feedback (JLBP-6): instead of
renaming the Jackson 2 artifact to jackson2-dataformat-msgpack and giving
Jackson 3 the unqualified jackson-dataformat-msgpack artifactId, rename the
Maven coordinates and the Java package together:

- Jackson 2 (msgpack-jackson): keeps org.msgpack:jackson-dataformat-msgpack
  and the org.msgpack.jackson.dataformat package, exactly as 0.9.x. Existing
  users need no changes. Maintenance mode: Jackson 2.x bumps and bug fixes only.
- Jackson 3 (msgpack-jackson3): published as
  org.msgpack.jackson3:jackson-dataformat-msgpack with the
  org.msgpack.jackson3.dataformat package, mirroring Jackson's own 2->3
  groupId rename (com.fasterxml.jackson.dataformat -> tools.jackson.dataformat).

Because the two artifacts share the same fully-qualified class names in
neither direction, they can coexist on one classpath, and dependency
resolution can never silently replace the Jackson 2 classes with Jackson 3
ones (or vice versa). The 1.0.0 version bump is no longer needed.

Both sbt subprojects now share the module name jackson-dataformat-msgpack,
so the Jackson 3 project overrides outputPath to keep sbt 2 build output
directories from overlapping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4Sp7Q2urgnYfuNXK2fVFm
@xerial xerial changed the title Migrate to Jackson 3 as jackson-dataformat-msgpack for 1.0.0; add jackson2-dataformat-msgpack Add Jackson 3 support as org.msgpack.jackson3:jackson-dataformat-msgpack Aug 10, 2026
@xerial

xerial commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

Restructured the PR as discussed (98e90f5):

groupId artifactId package
Jackson 3 org.msgpack.jackson3 jackson-dataformat-msgpack org.msgpack.jackson3.dataformat
Jackson 2 org.msgpack jackson-dataformat-msgpack org.msgpack.jackson.dataformat (unchanged)

The Jackson 2 module is back at msgpack-jackson/ with its original coordinates and code — existing 0.9.x users need no changes, and there is no jackson2-dataformat-msgpack artifact anymore. Jackson 3 lives in msgpack-jackson3/ as a new artifact (JLBP-6 Case 4: Maven ID and Java package renamed together), so both can coexist on one classpath. The 1.0.0 version bump is dropped; the 0.9.x line continues. PR description updated accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Jackson 3 support

2 participants