Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
2ac3cbc
Add msgpack-jackson3 module for Jackson 3.x support
komamitsu May 16, 2026
d8c66c1
Remove javaHome hack and deduplicate javacOptions in msgpack-jackson3
komamitsu May 16, 2026
1f26be8
Clean up dead code and add OSGi import exclusions for msgpack-jackson3
komamitsu May 16, 2026
bbc4de9
Skip msgpack-jackson3 tests on Java < 17 in CI
komamitsu May 17, 2026
752ccdf
Fix bugs in msgpack-jackson3
komamitsu May 17, 2026
c33d896
Fix MessagePackFactory.snapshot() to return a copy instead of this
komamitsu May 17, 2026
ab62c4d
Add TSFBuilder support via MessagePackFactoryBuilder
komamitsu May 17, 2026
ffc69db
Fix offset bugs in MessagePackGenerator and document pre-existing issues
komamitsu May 17, 2026
0887616
Fix isClosed() always false and stale currentState after container close
komamitsu May 17, 2026
07da78b
Fix writeRaw(String, offset, len) to copy only the requested slice
komamitsu May 17, 2026
ec29bb0
Use non-deprecated createGenerator(ObjectWriteContext, OutputStream) …
komamitsu May 17, 2026
fa8f901
Use BigDecimal.compareTo instead of string comparison in packBigDecimal
komamitsu May 17, 2026
43f92f1
Fix streamWriteContext, parser ThreadLocal byte-array leak, Serialize…
komamitsu May 17, 2026
b087eb7
Mark build Java-version guard as fixed in preexisting-issues.md
komamitsu May 17, 2026
2e90092
Fix several bugs identified in PR review
komamitsu May 17, 2026
1605bf4
Simplify string handling for Java 9+ compact strings
komamitsu May 17, 2026
daefba9
Replace hand-rolled benchmarks with JMH for msgpack-jackson3
komamitsu May 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 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-jackson3/**'
docs:
- '**.md'
- '**.txt'
Expand Down Expand Up @@ -65,6 +66,16 @@ jobs:
key: ${{ runner.os }}-jdk${{ matrix.java }}-${{ hashFiles('**/*.sbt') }}
restore-keys: ${{ runner.os }}-jdk${{ matrix.java }}-
- name: Test
run: ./sbt test
run: |
if [[ ${{ matrix.java }} -lt 17 ]]; then
./sbt msgpack-core/test msgpack-jackson/test
else
./sbt test
fi
- name: Universal Buffer Test
run: ./sbt test -J-Dmsgpack.universal-buffer=true
run: |
if [[ ${{ matrix.java }} -lt 17 ]]; then
./sbt msgpack-core/test msgpack-jackson/test -J-Dmsgpack.universal-buffer=true
else
./sbt test -J-Dmsgpack.universal-buffer=true
fi
40 changes: 37 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,16 @@ val buildSettings = Seq[Setting[?]](
Test / compile := ((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")
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 @@ -108,7 +114,10 @@ lazy val root = Project(id = "msgpack-java", base = file("."))
publish := {},
publishLocal := {}
)
.aggregate(msgpackCore, msgpackJackson)
.aggregate(
Seq[ProjectReference](msgpackCore, msgpackJackson) ++
(if (isJava17Plus) Seq[ProjectReference](msgpackJackson3) else Nil): _*
)

lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
.enablePlugins(SbtOsgi)
Expand Down Expand Up @@ -170,3 +179,28 @@ lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-j
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v")
)
.dependsOn(msgpackCore)

lazy val msgpackJackson3 = Project(id = "msgpack-jackson3", base = file("msgpack-jackson3"))
.enablePlugins(SbtOsgi, JmhPlugin)
.settings(
buildSettings,
name := "jackson-dataformat-msgpack3",
description := "Jackson 3.x extension that adds support for MessagePack",
OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-jackson3",
OsgiKeys.exportPackage := Seq("org.msgpack.jackson", "org.msgpack.jackson.dataformat"),
OsgiKeys.importPackage := Seq("!android.os", "!sun.*"),
Test / fork := true,
javacOptions := Seq("-source", "17", "-target", "17"),
doc / javacOptions := Seq("-source", "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)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.msgpack.jackson.dataformat.benchmark;

import org.msgpack.jackson.dataformat.MessagePackFactory;
import org.msgpack.jackson.dataformat.MessagePackMapper;
import org.msgpack.jackson.dataformat.benchmark.model.MediaItem;
import org.msgpack.jackson.dataformat.benchmark.model.MediaItems;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;

@State(Scope.Thread)
public class BenchmarkState
{
public final ObjectMapper msgpackMapper = MessagePackMapper.builder(new MessagePackFactory()).build();
public final ObjectMapper jsonMapper = JsonMapper.builder().build();

public final byte[] msgpackBytes;
public final byte[] jsonBytes;

public BenchmarkState()
{
try {
MediaItem item = MediaItems.stdMediaItem();
msgpackBytes = msgpackMapper.writeValueAsBytes(item);
jsonBytes = jsonMapper.writeValueAsBytes(item);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.msgpack.jackson.dataformat.benchmark;

import org.msgpack.jackson.dataformat.benchmark.model.MediaItem;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Fork(value = 2, jvmArgsAppend = {
"--add-opens=java.base/java.nio=ALL-UNNAMED",
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
})
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
public class MsgpackReadBenchmark
{
private final BenchmarkState state = new BenchmarkState();

@Benchmark
public Object readPojoMsgpack() throws Exception
{
return state.msgpackMapper.readValue(state.msgpackBytes, MediaItem.class);
}

@Benchmark
public Object readPojoJson() throws Exception
{
return state.jsonMapper.readValue(state.jsonBytes, MediaItem.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.msgpack.jackson.dataformat.benchmark;

import org.msgpack.jackson.dataformat.benchmark.model.MediaItem;
import org.msgpack.jackson.dataformat.benchmark.model.MediaItems;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Fork(value = 2, jvmArgsAppend = {
"--add-opens=java.base/java.nio=ALL-UNNAMED",
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
})
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
public class MsgpackWriteBenchmark
{
private final BenchmarkState state = new BenchmarkState();
private final MediaItem item = MediaItems.stdMediaItem();

@Benchmark
public int writePojoMsgpack() throws Exception
{
NopOutputStream out = new NopOutputStream();
state.msgpackMapper.writeValue(out, item);
return out.size();
}

@Benchmark
public int writePojoJson() throws Exception
{
NopOutputStream out = new NopOutputStream();
state.jsonMapper.writeValue(out, item);
return out.size();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.msgpack.jackson.dataformat.benchmark;

import java.io.OutputStream;

public class NopOutputStream
extends OutputStream
{
private int size;

@Override
public void write(int b)
{
size++;
}

@Override
public void write(byte[] b, int off, int len)
{
size += len;
}

public int size()
{
return size;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.msgpack.jackson.dataformat.benchmark.model;

public class Image
{
public String uri;
public String title;
public int width;
public int height;
public Size size;

public Image() {}

public Image(String uri, String title, int width, int height, Size size)
{
this.uri = uri;
this.title = title;
this.width = width;
this.height = height;
this.size = size;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.msgpack.jackson.dataformat.benchmark.model;

import java.util.ArrayList;
import java.util.List;

public class MediaContent
{
public String uri;
public String title;
public int width;
public int height;
public String format;
public long duration;
public long size;
public int bitrate;
public List<String> persons;
public Player player;
public String copyright;

public MediaContent() {}

public void addPerson(String person)
{
if (persons == null) {
persons = new ArrayList<>();
}
persons.add(person);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.msgpack.jackson.dataformat.benchmark.model;

import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import java.util.ArrayList;
import java.util.List;

@JsonPropertyOrder({"content", "images"})
public class MediaItem
{
public MediaContent content;
public List<Image> images;

public MediaItem() {}

public MediaItem(MediaContent content)
{
this.content = content;
}

public void addImage(Image image)
{
if (images == null) {
images = new ArrayList<>();
}
images.add(image);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.msgpack.jackson.dataformat.benchmark.model;

public class MediaItems
{
private static final MediaItem STD_MEDIA_ITEM;

static {
MediaContent content = new MediaContent();
content.uri = "http://javaone.com/keynote.mpg";
content.title = "Javaone Keynote";
content.width = 640;
content.height = 480;
content.format = "video/mpg4";
content.duration = 18000000L;
content.size = 58982400L;
content.bitrate = 262144;
content.player = Player.JAVA;
content.copyright = "None";
content.addPerson("Bill Gates");
content.addPerson("Steve Jobs");

MediaItem item = new MediaItem(content);
item.addImage(new Image("http://javaone.com/keynote_large.jpg", "Javaone Keynote", 1024, 768, Size.LARGE));
item.addImage(new Image("http://javaone.com/keynote_small.jpg", "Javaone Keynote", 320, 240, Size.SMALL));

STD_MEDIA_ITEM = item;
}

public static MediaItem stdMediaItem()
{
return STD_MEDIA_ITEM;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.msgpack.jackson.dataformat.benchmark.model;

public enum Player
{
JAVA, FLASH
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.msgpack.jackson.dataformat.benchmark.model;

public enum Size
{
SMALL, LARGE
}
Loading
Loading