Skip to content
17 changes: 15 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
- 'project/build.properties'
- 'msgpack-core/**'
- 'msgpack-jackson/**'
- 'msgpack-jackson2/**'
docs:
- '**.md'
- '**.txt'
Expand Down Expand Up @@ -81,8 +82,20 @@ jobs:
- name: Test
env:
TEST_JAVA_HOME: ${{ steps.target-jdk.outputs.path }}
run: ./sbt test
run: |
# msgpack-jackson (Jackson 3) requires JDK 17+; older lanes test the
# Java 8 compatible modules only
if [[ ${{ matrix.java }} -lt 17 ]]; then
./sbt msgpack-core/test msgpack-jackson2/test
else
./sbt test
fi
- name: Universal Buffer Test
env:
TEST_JAVA_HOME: ${{ steps.target-jdk.outputs.path }}
run: ./sbt test -J-Dmsgpack.universal-buffer=true
run: |
if [[ ${{ matrix.java }} -lt 17 ]]; then
./sbt msgpack-core/test msgpack-jackson2/test -J-Dmsgpack.universal-buffer=true
else
./sbt test -J-Dmsgpack.universal-buffer=true
fi
12 changes: 11 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,17 @@ jobs:
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
TEST_JAVA_HOME: ${{ steps.jdk8.outputs.path }}
run: |
./sbt publishSigned
./sbt msgpack-core/publishSigned msgpack-jackson2/publishSigned
# msgpack-jackson (Jackson 3) requires JDK 17+
- uses: actions/setup-java@v5
with:
java-version: 17
distribution: temurin
- name: Build bundle for msgpack-jackson (Jackson 3)
env:
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
run: |
./sbt msgpack-jackson/publishSigned
- name: Release to Sonatype
env:
SONATYPE_USERNAME: '${{ secrets.SONATYPE_USERNAME }}'
Expand Down
10 changes: 6 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

MessagePack-Java is a binary serialization library that provides a fast and compact alternative to JSON. The project consists of two main modules:
- **msgpack-core**: Standalone MessagePack implementation with no external dependencies
- **msgpack-jackson**: Jackson integration for object mapping capabilities
- **msgpack-jackson**: Jackson 3.x integration for object mapping capabilities (artifact `jackson-dataformat-msgpack`, Java 17+)
- **msgpack-jackson2**: Jackson 2.x integration in maintenance mode (artifact `jackson2-dataformat-msgpack`, Java 8+)

## Essential Development Commands

Expand Down Expand Up @@ -49,7 +50,8 @@ The main entry point is the `MessagePack` factory class which creates:

Key locations:
- Core interfaces: `msgpack-core/src/main/java/org/msgpack/core/`
- Jackson integration: `msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/`
- Jackson 3 integration: `msgpack-jackson/src/main/java/org/msgpack/jackson3/dataformat/`
- Jackson 2 integration: `msgpack-jackson2/src/main/java/org/msgpack/jackson/dataformat/`

### Buffer Management System
MessagePack uses an efficient buffer abstraction layer:
Expand All @@ -68,8 +70,8 @@ The msgpack-jackson module provides:
### Testing Structure
- **msgpack-core tests**: Written in Scala (always use the latest Scala 3 version) using AirSpec framework
- Location: `msgpack-core/src/test/scala/`
- **msgpack-jackson tests**: Written in Java using JUnit
- Location: `msgpack-jackson/src/test/java/`
- **msgpack-jackson / msgpack-jackson2 tests**: Written in Java using JUnit
- Location: `msgpack-jackson/src/test/java/`, `msgpack-jackson2/src/test/java/`

## Important JVM Options

Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,16 @@ For using DirectByteBuffer (off-heap memory access methods) in JDK17, you need t

### Integration with Jackson ObjectMapper (jackson-databind)

