Skip to content

Migrate to Jackson 3 as jackson-dataformat-msgpack for 1.0.0; add jackson2-dataformat-msgpack - #1012

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

Migrate to Jackson 3 as jackson-dataformat-msgpack for 1.0.0; add jackson2-dataformat-msgpack#1012
xerial wants to merge 8 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 restructures the modules for a 1.0.0 release, as proposed in #987 (comment):

Module Artifact Jackson Java package Requirements
msgpack-jackson jackson-dataformat-msgpack (1.x) 3.x org.msgpack.jackson3.dataformat Java 17+
msgpack-jackson2 jackson2-dataformat-msgpack 2.x org.msgpack.jackson.dataformat (unchanged) Java 8+
  • The unmarked artifact jackson-dataformat-msgpack targets Jackson 3.x from 1.0.0 onward; 0.9.x remains the Jackson 2.x line for users who stay put.
  • The Jackson 2.x code moves to jackson2-dataformat-msgpack unchanged (same package), so migrating from 0.9.x only requires changing the artifactId. The module is maintenance-mode: Jackson 2.x bumps and bug fixes only.
  • Distinct artifactIds and packages mean both artifacts can coexist on one classpath for incremental Jackson 2→3 migration.
  • CI: JDK 8/11 lanes test msgpack-core + msgpack-jackson2 only; JDK 17+ lanes test everything. Release publishes core/jackson2 with JDK 8 and the Jackson 3 module with JDK 17.

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 3): 123 passed
  • msgpack-jackson2: 77 passed (previously 0 executed)
  • 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?

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