msgpack-java supports serialization and deserialization of Java objects through [jackson-databind](https://github.com/FasterXML/jackson-databind).
For details, see [msgpack-jackson/README.md](https://github.com/msgpack/msgpack-java/blob/develop/msgpack-jackson/README.md). The template-based serialization mechanism used in v06 is deprecated.
msgpack-java supports serialization and deserialization of Java objects through [jackson-databind](https://github.com/FasterXML/jackson-databind). The template-based serialization mechanism used in v06 is deprecated.

Two artifacts are published depending on which Jackson major version your project uses:

| Jackson version | Artifact | Requirements |
| --- | --- | --- |
| Jackson 3.x | [`jackson-dataformat-msgpack`](https://github.com/msgpack/msgpack-java/blob/main/msgpack-jackson/README.md) (1.x) | Java 17+ |
| Jackson 2.x | [`jackson2-dataformat-msgpack`](https://github.com/msgpack/msgpack-java/blob/main/msgpack-jackson2/README.md) (maintenance mode) | Java 8+ |

Since msgpack-java 1.0.0, `jackson-dataformat-msgpack` targets Jackson 3.x. If your project still depends on Jackson 2.x, either stay on `jackson-dataformat-msgpack` 0.9.x or switch to `jackson2-dataformat-msgpack` to keep receiving msgpack-core updates (only the artifactId changes; the Java package is the same). See each module's README for install instructions and usage details.

- [Release Notes](https://github.com/msgpack/msgpack-java/blob/develop/RELEASE_NOTES.md)

Expand Down Expand Up @@ -145,5 +153,6 @@ If some sporadic error happens (e.g., Sonatype timeout), rerun `sonaRelease` aga

```
msgpack-core # Contains packer/unpacker implementation that never uses third-party libraries
msgpack-jackson # Contains jackson-dataformat-java implementation
msgpack-jackson # jackson-dataformat-msgpack: Jackson 3.x integration (Java 17+)
msgpack-jackson2 # jackson2-dataformat-msgpack: Jackson 2.x integration (maintenance mode)
```
54 changes: 47 additions & 7 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,19 @@ val buildSettings = Seq[Setting[?]](
Test / compile := Def.uncached((Test / compile).dependsOn(Test / jcheckStyle).value)
)

val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.14.4" % "test"
val junitVintage = "org.junit.vintage" % "junit-vintage-engine" % "5.14.4" % "test"
val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.14.4" % "test"
val junitVintage = "org.junit.vintage" % "junit-vintage-engine" % "5.14.4" % "test"
val junitInterface = "com.github.sbt" % "junit-interface" % "0.13.3" % "test"

// Project settings
val isJava17Plus: Boolean = {
val v = sys.props.getOrElse("java.specification.version", "1.8")
// getOrElse(false): non-numeric versions (e.g. early-access "17-ea") fail safe
// by not compiling the Jackson 3 module (msgpack-jackson) rather than making an
// optimistic guess.
if (v.startsWith("1.")) false else scala.util.Try(v.toInt >= 17).getOrElse(false)
}

lazy val root = Project(id = "msgpack-java", base = file("."))
.settings(
buildSettings,
Expand All @@ -127,7 +136,10 @@ lazy val root = Project(id = "msgpack-java", base = file("."))
publish := {},
publishLocal := {}
)
.aggregate(msgpackCore, msgpackJackson)
.aggregate(
Seq[ProjectReference](msgpackCore, msgpackJackson2) ++
(if (isJava17Plus) Seq[ProjectReference](msgpackJackson) else Nil): _*
)

lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
.enablePlugins(SbtOsgi)
Expand Down Expand Up @@ -170,21 +182,49 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
)
)

lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-jackson"))
// Maintenance-mode module for Jackson 2.x users: Jackson 2.x dependency bumps and
// bug fixes only. To be dropped in a future major release when Jackson 2 usage fades.
lazy val msgpackJackson2 = Project(id = "msgpack-jackson2", base = file("msgpack-jackson2"))
.enablePlugins(SbtOsgi)
.settings(
buildSettings,
name := "jackson-dataformat-msgpack",
description := "Jackson extension that adds support for MessagePack",
OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-jackson",
name := "jackson2-dataformat-msgpack",
description := "Jackson 2.x extension that adds support for MessagePack",
OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-jackson2",
OsgiKeys.exportPackage := Seq("org.msgpack.jackson", "org.msgpack.jackson.dataformat"),
libraryDependencies ++=
Seq(
"com.fasterxml.jackson.core" % "jackson-databind" % "2.22.1",
junitJupiter,
junitVintage,
"com.github.sbt.junit" % "jupiter-interface" % JupiterKeys.jupiterVersion.value % "test",
"org.apache.commons" % "commons-math3" % "3.6.1" % "test"
),
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v")
)
.dependsOn(msgpackCore)

lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-jackson"))
.enablePlugins(SbtOsgi, JmhPlugin)
.settings(
buildSettings,
name := "jackson-dataformat-msgpack",
description := "Jackson 3.x extension that adds support for MessagePack",
OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-jackson",
OsgiKeys.exportPackage := Seq("org.msgpack.jackson3", "org.msgpack.jackson3.dataformat"),
OsgiKeys.importPackage := Seq("!android.os", "!sun.*"),
Test / fork := true,
javacOptions := Seq("--release", "17"),
doc / javacOptions := Seq("--release", "17", "-Xdoclint:none"),
libraryDependencies ++=
Seq(
"tools.jackson.core" % "jackson-databind" % "3.1.2",
junitInterface
),
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v"),
Jmh / javaOptions ++= Seq(
"--add-opens=java.base/java.nio=ALL-UNNAMED",
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
)
)
.dependsOn(msgpackCore)
Loading
Loading