From ceffe074a9145f8f306af07fb8e21b0e0e6651d9 Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 8 Mar 2022 02:49:38 +0900 Subject: [PATCH 001/195] Keep consistent read size after closing MessageUnpacker (#621) --- .../java/org/msgpack/core/MessageUnpacker.java | 1 + .../org/msgpack/core/MessageUnpackerTest.scala | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index c59b742a..ff638b74 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -1735,6 +1735,7 @@ private int readNextLength32() public void close() throws IOException { + totalReadBytes += position; buffer = EMPTY_BUFFER; position = 0; in.close(); diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 720885c4..3ea5e911 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -254,6 +254,9 @@ class MessageUnpackerTest extends AirSpec with Benchmark { } count shouldBe 6 unpacker.getTotalReadBytes shouldBe arr.length + + unpacker.close() + unpacker.getTotalReadBytes shouldBe arr.length } } @@ -268,6 +271,9 @@ class MessageUnpackerTest extends AirSpec with Benchmark { skipCount shouldBe 2 unpacker.getTotalReadBytes shouldBe testData.length + + unpacker.close() + unpacker.getTotalReadBytes shouldBe testData.length } } @@ -322,6 +328,9 @@ class MessageUnpackerTest extends AirSpec with Benchmark { ib.result() shouldBe intSeq.toSeq unpacker.getTotalReadBytes shouldBe testData2.length + + unpacker.close() + unpacker.getTotalReadBytes shouldBe testData2.length } } @@ -352,6 +361,9 @@ class MessageUnpackerTest extends AirSpec with Benchmark { } count shouldBe numElems unpacker.getTotalReadBytes shouldBe data.length + + unpacker.close() + unpacker.getTotalReadBytes shouldBe data.length } } } @@ -869,6 +881,9 @@ class MessageUnpackerTest extends AirSpec with Benchmark { unpacker.unpackInt shouldBe 1 unpacker.getTotalReadBytes shouldBe arr.length + + unpacker.close() + unpacker.getTotalReadBytes shouldBe arr.length } } } From 3670c640a91e70266f2cb568ec2bb5ebf459d198 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Mar 2022 18:49:54 +0100 Subject: [PATCH 002/195] Update sbt to 1.5.8 (#615) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 71aac7fe..c456baca 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.5.6 +sbt.version=1.5.8 From ea5f407b851700fc400fb8c2b81dc81148eee168 Mon Sep 17 00:00:00 2001 From: zbuster05 <41530680+zbuster05@users.noreply.github.com> Date: Mon, 7 Mar 2022 09:50:44 -0800 Subject: [PATCH 003/195] Fixed examples relative link in README (#622) * Fixed examples relative link in README. On the message pack mirror of the readme, since this is relatively linked, it attempts to route to the location https://msgpack.org/msgpack/msgpack-java/blob/develop/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java which subsequently returns a 404. Statically linking the domain should fix this issue and look a lot more professional. * Fixed other instances --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c5af97cd..4035fdc4 100644 --- a/README.md +++ b/README.md @@ -40,14 +40,14 @@ dependencies { } ``` -- [Usage examples](msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java) +- [Usage examples](https://github.com/msgpack/msgpack-java/blob/develop/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java) ### 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](msgpack-jackson/README.md). The template-based serialization mechanism used in v06 is deprecated. +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. -- [Release Notes](RELEASE_NOTES.md) +- [Release Notes](https://github.com/msgpack/msgpack-java/blob/develop/RELEASE_NOTES.md) ## For MessagePack Developers [![Travis CI](https://travis-ci.org/msgpack/msgpack-java.svg?branch=v07-develop)](https://travis-ci.org/msgpack/msgpack-java) From 3442714f66e7c671598cc354ac140afe4bdd30c3 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Mar 2022 18:50:58 +0100 Subject: [PATCH 004/195] Update sbt-scalafmt to 2.4.6 (#616) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 1609ca90..59821f87 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.5") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") scalacOptions ++= Seq("-deprecation", "-feature") From a8f05e6b1336ae0decd14dd38ff4246c453f6b56 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Mar 2022 18:51:11 +0100 Subject: [PATCH 005/195] Update junit-interface to 0.13.3 (#617) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index b8c4b9d5..2b49fcbf 100644 --- a/build.sbt +++ b/build.sbt @@ -46,7 +46,7 @@ val buildSettings = Seq[Setting[_]]( Test / compile := ((Test / compile) dependsOn (Test / jcheckStyle)).value ) -val junitInterface = "com.github.sbt" % "junit-interface" % "0.13.2" % "test" +val junitInterface = "com.github.sbt" % "junit-interface" % "0.13.3" % "test" // Project settings lazy val root = Project(id = "msgpack-java", base = file(".")) From 14624bd413e826b8fc70f179ab4d7dc603155df0 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Mar 2022 18:51:33 +0100 Subject: [PATCH 006/195] Update airframe-json, airspec to 22.2.0 (#626) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 2b49fcbf..19d73c85 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "21.12.1" +val AIRFRAME_VERSION = "22.2.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 3272530d19a6f944b9f03a1ad3dc49ad2e34f0aa Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Mar 2022 18:53:19 +0100 Subject: [PATCH 007/195] Update akka-actor to 2.6.18 (#614) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 19d73c85..f17edd64 100644 --- a/build.sbt +++ b/build.sbt @@ -84,7 +84,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka - "com.typesafe.akka" %% "akka-actor" % "2.6.17" % "test", + "com.typesafe.akka" %% "akka-actor" % "2.6.18" % "test", "org.scala-lang.modules" %% "scala-collection-compat" % "2.6.0" % "test" ) ) From d0f47d4823c76d2e7aa5f9c43d5743777524df90 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 7 Mar 2022 10:22:41 -0800 Subject: [PATCH 008/195] 0.9.1 release notes --- RELEASE_NOTES.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4f00c472..a8e81de5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,26 @@ # Release Notes +## 0.9.1 + +Bug fixes and improvements: + +- Keep consistent read size after closing MessageUnpacker (#621) @okumin +- Fixed examples relative link in README (#622) @zbuster05 +- Add an ObjectMapper shorthand @cyberdelia (#620) +- Specify the bufferSize of the ArrayBufferOutput (#597) @szh + +Internal updates: + +- Update akka-actor to 2.6.18 (#614) @Scala Steward +- Update airframe-json, airspec to 22.2.0 (#626) @Scala Steward +- Update junit-interface to 0.13.3 (#617) @Scala Steward +- Update sbt-scalafmt to 2.4.6 (#616) @Scala Steward +- Upgrade sbt to 1.5.6 (#610) @Taro L. Saito +- Update scala-collection-compat to 2.6.0 (#604) @Scala Steward + +Known issues: +- Unpack method doesn't work in JDK17 https://github.com/msgpack/msgpack-java/issues/600 + ## 0.9.0 This version support reading and writing [Timestamp values](https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type). From 5adf9790f5c57e07d76f4c2b3ebdf07274798caa Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 11 Mar 2022 01:14:55 +0100 Subject: [PATCH 009/195] Update sbt to 1.6.2 (#630) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index c456baca..022b635b 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.5.8 +sbt.version=1.6.2 From 4d2acc775414250e7258a0ca926ed98a3e4316a8 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 25 May 2022 08:21:48 +0200 Subject: [PATCH 010/195] Update airframe-json, airspec to 22.5.0 (#643) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index f17edd64..da190027 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.2.0" +val AIRFRAME_VERSION = "22.5.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From f21c8867ff59dd80f1bbb7b6af1bb364e6aafac0 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 25 May 2022 08:21:57 +0200 Subject: [PATCH 011/195] Update sbt-sonatype to 3.9.13 (#644) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 59821f87..4b437b7c 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.13") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From af42f3f766b237098e1ebf6d13493edcf57c3cea Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 25 May 2022 08:22:27 +0200 Subject: [PATCH 012/195] Update scala-collection-compat to 2.7.0 (#632) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index da190027..f0ec7f96 100644 --- a/build.sbt +++ b/build.sbt @@ -85,7 +85,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.18" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.6.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" % "test" ) ) From 294c7cc2b63ab637a6a5afa42aeff05ffb11c2c6 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 25 May 2022 08:22:36 +0200 Subject: [PATCH 013/195] Update scalacheck to 1.16.0 (#636) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index f0ec7f96..5d01030e 100644 --- a/build.sbt +++ b/build.sbt @@ -80,7 +80,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.15.4" % "test", + "org.scalacheck" %% "scalacheck" % "1.16.0" % "test", // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka From b07e5f4f349d53a2244f1a02b32558a033326d37 Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Fri, 3 Jun 2022 13:24:38 -0700 Subject: [PATCH 014/195] Update airframe-json, airspec to 22.6.1 (#649) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5d01030e..5d29df7b 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.5.0" +val AIRFRAME_VERSION = "22.6.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 7ba38b10ca56236d64c9f1718df69895e0a8c410 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 3 Jun 2022 22:24:56 +0200 Subject: [PATCH 015/195] Update akka-actor to 2.6.19 (#631) * Update akka-actor to 2.6.19 * Revert commit(s) 8decc5c2 * Update akka-actor to 2.6.19 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5d29df7b..25bc87bb 100644 --- a/build.sbt +++ b/build.sbt @@ -84,7 +84,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka - "com.typesafe.akka" %% "akka-actor" % "2.6.18" % "test", + "com.typesafe.akka" %% "akka-actor" % "2.6.19" % "test", "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" % "test" ) ) From 4469bf69fa3d62494441ec10146d3445367b3c39 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 5 Jun 2022 21:31:33 +0900 Subject: [PATCH 016/195] Use jackson-databind 2.13.3 for CVE-2020-36518 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 25bc87bb..990aed1b 100644 --- a/build.sbt +++ b/build.sbt @@ -102,7 +102,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.10.5.1", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.13.3", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From dadb7551ae84aa0698525d9d1e2fb9857efbf13d Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Tue, 7 Jun 2022 22:35:00 +0900 Subject: [PATCH 017/195] Fix testComplexTypeKey() --- .../jackson/dataformat/MessagePackGeneratorTest.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index e2c202bc..9c66fa05 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -663,7 +663,9 @@ public void testNonStringKey() ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); if (mapHolder instanceof NonStringKeyMapHolderWithoutAnnotation) { - objectMapper.setSerializerFactory(new MessagePackSerializerFactory()); + SimpleModule mod = new SimpleModule("test"); + mod.addKeySerializer(TinyPojo.class, new MessagePackKeySerializer()); + objectMapper.registerModule(mod); } byte[] bytes = objectMapper.writeValueAsBytes(mapHolder); @@ -709,7 +711,9 @@ public void testComplexTypeKey() map.put(pojo, 42); ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); - objectMapper.setSerializerFactory(new MessagePackSerializerFactory()); + SimpleModule mod = new SimpleModule("test"); + mod.addKeySerializer(TinyPojo.class, new MessagePackKeySerializer()); + objectMapper.registerModule(mod); byte[] bytes = objectMapper.writeValueAsBytes(map); MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes); @@ -731,7 +735,9 @@ public void testComplexTypeKeyWithV06Format() ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); objectMapper.setAnnotationIntrospector(new JsonArrayFormat()); - objectMapper.setSerializerFactory(new MessagePackSerializerFactory()); + SimpleModule mod = new SimpleModule("test"); + mod.addKeySerializer(TinyPojo.class, new MessagePackKeySerializer()); + objectMapper.registerModule(mod); byte[] bytes = objectMapper.writeValueAsBytes(map); MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes); From 61c6910bc070479d8bd537011abf4812d869ada5 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Wed, 8 Jun 2022 23:51:43 +0900 Subject: [PATCH 018/195] Fix test --- .../msgpack/jackson/dataformat/MessagePackGeneratorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 9c66fa05..931a33f5 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -664,7 +664,7 @@ public void testNonStringKey() ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); if (mapHolder instanceof NonStringKeyMapHolderWithoutAnnotation) { SimpleModule mod = new SimpleModule("test"); - mod.addKeySerializer(TinyPojo.class, new MessagePackKeySerializer()); + mod.addKeySerializer(Object.class, new MessagePackKeySerializer()); objectMapper.registerModule(mod); } From 4c5d180dc29efb81f305f65e7299072d5c33a5d5 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 12 Jun 2022 17:21:23 +0900 Subject: [PATCH 019/195] Add how to internally represent BigDecimal as str to the doc --- msgpack-jackson/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index f1710ff2..d3c77986 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -224,6 +224,22 @@ When you want to use non-String value as a key of Map, use `MessagePackKeySerial System.out.println(deserialized); // => {42=Hello} ``` +### Serialize and deserialize BigDecimal as str type internally in MessagePack format + +`jackson-dataformat-msgpack` represents BigDecimal values as float type in MessagePack format by default. When you want to handle BigDeciaml values as str type with arbitrary precision in MessagePack format, you can use `com.fasterxml.jackson.databind.cfg.MutableConfigOverride#setFormat` like this: + +```java + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); + mapper.configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); + + Pojo obj = new Pojo(); + obj.value = new BigDecimal("1234567890.98765432100"); + + byte[] converted = mapper.writeValueAsBytes(obj); + + System.out.println(mapper.readValue(converted, Pojo.class)); // => Pojo{value=1234567890.98765432100} +``` + ### Deserialize extension types with ExtensionTypeCustomDeserializers `ExtensionTypeCustomDeserializers` helps you to deserialize extension types easily. From b7ba3973c8e96cd739d73331066b4496bc2c3ee1 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 18 Jun 2022 14:19:48 +0900 Subject: [PATCH 020/195] Update RELEASE_NOTES for 0.9.2 --- RELEASE_NOTES.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a8e81de5..c3d62590 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,18 @@ # Release Notes +## 0.9.2 + +Internal updates: + +* Update jackson-databind to 2.13.3 [#650](http://github.com/msgpack/msgpack-java/pull/650) +* Update akka-actor to 2.6.19 [#631](http://github.com/msgpack/msgpack-java/pull/631) +* Update airframe-json, airspec to 22.6.1 [#649](http://github.com/msgpack/msgpack-java/pull/649) +* Update scalacheck to 1.16.0 [#636](http://github.com/msgpack/msgpack-java/pull/636) +* Update scala-collection-compat to 2.7.0 [#632](http://github.com/msgpack/msgpack-java/pull/632) +* Update sbt-sonatype to 3.9.13 [#644](http://github.com/msgpack/msgpack-java/pull/644) +* Update airframe-json, airspec to 22.5.0 [#643](http://github.com/msgpack/msgpack-java/pull/643) +* Update sbt to 1.6.2 [#630](http://github.com/msgpack/msgpack-java/pull/630) + ## 0.9.1 Bug fixes and improvements: From 1346a031cf483b0650f08c2270e78c73c584a122 Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Mon, 27 Jun 2022 23:56:29 -0700 Subject: [PATCH 021/195] Update airframe-json, airspec to 22.6.4 (#659) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 990aed1b..274545e2 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.6.1" +val AIRFRAME_VERSION = "22.6.4" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From d665284264cbcf11917e2659d886bd881b098bdf Mon Sep 17 00:00:00 2001 From: Torsten Mehnert <92546601+tmehnert@users.noreply.github.com> Date: Tue, 28 Jun 2022 09:05:48 +0200 Subject: [PATCH 022/195] Use SPDX-ID in license name (#653) Change the license name to the SPDX-ID equivalent. See: https://spdx.org/licenses/ --- NOTICE | 2 +- sonatype.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NOTICE b/NOTICE index bc6328db..93b2e28b 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ This product includes the software developed by third-party: - * Google Guava https://code.google.com/p/guava-libraries/ (APL2) + * Google Guava https://code.google.com/p/guava-libraries/ (Apache-2.0) * sbt-extras: https://github.com/paulp/sbt-extras (BSD) (LICENSE.sbt-extras.txt) diff --git a/sonatype.sbt b/sonatype.sbt index f016335a..3fcb592f 100644 --- a/sonatype.sbt +++ b/sonatype.sbt @@ -2,7 +2,7 @@ import xerial.sbt.Sonatype._ ThisBuild / sonatypeProfileName := "org.msgpack" ThisBuild / homepage := Some(url("https://msgpack.org/")) -ThisBuild / licenses := Seq("APL2" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")) +ThisBuild / licenses := Seq("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")) ThisBuild / scmInfo := Some( ScmInfo( url("https://github.com/msgpack/msgpack-java"), From 117f1612fc3c08741a8acb159e52aa5d29c50988 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 28 Jun 2022 22:09:48 +0900 Subject: [PATCH 023/195] Support JDK17 (#660) * Reproduce #600 (JDK17 error) * Add workaround for Java17 * Add a helpful error message * Add note on JDK17 --- .github/workflows/CI.yml | 28 ++++++++++-- README.md | 9 ++++ build.sbt | 7 +++ .../core/buffer/DirectBufferAccess.java | 44 ++++++++++++------- .../core/buffer/DirectBufferAccessTest.scala | 29 ++++++++++++ 5 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f289bc70..f845825e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -26,14 +26,33 @@ jobs: - uses: actions/checkout@v2 - name: jcheckstyle run: ./sbt jcheckStyle + test_jdk17: + name: Test JDK17 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '17' + - uses: actions/cache@v2 + with: + path: ~/.cache + key: ${{ runner.os }}-jdk11-${{ hashFiles('**/*.sbt') }} + restore-keys: ${{ runner.os }}-jdk17- + - name: Test + run: ./sbt test + - name: Universal Buffer Test + run: ./sbt test -J-Dmsgpack.universal-buffer=true test_jdk11: name: Test JDK11 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: olafurpg/setup-scala@v10 + - uses: actions/setup-java@v3 with: - java-version: adopt@1.11 + distribution: 'zulu' + java-version: '11' - uses: actions/cache@v2 with: path: ~/.cache @@ -48,9 +67,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: olafurpg/setup-scala@v10 + - uses: actions/setup-java@v3 with: - java-version: adopt@1.8 + distribution: 'zulu' + java-version: '8' - uses: actions/cache@v2 with: path: ~/.cache diff --git a/README.md b/README.md index 4035fdc4..7723eb6e 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,15 @@ dependencies { - [Usage examples](https://github.com/msgpack/msgpack-java/blob/develop/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java) +### Java 17 Support + +For using DirectByteBuffer (off-heap memory access methods) in JDK17, you need to specify two JVM options: +``` +--add-opens=java.base/java.nio=ALL-UNNAMED +--add-opens=java.base/sun.nio.ch=ALL-UNNAMED +``` + + ### Integration with Jackson ObjectMapper (jackson-databind) msgpack-java supports serialization and deserialization of Java objects through [jackson-databind](https://github.com/FasterXML/jackson-databind). diff --git a/build.sbt b/build.sbt index 274545e2..0154bf5a 100644 --- a/build.sbt +++ b/build.sbt @@ -74,6 +74,13 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack.value.impl" ), testFrameworks += new TestFramework("wvlet.airspec.Framework"), + Test / javaOptions ++= Seq( + // --add-opens is not available in JDK8 + "-XX:+IgnoreUnrecognizedVMOptions", + "--add-opens=java.base/java.nio=ALL-UNNAMED", + "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" + ), + Test / fork := true, libraryDependencies ++= Seq( // msgpack-core should have no external dependencies junitInterface, diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java index cde2e6ec..f54c50b9 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java @@ -18,11 +18,13 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.AccessController; import java.security.PrivilegedAction; import sun.misc.Unsafe; +import sun.nio.ch.DirectBuffer; /** * Wraps the difference of access methods to DirectBuffers between Android and others. @@ -30,7 +32,8 @@ class DirectBufferAccess { private DirectBufferAccess() - {} + { + } enum DirectBufferConstructorType { @@ -40,7 +43,6 @@ enum DirectBufferConstructorType ARGS_MB_INT_INT } - static Method mGetAddress; // For Java <=8, gets a sun.misc.Cleaner static Method mCleaner; static Method mClean; @@ -95,10 +97,19 @@ enum DirectBufferConstructorType if (byteBufferConstructor == null) { throw new RuntimeException("Constructor of DirectByteBuffer is not found"); } - byteBufferConstructor.setAccessible(true); - mGetAddress = directByteBufferClass.getDeclaredMethod("address"); - mGetAddress.setAccessible(true); + try { + byteBufferConstructor.setAccessible(true); + } + catch (RuntimeException e) { + // This is a Java9+ exception, so we need to detect it without importing it for Java8 support + if ("java.lang.reflect.InaccessibleObjectException".equals(e.getClass().getName())) { + byteBufferConstructor = null; + } + else { + throw e; + } + } if (MessageBuffer.javaVersion <= 8) { setupCleanerJava6(direct); @@ -160,6 +171,7 @@ public Object run() /** * Checks if we have a usable {@link DirectByteBuffer#cleaner}. + * * @param direct a direct buffer * @return the method or an error */ @@ -184,6 +196,7 @@ private static Object getCleanerMethod(ByteBuffer direct) /** * Checks if we have a usable {@link sun.misc.Cleaner#clean}. + * * @param direct a direct buffer * @param mCleaner the {@link DirectByteBuffer#cleaner} method * @return the method or null @@ -210,6 +223,7 @@ private static Object getCleanMethod(ByteBuffer direct, Method mCleaner) /** * Checks if we have a usable {@link Unsafe#invokeCleaner}. + * * @param direct a direct buffer * @return the method or an error */ @@ -218,7 +232,7 @@ private static Object getInvokeCleanerMethod(ByteBuffer direct) try { // See https://bugs.openjdk.java.net/browse/JDK-8171377 Method m = MessageBuffer.unsafe.getClass().getDeclaredMethod( - "invokeCleaner", ByteBuffer.class); + "invokeCleaner", ByteBuffer.class); m.invoke(MessageBuffer.unsafe, direct); return m; } @@ -233,17 +247,9 @@ private static Object getInvokeCleanerMethod(ByteBuffer direct) } } - static long getAddress(Object base) + static long getAddress(Buffer buffer) { - try { - return (Long) mGetAddress.invoke(base); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) { - throw new RuntimeException(e); - } + return ((DirectBuffer) buffer).address(); } static void clean(Object base) @@ -253,7 +259,7 @@ static void clean(Object base) Object cleaner = mCleaner.invoke(base); mClean.invoke(cleaner); } - else { + else { mInvokeCleaner.invoke(MessageBuffer.unsafe, base); } } @@ -269,6 +275,10 @@ static boolean isDirectByteBufferInstance(Object s) static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) { + if (byteBufferConstructor == null) { + throw new IllegalStateException("Can't create a new DirectByteBuffer. In JDK17+, two JVM options needs to be set: " + + "--add-opens=java.base/java.nio=ALL-UNNAMED and --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"); + } try { switch (directBufferConstructorType) { case ARGS_LONG_INT_REF: diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala new file mode 100644 index 00000000..40f4c770 --- /dev/null +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala @@ -0,0 +1,29 @@ +// +// MessagePack for Java +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.core.buffer + +import wvlet.airspec.AirSpec + +import java.nio.ByteBuffer + +class DirectBufferAccessTest extends AirSpec { + + test("instantiate DirectBufferAccess") { + val bb = ByteBuffer.allocateDirect(1) + val addr = DirectBufferAccess.getAddress(bb) + + } +} From 36f601a044f3ca325ecd87d5a2e2ee091dc59714 Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Tue, 28 Jun 2022 06:10:53 -0700 Subject: [PATCH 024/195] Update akka-actor to 2.6.19 (#647) From d502fa122d8072886e8b73936e3d2634b25d8350 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Tue, 28 Jun 2022 22:19:36 +0900 Subject: [PATCH 025/195] 0.9.3 release notes --- RELEASE_NOTES.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c3d62590..367ab917 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,21 @@ # Release Notes +## 0.9.3 + +This version supports JDK17 [#660](http://github.com/msgpack/msgpack-java/pull/660). + +Important: If you need to use DirectByteBuffer (raw memory access) in JDK17 or later, specify two JVM options to allow accessing +native memory: +``` +--add-opens=java.base/java.nio=ALL-UNNAMED +--add-opens=java.base/sun.nio.ch=ALL-UNNAMED +``` +Internal updates: + +* Use SPDX-ID in license name [#653](http://github.com/msgpack/msgpack-java/pull/653) +* Update airframe-json, airspec to 22.6.4 [#659](http://github.com/msgpack/msgpack-java/pull/659) +* Update akka-actor to 2.6.19 [#647](http://github.com/msgpack/msgpack-java/pull/647) + ## 0.9.2 Internal updates: From 192457c6b731efc4bc61432aa0579fa66dd2b5fe Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Sat, 9 Jul 2022 03:23:27 -0700 Subject: [PATCH 026/195] Update scala-collection-compat to 2.8.0 (#663) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 0154bf5a..95effdb3 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.19" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.7.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.8.0" % "test" ) ) From 7108f4db3dfcb44e9315297ce0202d25a74d3200 Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Sat, 9 Jul 2022 03:23:35 -0700 Subject: [PATCH 027/195] Update airframe-json, airspec to 22.7.1 (#662) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 95effdb3..05a104bf 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.6.4" +val AIRFRAME_VERSION = "22.7.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 5ead37e9c558f3a12d729cfdb6086417c3e837f3 Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Wed, 13 Jul 2022 17:13:08 -0700 Subject: [PATCH 028/195] Update sbt to 1.7.1 (#666) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 022b635b..38c0109b 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.6.2 +sbt.version=1.7.1 From ee40181bef0dd9dea9ab6d03054328167b2b4bd5 Mon Sep 17 00:00:00 2001 From: xerial-bot Date: Wed, 13 Jul 2022 17:13:22 -0700 Subject: [PATCH 029/195] Update airframe-json, airspec to 22.7.2 (#668) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 05a104bf..3dcd3bca 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.7.1" +val AIRFRAME_VERSION = "22.7.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 64bf2e25bb6a6f72793a755e83539de98a1f7a3c Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 18 Jul 2022 08:16:54 +0200 Subject: [PATCH 030/195] Update sbt to 1.7.1 (#669) From bc0d03c3c7c77d67ef8e20ae99db1bb78f97d5fc Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Wed, 14 Sep 2022 20:16:21 +0900 Subject: [PATCH 031/195] Support timestamp extension in jackson-dataformat-msgpack (#677) * Support JDK8 to handle Instant * Add TimestampExtensionModule * Add TimestampExtensionModuleTest * Add a few more tests * Use msgpack-core's serde for timestamp internally * Add a test for 96-bit format * Revert "Support JDK8 to handle Instant" This reverts commit 33cdf2de163fa2a892a8dab904e1d6bed1f30c6f. * Take care of "No newline at end of file" * Fix format * Handle checkstyle error "Utility classes should not have a public or default constructor" * Clean up * Add some test for serializing * Add how to use TimestampExtensionModule in the doc --- msgpack-jackson/README.md | 20 +- .../dataformat/TimestampExtensionModule.java | 82 +++++++ .../TimestampExtensionModuleTest.java | 218 ++++++++++++++++++ 3 files changed, 319 insertions(+), 1 deletion(-) create mode 100755 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/TimestampExtensionModule.java create mode 100755 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index d3c77986..7e859781 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -240,9 +240,27 @@ When you want to use non-String value as a key of Map, use `MessagePackKeySerial System.out.println(mapper.readValue(converted, Pojo.class)); // => Pojo{value=1234567890.98765432100} ``` +### Serialize and deserialize Instant instances as MessagePack extension type + +`timestamp` extension type is defined in MessagePack as type:-1. Registering `TimestampExtensionModule.INSTANCE` module enables automatic serialization and deserialization of java.time.Instant to/from the MessagePack extension type. + +```java + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()) + .registerModule(TimestampExtensionModule.INSTANCE); + Pojo pojo = new Pojo(); + // The type of `timestamp` variable is Instant + pojo.timestamp = Instant.now(); + byte[] bytes = objectMapper.writeValueAsBytes(pojo); + + // The Instant instance is serialized as MessagePack extension type (type: -1) + + Pojo deserialized = objectMapper.readValue(bytes, Pojo.class); + System.out.println(deserialized); // "2022-09-14T08:47:24.922Z" +``` + ### Deserialize extension types with ExtensionTypeCustomDeserializers -`ExtensionTypeCustomDeserializers` helps you to deserialize extension types easily. +`ExtensionTypeCustomDeserializers` helps you to deserialize your own custom extension types easily. #### Deserialize extension type value directly diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/TimestampExtensionModule.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/TimestampExtensionModule.java new file mode 100755 index 00000000..2216d276 --- /dev/null +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/TimestampExtensionModule.java @@ -0,0 +1,82 @@ +package org.msgpack.jackson.dataformat; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.msgpack.core.ExtensionTypeHeader; +import org.msgpack.core.MessagePack; +import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageUnpacker; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.time.Instant; + +public class TimestampExtensionModule +{ + public static final byte EXT_TYPE = -1; + public static final SimpleModule INSTANCE = new SimpleModule("msgpack-ext-timestamp"); + + static { + INSTANCE.addSerializer(Instant.class, new InstantSerializer(Instant.class)); + INSTANCE.addDeserializer(Instant.class, new InstantDeserializer(Instant.class)); + } + + private static class InstantSerializer extends StdSerializer + { + protected InstantSerializer(Class t) + { + super(t); + } + + @Override + public void serialize(Instant value, JsonGenerator gen, SerializerProvider provider) + throws IOException + { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + // MEMO: Reusing these MessagePacker and MessageUnpacker instances would improve the performance + try (MessagePacker packer = MessagePack.newDefaultPacker(os)) { + packer.packTimestamp(value); + } + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(os.toByteArray())) { + ExtensionTypeHeader header = unpacker.unpackExtensionTypeHeader(); + byte[] bytes = unpacker.readPayload(header.getLength()); + + MessagePackExtensionType extensionType = new MessagePackExtensionType(EXT_TYPE, bytes); + gen.writeObject(extensionType); + } + } + } + + private static class InstantDeserializer extends StdDeserializer + { + protected InstantDeserializer(Class vc) + { + super(vc); + } + + @Override + public Instant deserialize(JsonParser p, DeserializationContext ctxt) + throws IOException + { + MessagePackExtensionType ext = p.readValueAs(MessagePackExtensionType.class); + if (ext.getType() != EXT_TYPE) { + throw new RuntimeException( + String.format("Unexpected extension type (0x%X) for Instant object", ext.getType())); + } + + // MEMO: Reusing this MessageUnpacker instance would improve the performance + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(ext.getData())) { + return unpacker.unpackTimestamp(new ExtensionTypeHeader(EXT_TYPE, ext.getData().length)); + } + } + } + + private TimestampExtensionModule() + { + } +} diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java new file mode 100755 index 00000000..05851dbc --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java @@ -0,0 +1,218 @@ +// +// MessagePack for Java +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.jackson.dataformat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.msgpack.core.MessagePack; +import org.msgpack.core.MessagePacker; +import org.msgpack.core.MessageUnpacker; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.time.Instant; + +import static org.junit.Assert.assertEquals; + +public class TimestampExtensionModuleTest +{ + private final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + private final SingleInstant singleInstant = new SingleInstant(); + private final TripleInstants tripleInstants = new TripleInstants(); + + private static class SingleInstant + { + public Instant instant; + } + + private static class TripleInstants + { + public Instant a; + public Instant b; + public Instant c; + } + + @Before + public void setUp() + throws Exception + { + objectMapper.registerModule(TimestampExtensionModule.INSTANCE); + } + + @Test + public void testSingleInstantPojo() + throws IOException + { + singleInstant.instant = Instant.now(); + byte[] bytes = objectMapper.writeValueAsBytes(singleInstant); + SingleInstant deserialized = objectMapper.readValue(bytes, SingleInstant.class); + assertEquals(singleInstant.instant, deserialized.instant); + } + + @Test + public void testTripleInstantsPojo() + throws IOException + { + Instant now = Instant.now(); + tripleInstants.a = now.minusSeconds(1); + tripleInstants.b = now; + tripleInstants.c = now.plusSeconds(1); + byte[] bytes = objectMapper.writeValueAsBytes(tripleInstants); + TripleInstants deserialized = objectMapper.readValue(bytes, TripleInstants.class); + assertEquals(now.minusSeconds(1), deserialized.a); + assertEquals(now, deserialized.b); + assertEquals(now.plusSeconds(1), deserialized.c); + } + + @Test + public void serialize32BitFormat() + throws IOException + { + singleInstant.instant = Instant.ofEpochSecond(Instant.now().getEpochSecond()); + + byte[] bytes = objectMapper.writeValueAsBytes(singleInstant); + + // Check the size of serialized data first + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + assertEquals("instant", unpacker.unpackString()); + assertEquals(4, unpacker.unpackExtensionTypeHeader().getLength()); + } + + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + unpacker.unpackString(); + assertEquals(singleInstant.instant, unpacker.unpackTimestamp()); + } + } + + @Test + public void serialize64BitFormat() + throws IOException + { + singleInstant.instant = Instant.ofEpochSecond(Instant.now().getEpochSecond(), 1234); + + byte[] bytes = objectMapper.writeValueAsBytes(singleInstant); + + // Check the size of serialized data first + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + assertEquals("instant", unpacker.unpackString()); + assertEquals(8, unpacker.unpackExtensionTypeHeader().getLength()); + } + + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + unpacker.unpackString(); + assertEquals(singleInstant.instant, unpacker.unpackTimestamp()); + } + } + + @Test + public void serialize96BitFormat() + throws IOException + { + singleInstant.instant = Instant.ofEpochSecond(19880866800L /* 2600-01-01 */, 1234); + + byte[] bytes = objectMapper.writeValueAsBytes(singleInstant); + + // Check the size of serialized data first + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + assertEquals("instant", unpacker.unpackString()); + assertEquals(12, unpacker.unpackExtensionTypeHeader().getLength()); + } + + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + unpacker.unpackString(); + assertEquals(singleInstant.instant, unpacker.unpackTimestamp()); + } + } + + @Test + public void deserialize32BitFormat() + throws IOException + { + Instant instant = Instant.ofEpochSecond(Instant.now().getEpochSecond()); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try (MessagePacker packer = MessagePack.newDefaultPacker(os)) { + packer.packMapHeader(1) + .packString("instant") + .packTimestamp(instant); + } + + byte[] bytes = os.toByteArray(); + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + unpacker.unpackString(); + assertEquals(4, unpacker.unpackExtensionTypeHeader().getLength()); + } + + SingleInstant deserialized = objectMapper.readValue(bytes, SingleInstant.class); + assertEquals(instant, deserialized.instant); + } + + @Test + public void deserialize64BitFormat() + throws IOException + { + Instant instant = Instant.ofEpochSecond(Instant.now().getEpochSecond(), 1234); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try (MessagePacker packer = MessagePack.newDefaultPacker(os)) { + packer.packMapHeader(1) + .packString("instant") + .packTimestamp(instant); + } + + byte[] bytes = os.toByteArray(); + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + unpacker.unpackString(); + assertEquals(8, unpacker.unpackExtensionTypeHeader().getLength()); + } + + SingleInstant deserialized = objectMapper.readValue(bytes, SingleInstant.class); + assertEquals(instant, deserialized.instant); + } + + @Test + public void deserialize96BitFormat() + throws IOException + { + Instant instant = Instant.ofEpochSecond(19880866800L /* 2600-01-01 */, 1234); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try (MessagePacker packer = MessagePack.newDefaultPacker(os)) { + packer.packMapHeader(1) + .packString("instant") + .packTimestamp(instant); + } + + byte[] bytes = os.toByteArray(); + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes)) { + unpacker.unpackMapHeader(); + unpacker.unpackString(); + assertEquals(12, unpacker.unpackExtensionTypeHeader().getLength()); + } + + SingleInstant deserialized = objectMapper.readValue(bytes, SingleInstant.class); + assertEquals(instant, deserialized.instant); + } +} From 48f67c6358953f67f6faf7f159f2dc488f1fc768 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:43:45 +0200 Subject: [PATCH 032/195] Update airframe-json, airspec to 22.7.3 (#671) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3dcd3bca..be91cf63 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.7.2" +val AIRFRAME_VERSION = "22.7.3" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From d9379269c4e2188bf6a82b21121cf305f28c1d5a Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:43:55 +0200 Subject: [PATCH 033/195] Update scala-collection-compat to 2.8.1 (#673) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index be91cf63..52655492 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.19" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.8.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.8.1" % "test" ) ) From 112962c0a5a91b8c20b9ff0640a6b42c97b4db46 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 17 Sep 2022 02:05:57 +0200 Subject: [PATCH 034/195] Update airframe-json, airspec to 22.9.0 (#678) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 52655492..7ae88df5 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.7.3" +val AIRFRAME_VERSION = "22.9.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 965564dc4548151f9572ab8d3fe4f477f8294a26 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 17 Sep 2022 02:06:09 +0200 Subject: [PATCH 035/195] Update akka-actor to 2.6.20 (#676) * Update akka-actor to 2.6.20 * Revert commit(s) 7d76a574 * Update akka-actor to 2.6.20 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7ae88df5..b4992f3f 100644 --- a/build.sbt +++ b/build.sbt @@ -91,7 +91,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka - "com.typesafe.akka" %% "akka-actor" % "2.6.19" % "test", + "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", "org.scala-lang.modules" %% "scala-collection-compat" % "2.8.1" % "test" ) ) From 44c939b9403cfcc88ce83143e025f6d256189944 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 17 Sep 2022 02:06:27 +0200 Subject: [PATCH 036/195] Update jackson-databind to 2.13.4 (#675) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index b4992f3f..ce3ab0a7 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.13.3", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.13.4", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 3c7ab6fb7dfc2ace9d53fb98e8018397f43a57fb Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 2 Nov 2022 07:27:15 +0100 Subject: [PATCH 037/195] Update airframe-json, airspec to 22.9.2 (#680) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index ce3ab0a7..0a14f8e3 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.9.0" +val AIRFRAME_VERSION = "22.9.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From e05285cf03a8d74b1c8db0cea7722b0d16826365 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 12 Nov 2022 00:16:38 +0100 Subject: [PATCH 038/195] Update sbt-sonatype to 3.9.14 (#686) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 4b437b7c..1c9c463f 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.13") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.14") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From 5aabe40da9ad368de0dd4a56c79d1f05ea929ee2 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 12 Nov 2022 00:17:01 +0100 Subject: [PATCH 039/195] Update airframe-json, airspec to 22.9.3 (#685) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 0a14f8e3..570baaae 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.9.2" +val AIRFRAME_VERSION = "22.9.3" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From e5763b2985a03c8468d94ca74458facdab5d69e1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 14 Nov 2022 01:46:14 +0100 Subject: [PATCH 040/195] Update sbt-pgp to 2.2.0 (#683) * Update sbt-pgp to 2.2.0 * Revert commit(s) d0535a53 * Update sbt-pgp to 2.2.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 1c9c463f..862592e6 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.14") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.0") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") From f1ac3dd322a03516e3dcdc6cbec7686e14b1c8f2 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 14 Nov 2022 01:46:23 +0100 Subject: [PATCH 041/195] Update scalacheck to 1.17.0 (#679) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 570baaae..4a41598c 100644 --- a/build.sbt +++ b/build.sbt @@ -87,7 +87,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.16.0" % "test", + "org.scalacheck" %% "scalacheck" % "1.17.0" % "test", // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka From a846ca11726cb7f688671fe4682e9bf87ae280f1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 21 Jan 2023 07:47:06 +0100 Subject: [PATCH 042/195] Update sbt-sonatype to 3.9.15 (#696) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 862592e6..91d167e0 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.14") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.15") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.0") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From 5235a8304efb12c7d39ec97329474687be192edc Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 21 Jan 2023 07:47:23 +0100 Subject: [PATCH 043/195] Update scala-collection-compat to 2.9.0 (#697) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4a41598c..3919448a 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.8.1" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.9.0" % "test" ) ) From b45c90e37e1701f9be800f98b0eab08e30249bb1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 21 Jan 2023 07:47:32 +0100 Subject: [PATCH 044/195] Update sbt to 1.7.3 (#684) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 38c0109b..b986067e 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.7.1 +sbt.version=1.7.3 From d066051af1c47b58a3cf87cb52712d9a22e50ba7 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 21 Jan 2023 08:26:36 +0100 Subject: [PATCH 045/195] Update sbt-scalafmt to 2.5.0 (#689) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 91d167e0..7cb596d4 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.0") //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0") addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") scalacOptions ++= Seq("-deprecation", "-feature") From 00fc660637b811669a1e266c45cd2eda92bdade0 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 22 Jan 2023 01:31:38 +0900 Subject: [PATCH 046/195] Small improvement of msgpack-jackson bench (#705) Small improvment of msgpack-jackson bench --- .github/workflows/CI.yml | 1 + .../benchmark/MessagePackDataformatHugeDataBenchmarkTest.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f845825e..d53a68bf 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,6 +17,7 @@ on: - '**.java' - '**.sbt' - '.github/workflows/**.yml' + workflow_dispatch: jobs: code_format: diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java index b3a15911..fea34fd8 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java @@ -30,7 +30,7 @@ public class MessagePackDataformatHugeDataBenchmarkTest { - private static final int ELM_NUM = 100000; + private static final int ELM_NUM = 1000000; private static final int COUNT = 6; private static final int WARMUP_COUNT = 4; private final ObjectMapper origObjectMapper = new ObjectMapper(); From ef8ad71af83b4241db30fcee9f12425c38d0f5ab Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 25 Jan 2023 09:56:15 +0100 Subject: [PATCH 047/195] Update sbt to 1.8.2 (#706) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index b986067e..6cd347fa 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.7.3 +sbt.version=1.8.2 From 41cee04c2fe7558d985113756f0ab33da701add3 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 25 Jan 2023 09:56:27 +0100 Subject: [PATCH 048/195] Update airframe-json, airspec to 22.12.6 (#703) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3919448a..c4f5ab2b 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.9.3" +val AIRFRAME_VERSION = "22.12.6" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 45f287e5d4deefa604c253f68f75fc54390bb2d0 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 4 Feb 2023 01:22:49 +0100 Subject: [PATCH 049/195] Update sbt-sonatype to 3.9.17 (#710) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 7cb596d4..6caa6bcb 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.15") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.17") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.0") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From c83aa6ab83c3cf6a36c5c8af10e5756c02c7f39d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 4 Feb 2023 01:22:57 +0100 Subject: [PATCH 050/195] Update airframe-json, airspec to 23.1.4 (#708) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c4f5ab2b..c67f7482 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "22.12.6" +val AIRFRAME_VERSION = "23.1.4" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From c796b29b5b0df7a1e2abebc0b80002273c25909e Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 4 Feb 2023 01:23:09 +0100 Subject: [PATCH 051/195] Update jackson-databind to 2.13.5 (#707) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c67f7482..462e8acf 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.13.4", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.13.5", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 04d03d883ffbb6c7a277bf2552de5aa93465da11 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 4 Feb 2023 19:41:55 +0100 Subject: [PATCH 052/195] Update airframe-json, airspec to 23.2.0 (#712) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 462e8acf..30c56e35 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.1.4" +val AIRFRAME_VERSION = "23.2.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 211d349c7db614b7f1a011bc86dbce035bc82f24 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 4 Feb 2023 19:42:03 +0100 Subject: [PATCH 053/195] Update sbt-pgp to 2.2.1 (#698) * Update sbt-pgp to 2.2.1 * Revert commit(s) bae49c71 * Update sbt-pgp to 2.2.1 --------- Co-authored-by: Taro L. Saito --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 project/plugins.sbt diff --git a/project/plugins.sbt b/project/plugins.sbt old mode 100755 new mode 100644 index 6caa6bcb..b2de1be9 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.17") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.0") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") From 6ba76dd3cf16c54540c3e24071ea6d72c8105d85 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 4 Feb 2023 19:44:20 +0100 Subject: [PATCH 054/195] Update jackson-databind to 2.14.2 (#711) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 30c56e35..c5c7ac78 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.13.5", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.14.2", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 8e3bc5117a00e851bac457e828102739742d3df7 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 6 Feb 2023 20:01:57 -0800 Subject: [PATCH 055/195] Introduce release drafter (#713) * Introduce release drafter * Target develop/main branches * Update README.md * Update README.md --- .github/release-drafter.yml | 55 +++++++++++++++++++++++++++ .github/workflows/release-drafter.yml | 32 ++++++++++++++++ README.md | 9 +---- 3 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 .github/release-drafter.yml create mode 100644 .github/workflows/release-drafter.yml diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000..86a39768 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,55 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' +categories: + - title: '🔥 Breaking Changes' + labels: + - 'breaking' + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'bug' + - title: '👋 Deprecated' + labels: + - 'deprecation' + - title: '🔗 Dependency Updates' + labels: + - 'library-update' + - 'dependencies' + - title: '🛠 Internal Updates' + labels: + - 'internal' + - 'kaizen' + - 'test-library-update' + - 'sbt-plugin-update' + - title: '📚 Docs' + labels: + - 'doc' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' + +template: | + ## What's Changed + + $CHANGES + + **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION + + +autolabeler: + - label: 'doc' + files: + - '*.md' + - label: 'feature' + title: + - '/(support|add)/i' + - label: 'bug' + title: + - '/fix/i' + - label: 'internal' + title: + - '/internal/i' + - label: 'deprecation' + title: + - '/deprecate/i' diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 00000000..6a48ed0a --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,32 @@ +name: Release Drafter + +on: + push: + branches: + - develop + - main + # pull_request event is required only for autolabeler + pull_request: + # Only following types are handled by the action, but one can default to all as well + types: [opened, reopened, synchronize] + # pull_request_target event is required for autolabeler to support PRs from forks + pull_request_target: + types: [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + update_release_draft: + permissions: + # write permission is required to create a github release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 7723eb6e..8cad43c6 100644 --- a/README.md +++ b/README.md @@ -82,10 +82,8 @@ Here is a list of sbt commands for daily development: > ~testOnly *MessagePackTest -- (pattern) # Run tests matching the pattern > project msgpack-core # Focus on a specific project > package # Create a jar file in the target folder of each project -> findbugs # Produce findbugs report in target/findbugs -> jacoco:cover # Report the code coverage of tests to target/jacoco folder > jcheckStyle # Run check style -> ;scalafmt;test:scalafmt;scalafmtSbt # Reformat Scala codes +> scalafmtAll # Reformat code ``` ### Publishing @@ -105,10 +103,7 @@ $ git tag v0.x.y $ git push origin v0.x.y ``` -To generate a release notes, you can use this command line: -``` -$ git log v(last version).. --oneline | cut -f 2- -d ' ' | perl -npe 's/(.*)\(\#([0-9]+)\)/* \1\[\#\2\]\(https:\/\/round-lake.dustinice.workers.dev:443\/http\/github.com\/msgpack\/msgpack-java\/pull\/\2\)/g' -``` +A draft of the next release note will be updated automatically at the [GitHub Releases](https://github.com/msgpack/msgpack-java/releases) page. For each PR merged, [release-drafter](https://github.com/release-drafter/release-drafter) will modify the release note draft. When you create a new release tag, edit and publish the draft of the release note. If necessary, adjust the version number and target tag. #### Publishing to Sonatype from Local Machine From 85c5392b6c49c2b71064e5fb2cd2cd448c01908b Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 6 Feb 2023 21:51:08 -0800 Subject: [PATCH 056/195] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 367ab917..3f8d8d9d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,7 @@ # Release Notes +The latest release notes will be available from the [GitHub release page](https://github.com/msgpack/msgpack-java/releases) + ## 0.9.3 This version supports JDK17 [#660](http://github.com/msgpack/msgpack-java/pull/660). From e7418c69e4899eaca8b5397b96c09ab18301bfef Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 6 Feb 2023 23:03:58 -0800 Subject: [PATCH 057/195] Classify PRs based on Scala-Steward PR body message --- .github/release-drafter.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 86a39768..79b084d7 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -53,3 +53,9 @@ autolabeler: - label: 'deprecation' title: - '/deprecate/i' + - label: 'library-update' + body: + - '/library-update/' + - label: 'test-library-update' + body: + - '/test-library-update/' From 7779615cf1b36486ab2f9cf4b05557ed8e8484ad Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 6 Feb 2023 23:07:14 -0800 Subject: [PATCH 058/195] Mark test library/sbt plugin updates as internal --- .github/release-drafter.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 79b084d7..2e6420f9 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -56,6 +56,7 @@ autolabeler: - label: 'library-update' body: - '/library-update/' - - label: 'test-library-update' + - label: 'internal' body: - '/test-library-update/' + - '/sbt-plugin-update/' From 3381322f6c163154e927207509be11adfb755de0 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 6 Feb 2023 23:21:47 -0800 Subject: [PATCH 059/195] update sbt script (#714) --- sbt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbt b/sbt index 18c6b112..0c5112ba 100755 --- a/sbt +++ b/sbt @@ -34,11 +34,11 @@ set -o pipefail -declare -r sbt_release_version="1.5.5" -declare -r sbt_unreleased_version="1.6.0-M1" +declare -r sbt_release_version="1.8.2" +declare -r sbt_unreleased_version="1.8.2" -declare -r latest_213="2.13.7" -declare -r latest_212="2.12.15" +declare -r latest_213="2.13.10" +declare -r latest_212="2.12.17" declare -r latest_211="2.11.12" declare -r latest_210="2.10.7" declare -r latest_29="2.9.3" From 78080d18ffa29ff06d8d6160a3e7bf360d7bb859 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 27 Feb 2023 02:50:28 +0100 Subject: [PATCH 060/195] Update airframe-json, airspec to 23.2.5 (#717) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c5c7ac78..28671003 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.2.0" +val AIRFRAME_VERSION = "23.2.5" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From e423757f3b7d7e1c2853e6624bf0fc410beb4ae1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:37:51 +0100 Subject: [PATCH 061/195] Update sbt-sonatype to 3.9.18 (#719) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index b2de1be9..1bcb3851 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.17") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.18") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From 93d4bc0e1e6d375a5c2fb949c3a329d092ecf1e8 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:38:03 +0100 Subject: [PATCH 062/195] Update airframe-json, airspec to 23.3.0 (#718) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 28671003..8dc03cad 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.2.5" +val AIRFRAME_VERSION = "23.3.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 4bb8a03b00795ae74397261d53abeca9d02c3e30 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 29 Apr 2023 18:46:23 +0200 Subject: [PATCH 063/195] Update airframe-json, airspec to 23.3.4 (#723) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 8dc03cad..e992a4d6 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.3.0" +val AIRFRAME_VERSION = "23.3.4" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 4853f0459b310e2520dcdffb93487368ee1d577f Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 29 Apr 2023 18:46:41 +0200 Subject: [PATCH 064/195] Update scala-collection-compat to 2.10.0 (#726) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index e992a4d6..fd414fac 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.9.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.10.0" % "test" ) ) From 6512662dbe15645bbb3567a9d115a82af73486ae Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 5 May 2023 18:24:36 +0200 Subject: [PATCH 065/195] Update airframe-json, airspec to 23.5.0 (#728) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index fd414fac..9029b82e 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.3.4" +val AIRFRAME_VERSION = "23.5.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From ce92979ec2be89a49969a89904884c399c18b67d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 5 May 2023 18:24:45 +0200 Subject: [PATCH 066/195] Update sbt-sonatype to 3.9.19 (#729) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 1bcb3851..fa10c664 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.18") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.19") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From 4d24d82b044f2f9506cf9b2a1bde0a571253ed64 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 11 May 2023 11:43:31 +0200 Subject: [PATCH 067/195] Update sbt-sonatype to 3.9.20 (#732) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index fa10c664..f79c91e8 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.19") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.20") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From f351e3fb934883f50002592b5f1a44e15df232df Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 11 May 2023 11:43:40 +0200 Subject: [PATCH 068/195] Update airframe-json, airspec to 23.5.2 (#731) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 9029b82e..b35f90be 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.5.0" +val AIRFRAME_VERSION = "23.5.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 1e5483ffd7e7e791229e9956a36d797bbb01de4d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 22 May 2023 19:05:48 +0200 Subject: [PATCH 069/195] Update jackson-databind to 2.14.3 (#730) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index b35f90be..7df0944b 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.14.2", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.14.3", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 727bdf9b84fcdc6d02545439c2a596ef15ea44be Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 31 May 2023 23:36:11 +0200 Subject: [PATCH 070/195] Update sbt-sonatype to 3.9.21 (#737) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index f79c91e8..af845560 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.20") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.21") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From dd6accbbf98708a557926223a7ed38e44856e345 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 31 May 2023 23:36:19 +0200 Subject: [PATCH 071/195] Update sbt to 1.8.3 (#735) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 6cd347fa..5041518d 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.8.2 +sbt.version=1.8.3 From 24a89ca2d919707ed92ef8fcdc35facd912f3a80 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 31 May 2023 23:36:27 +0200 Subject: [PATCH 072/195] Update sbt-dynver to 5.0.1 (#733) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index af845560..2e2e4806 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,6 +6,6 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0") -addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") +addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") scalacOptions ++= Seq("-deprecation", "-feature") From 2ffd012ed28e78d394d38896bee73171f7ed9505 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 31 May 2023 23:36:37 +0200 Subject: [PATCH 073/195] Update airframe-json, airspec to 23.5.6 (#736) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7df0944b..19c1a11f 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.5.2" +val AIRFRAME_VERSION = "23.5.6" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From a40cfd11279f4d466ba6500e6c72e83a7a9ecd86 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 3 Jun 2023 00:18:49 +0200 Subject: [PATCH 074/195] Update sbt to 1.9.0 (#738) * Update sbt to 1.9.0 * Run CI on sbt upgrade --------- Co-authored-by: Taro L. Saito --- .github/workflows/CI.yml | 2 ++ project/build.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d53a68bf..3c8d09e6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -7,6 +7,7 @@ on: - '**.java' - '**.sbt' - '.github/workflows/**.yml' + - 'project/build.properties' push: branches: - master @@ -17,6 +18,7 @@ on: - '**.java' - '**.sbt' - '.github/workflows/**.yml' + - 'project/build.properties' workflow_dispatch: jobs: diff --git a/project/build.properties b/project/build.properties index 5041518d..01892960 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.8.3 +sbt.version=1.9.0 From caba23895f08df87afe6f63f4d9d0909a516e3b0 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 28 Jun 2023 00:14:38 +0200 Subject: [PATCH 075/195] Update airframe-json, airspec to 23.5.7 (#739) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 19c1a11f..d5260290 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.5.6" +val AIRFRAME_VERSION = "23.5.7" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From b2181d8eba51f6534adb91d73cef8fdc8a16e97d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 28 Jun 2023 00:14:47 +0200 Subject: [PATCH 076/195] Update scala-collection-compat to 2.11.0 (#740) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index d5260290..73d64eda 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.10.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.11.0" % "test" ) ) From 4b3895488c1263bf91489748bdceac0069bca85e Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 28 Jun 2023 00:18:37 +0200 Subject: [PATCH 077/195] Update jackson-databind to 2.15.2 (#734) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 73d64eda..ca8f9cf6 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.14.3", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.15.2", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 95863661a5d48052a9c8ffbeae70dcd286c09941 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Mon, 10 Jul 2023 22:24:59 +0900 Subject: [PATCH 078/195] Add `MessagePackMapper#handleBigDecimalAsString` (#745) --- msgpack-jackson/README.md | 32 +++++++++----- .../jackson/dataformat/MessagePackMapper.java | 9 ++++ .../dataformat/MessagePackMapperTest.java | 44 +++++++++++++++++++ 3 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index 7e859781..e91c6f8b 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -61,7 +61,13 @@ Only thing you need to do is to instantiate `MessagePackFactory` and pass it to Or more easily: ```java -ObjectMapper objectMapper = new MessagePackMapper(); + ObjectMapper objectMapper = new MessagePackMapper(); +``` + +We strongly recommend to call `MessagePackMapper#handleBigDecimalAsString()` if you serialize and/or deserialize BigDecimal values. See [Serialize and deserialize BigDecimal as str type internally in MessagePack format](#serialize-and-deserialize-bigdecimal-as-str-type-internally-in-messagepack-format) for details. + +```java + ObjectMapper objectMapper = new MessagePackMapper().handleBigDecimalAsString(); ``` ### Serialization/Deserialization of List @@ -226,26 +232,33 @@ When you want to use non-String value as a key of Map, use `MessagePackKeySerial ### Serialize and deserialize BigDecimal as str type internally in MessagePack format -`jackson-dataformat-msgpack` represents BigDecimal values as float type in MessagePack format by default. When you want to handle BigDeciaml values as str type with arbitrary precision in MessagePack format, you can use `com.fasterxml.jackson.databind.cfg.MutableConfigOverride#setFormat` like this: +`jackson-dataformat-msgpack` represents BigDecimal values as float type in MessagePack format by default for backward compatibility. But the default behavior could fail when handling too large value for `double` type. So we strongly recommend to call `MessagePackMapper#handleBigDecimalAsString()` to internally handle BigDecimal values as String. ```java - ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); - mapper.configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); + ObjectMapper objectMapper = new MessagePackMapper().handleBigDecimalAsString(); Pojo obj = new Pojo(); + // This value is too large to be serialized as double obj.value = new BigDecimal("1234567890.98765432100"); - byte[] converted = mapper.writeValueAsBytes(obj); + byte[] converted = objectMapper.writeValueAsBytes(obj); + + System.out.println(objectMapper.readValue(converted, Pojo.class)); // => Pojo{value=1234567890.98765432100} +``` +`MessagePackMapper#handleBigDecimalAsString()` is equivalent to the following configuration. - System.out.println(mapper.readValue(converted, Pojo.class)); // => Pojo{value=1234567890.98765432100} +```java + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + objectMapper.configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); ``` + ### Serialize and deserialize Instant instances as MessagePack extension type `timestamp` extension type is defined in MessagePack as type:-1. Registering `TimestampExtensionModule.INSTANCE` module enables automatic serialization and deserialization of java.time.Instant to/from the MessagePack extension type. ```java - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()) + ObjectMapper objectMapper = new MessagePackMapper() .registerModule(TimestampExtensionModule.INSTANCE); Pojo pojo = new Pojo(); // The type of `timestamp` variable is Instant @@ -287,8 +300,8 @@ When you want to use non-String value as a key of Map, use `MessagePackKeySerial return "Java"; } return "Not Java"; - } - ); + }); + ObjectMapper objectMapper = new ObjectMapper( new MessagePackFactory().setExtTypeCustomDesers(extTypeCustomDesers)); @@ -476,4 +489,3 @@ There are a few options to fix this issue, but they introduce performance degred ObjectMapper objectMapper = new ObjectMapper( new MessagePackFactory().setReuseResourceInGenerator(false)); ``` - diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java index 3c3d228b..52af0372 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java @@ -15,9 +15,12 @@ // package org.msgpack.jackson.dataformat; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.cfg.MapperBuilder; +import java.math.BigDecimal; + public class MessagePackMapper extends ObjectMapper { private static final long serialVersionUID = 3L; @@ -40,6 +43,12 @@ public MessagePackMapper(MessagePackFactory f) super(f); } + public MessagePackMapper handleBigDecimalAsString() + { + configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); + return this; + } + public static Builder builder() { return new Builder(new MessagePackMapper()); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java new file mode 100644 index 00000000..6dfd41cf --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java @@ -0,0 +1,44 @@ +// +// MessagePack for Java +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.jackson.dataformat; + +import org.junit.Test; + +import java.io.IOException; +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; + +public class MessagePackMapperTest +{ + static class Pojo + { + public BigDecimal value; + } + + @Test + public void handleBigDecimalAsString() throws IOException + { + MessagePackMapper mapper = new MessagePackMapper().handleBigDecimalAsString(); + Pojo obj = new Pojo(); + obj.value = new BigDecimal("1234567890.98765432100"); + + byte[] converted = mapper.writeValueAsBytes(obj); + + Pojo deserialized = mapper.readValue(converted, Pojo.class); + assertEquals(obj.value, deserialized.value); + } +} From 60f5aa62ea3e22b1c7964b0221c26e601d956537 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:01:01 +0200 Subject: [PATCH 079/195] Update sbt to 1.9.1 (#741) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 01892960..ffd11bcc 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.0 +sbt.version=1.9.1 From 629c6f4b5e00a9ebc13fc87160361154211b6ed4 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:58:15 +0200 Subject: [PATCH 080/195] Update sbt to 1.9.2 (#746) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index ffd11bcc..7a2f2cd1 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.1 +sbt.version=1.9.2 From 596b6faea3053c77099b2c02470f8d73ca8cb0c1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 12 Jul 2023 16:58:24 +0200 Subject: [PATCH 081/195] Update airframe-json, airspec to 23.7.1 (#744) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index ca8f9cf6..c3b3e1ce 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.5.7" +val AIRFRAME_VERSION = "23.7.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From b3f5e806581ee7208e54cb8db328fe066ebdd927 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 17 Jul 2023 19:14:57 +0200 Subject: [PATCH 082/195] Update airframe-json, airspec to 23.7.2 (#748) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c3b3e1ce..58aee857 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.7.1" +val AIRFRAME_VERSION = "23.7.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 2465fd311a6905be459975664e5ca123d921d089 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 25 Jul 2023 00:17:58 +0200 Subject: [PATCH 083/195] Update sbt to 1.9.3 (#750) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 7a2f2cd1..91550e82 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.2 +sbt.version=1.9.3 From 3085cc16dabbd13bedcb7d8820af255b606c1470 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Mon, 31 Jul 2023 10:08:18 -0700 Subject: [PATCH 084/195] core (fix): Fix MessageUnpacker.unpackValue to check the custom stringSizeLimit (#753) * core (fix): Fix MessageUnpacker.unpackValue to check the custom stringSizeLimit * Cover unpackVariable(var) --- .../org/msgpack/core/MessageUnpacker.java | 6 +++ .../org/msgpack/core/StringLimitTest.scala | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index ff638b74..8da8d794 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -624,6 +624,9 @@ public ImmutableValue unpackValue() return ValueFactory.newFloat(unpackDouble()); case STRING: { int length = unpackRawStringHeader(); + if (length > stringSizeLimit) { + throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, length), length); + } return ValueFactory.newString(readPayload(length), true); } case BINARY: { @@ -689,6 +692,9 @@ public Variable unpackValue(Variable var) return var; case STRING: { int length = unpackRawStringHeader(); + if (length > stringSizeLimit) { + throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", stringSizeLimit, length), length); + } var.setStringValue(readPayload(length)); return var; } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala new file mode 100644 index 00000000..96319a7f --- /dev/null +++ b/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala @@ -0,0 +1,37 @@ +package org.msgpack.core + +import org.msgpack.core.MessagePack.UnpackerConfig +import org.msgpack.value.Variable +import wvlet.airspec.AirSpec + +class StringLimitTest extends AirSpec { + + test("throws an exception when the string size exceeds a limit") { + val customLimit = 100 + val packer = MessagePack.newDefaultBufferPacker() + packer.packString("a" * (customLimit + 1)) + val msgpack = packer.toByteArray + + test("unpackString") { + val unpacker = new UnpackerConfig().withStringSizeLimit(customLimit).newUnpacker(msgpack) + intercept[MessageSizeException] { + unpacker.unpackString() + } + } + + test("unpackValue") { + val unpacker = new UnpackerConfig().withStringSizeLimit(customLimit).newUnpacker(msgpack) + intercept[MessageSizeException] { + unpacker.unpackValue() + } + } + + test("unpackValue(var)") { + val unpacker = new UnpackerConfig().withStringSizeLimit(customLimit).newUnpacker(msgpack) + intercept[MessageSizeException] { + val v = new Variable() + unpacker.unpackValue(v) + } + } + } +} From eaab10600a5e5e2a7e8d26e1a4eee02703c6506e Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:43:02 +0200 Subject: [PATCH 085/195] Update airframe-json, airspec to 23.7.4 (#752) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 58aee857..ba727573 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.7.2" +val AIRFRAME_VERSION = "23.7.4" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From cdfe139e2b0c81c22fe7cb95562480afbb52b708 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Aug 2023 08:01:27 +0200 Subject: [PATCH 086/195] Update airframe-json, airspec to 23.8.0 (#754) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index ba727573..faa64554 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.7.4" +val AIRFRAME_VERSION = "23.8.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 1e0eaff64319c74c6c0eb814eab93456bd695e16 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sun, 6 Aug 2023 23:18:01 -0700 Subject: [PATCH 087/195] Switch the default branch from develop to main (#755) * Switch the default branch from develop to main * Revert unnecessary changes --- .github/release-drafter.yml | 4 ++-- .github/workflows/CI.yml | 2 -- .github/workflows/release-drafter.yml | 3 +-- .github/workflows/snapshot.yml | 1 - 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 2e6420f9..fb21a72b 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -43,10 +43,10 @@ autolabeler: - '*.md' - label: 'feature' title: - - '/(support|add)/i' + - '/(feature|support)/i' - label: 'bug' title: - - '/fix/i' + - '/(fix|bug)/i' - label: 'internal' title: - '/internal/i' diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3c8d09e6..74352654 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,8 +10,6 @@ on: - 'project/build.properties' push: branches: - - master - - develop - main paths: - '**.scala' diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 6a48ed0a..3e173377 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -3,7 +3,6 @@ name: Release Drafter on: push: branches: - - develop - main # pull_request event is required only for autolabeler pull_request: @@ -12,7 +11,7 @@ on: # pull_request_target event is required for autolabeler to support PRs from forks pull_request_target: types: [opened, reopened, synchronize] - + permissions: contents: read diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 1fde65f1..e244adfd 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -3,7 +3,6 @@ name: Snapshot Release on: push: branches: - - develop - main paths: - '**.scala' From 8f7bc87461fe9653c141a6f2a44e973199d3b4e6 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:25:30 +0200 Subject: [PATCH 088/195] Update airframe-json, airspec to 23.8.1 (#756) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index faa64554..310ebe55 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.8.0" +val AIRFRAME_VERSION = "23.8.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 72eb1bcc4d1f9ee5ccadf3915b56b1e7de0c0849 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 12 Sep 2023 08:54:37 +0200 Subject: [PATCH 089/195] Update sbt to 1.9.4 (#759) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 91550e82..0425ccf8 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.3 +sbt.version=1.9.4 From 511c4d4b625acb044db17aa33c894ada5efdb9fa Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 12 Sep 2023 08:54:49 +0200 Subject: [PATCH 090/195] Update airframe-json, airspec to 23.8.6 (#760) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 310ebe55..8f83f27d 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.8.1" +val AIRFRAME_VERSION = "23.8.6" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From e6d016a63aa44428bd53dbaae7df6a791c575138 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 21 Sep 2023 01:00:13 +0200 Subject: [PATCH 091/195] Update sbt to 1.9.6 (#763) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 0425ccf8..07960c01 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.4 +sbt.version=1.9.6 From 6ea9d91eaa1249dd15ab827881a03b0bbbb34ec2 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 21 Sep 2023 01:00:24 +0200 Subject: [PATCH 092/195] Update airframe-json, airspec to 23.9.1 (#762) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 8f83f27d..32c97172 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.8.6" +val AIRFRAME_VERSION = "23.9.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From c79ef243674b4b7465dae4cb7519a80d81121d5d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 21 Sep 2023 01:00:32 +0200 Subject: [PATCH 093/195] Update sbt-scalafmt to 2.5.2 (#761) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 2e2e4806..dd508b3b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") scalacOptions ++= Seq("-deprecation", "-feature") From c2c3a8f303eaf91572cee7592eb3d664e33f0cae Mon Sep 17 00:00:00 2001 From: Naoki Takezoe Date: Sun, 24 Sep 2023 09:36:13 +0900 Subject: [PATCH 094/195] Correct MessageUnpacker javadoc (#764) --- .../src/main/java/org/msgpack/core/MessageUnpacker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index 8da8d794..5a9a1a63 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -342,7 +342,7 @@ private static int utf8MultibyteCharacterSize(byte firstByte) } /** - * Returns true true if this unpacker has more elements. + * Returns true if this unpacker has more elements. * When this returns true, subsequent call to {@link #getNextFormat()} returns an * MessageFormat instance. If false, next {@link #getNextFormat()} call will throw an MessageInsufficientBufferException. * @@ -759,7 +759,7 @@ public void unpackNil() /** * Peeks a Nil byte and reads it if next byte is a nil value. * - * The difference from {@link unpackNil} is that unpackNil throws an exception if the next byte is not nil value + * The difference from {@link #unpackNil()} is that unpackNil throws an exception if the next byte is not nil value * while this tryUnpackNil method returns false without changing position. * * @return true if a nil value is read From ba1beabb4566a233e999d34b09c580feeab12a58 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 23 Sep 2023 20:53:46 -0700 Subject: [PATCH 095/195] feature: Support JDK21 (and drop JDK7 support) (#765) * feature: Support JDK21 * JDK21 doesn't support -source 1.7 option any more * Upgrade to Scala 2.13.12, which supports JDK21 * Use DirectByteBuffer(long, long) in JDK21 --- .github/workflows/CI.yml | 20 ++++++++- build.sbt | 8 ++-- .../core/buffer/DirectBufferAccess.java | 44 ++++++++++++------- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 74352654..57cc4eec 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -27,6 +27,24 @@ jobs: - uses: actions/checkout@v2 - name: jcheckstyle run: ./sbt jcheckStyle + test_jdk21: + name: Test JDK21 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '21' + - uses: actions/cache@v2 + with: + path: ~/.cache + key: ${{ runner.os }}-jdk21-${{ hashFiles('**/*.sbt') }} + restore-keys: ${{ runner.os }}-jdk21- + - name: Test + run: ./sbt test + - name: Universal Buffer Test + run: ./sbt test -J-Dmsgpack.universal-buffer=true test_jdk17: name: Test JDK17 runs-on: ubuntu-latest @@ -39,7 +57,7 @@ jobs: - uses: actions/cache@v2 with: path: ~/.cache - key: ${{ runner.os }}-jdk11-${{ hashFiles('**/*.sbt') }} + key: ${{ runner.os }}-jdk17-${{ hashFiles('**/*.sbt') }} restore-keys: ${{ runner.os }}-jdk17- - name: Test run: ./sbt test diff --git a/build.sbt b/build.sbt index 32c97172..3aa3c9c7 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,7 @@ val buildSettings = Seq[Setting[_]]( organizationName := "MessagePack", organizationHomepage := Some(new URL("http://msgpack.org/")), description := "MessagePack for Java", - scalaVersion := "2.13.6", + scalaVersion := "2.13.12", Test / logBuffered := false, // msgpack-java should be a pure-java library, so remove Scala specific configurations autoScalaLibrary := false, @@ -26,11 +26,11 @@ val buildSettings = Seq[Setting[_]]( // JVM options for building scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-feature"), Test / javaOptions ++= Seq("-ea"), - javacOptions ++= Seq("-source", "1.7", "-target", "1.7"), + javacOptions ++= Seq("-source", "1.8", "-target", "1.8"), Compile / compile / javacOptions ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation"), // Use lenient validation mode when generating Javadoc (for Java8) doc / javacOptions := { - val opts = Seq("-source", "1.7") + val opts = Seq("-source", "1.8") if (scala.util.Properties.isJavaAtLeast("1.8")) { opts ++ Seq("-Xdoclint:none") } else { @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.11.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.11.0" % "test" ) ) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java index f54c50b9..7b5ea461 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/DirectBufferAccess.java @@ -37,6 +37,7 @@ private DirectBufferAccess() enum DirectBufferConstructorType { + ARGS_LONG_LONG, ARGS_LONG_INT_REF, ARGS_LONG_INT, ARGS_INT_INT, @@ -64,28 +65,35 @@ enum DirectBufferConstructorType DirectBufferConstructorType constructorType = null; Method mbWrap = null; try { - // TODO We should use MethodHandle for Java7, which can avoid the cost of boxing with JIT optimization - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); - constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; + // JDK21 DirectByteBuffer(long, long) + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, long.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_LONG; } - catch (NoSuchMethodException e0) { + catch (NoSuchMethodException e00) { try { - // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java - // DirectByteBuffer(long address, int capacity) - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_LONG_INT; + // TODO We should use MethodHandle for Java7, which can avoid the cost of boxing with JIT optimization + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class, Object.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_INT_REF; } - catch (NoSuchMethodException e1) { + catch (NoSuchMethodException e0) { try { - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_INT_INT; + // https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/nio/DirectByteBuffer.java + // DirectByteBuffer(long address, int capacity) + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(long.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_LONG_INT; } - catch (NoSuchMethodException e2) { - Class aClass = Class.forName("java.nio.MemoryBlock"); - mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); - mbWrap.setAccessible(true); - directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(aClass, int.class, int.class); - constructorType = DirectBufferConstructorType.ARGS_MB_INT_INT; + catch (NoSuchMethodException e1) { + try { + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(int.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_INT_INT; + } + catch (NoSuchMethodException e2) { + Class aClass = Class.forName("java.nio.MemoryBlock"); + mbWrap = aClass.getDeclaredMethod("wrapFromJni", int.class, long.class); + mbWrap.setAccessible(true); + directByteBufferConstructor = directByteBufferClass.getDeclaredConstructor(aClass, int.class, int.class); + constructorType = DirectBufferConstructorType.ARGS_MB_INT_INT; + } } } } @@ -281,6 +289,8 @@ static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer } try { switch (directBufferConstructorType) { + case ARGS_LONG_LONG: + return (ByteBuffer) byteBufferConstructor.newInstance(address + index, (long) length); case ARGS_LONG_INT_REF: return (ByteBuffer) byteBufferConstructor.newInstance(address + index, length, reference); case ARGS_LONG_INT: From 3929eb362df2b55e70bd23548bfaa34f2774d18b Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 23 Sep 2023 20:54:10 -0700 Subject: [PATCH 096/195] internal: Automatically generate release notes (#766) --- .github/release.yml | 31 +++++++++++++++++++++++++++ .github/workflows/release-drafter.yml | 6 +----- .github/workflows/release-note.yml | 18 ++++++++++++++++ README.md | 4 ++-- 4 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 .github/release.yml create mode 100644 .github/workflows/release-note.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..973c3db6 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,31 @@ +changelog: + categories: + - title: '🔥 Breaking Changes' + labels: + - 'breaking' + - title: '👋 Deprecated' + labels: + - 'deprecation' + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'bug' + - title: '🔗 Dependency Updates' + labels: + - 'library-update' + - 'dependencies' + - title: '🛠 Internal Updates' + labels: + - 'internal' + - 'kaizen' + - 'test-library-update' + - 'sbt-plugin-update' + - title: '📚 Docs' + labels: + - 'doc' + - title: Other Changes + labels: + - "*" diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 3e173377..42d3901d 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -1,9 +1,6 @@ name: Release Drafter on: - push: - branches: - - main # pull_request event is required only for autolabeler pull_request: # Only following types are handled by the action, but one can default to all as well @@ -18,8 +15,7 @@ permissions: jobs: update_release_draft: permissions: - # write permission is required to create a github release - contents: write + contents: read # write permission is required for autolabeler # otherwise, read permission is required at least pull-requests: write diff --git a/.github/workflows/release-note.yml b/.github/workflows/release-note.yml new file mode 100644 index 00000000..ac290e4c --- /dev/null +++ b/.github/workflows/release-note.yml @@ -0,0 +1,18 @@ +name: Release Note + +on: + push: + tags: + - v* + workflow_dispatch: + +jobs: + release: + name: Create a new release note + runs-on: ubuntu-latest + steps: + - name: Create a release note + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "$GITHUB_REF_NAME" --repo="$GITHUB_REPOSITORY" --generate-notes diff --git a/README.md b/README.md index 8cad43c6..34a3f277 100644 --- a/README.md +++ b/README.md @@ -96,14 +96,14 @@ Here is a list of sbt commands for daily development: ### Publish to Sonatype (Maven Central) -To publish a new version, you only need to add a new git tag and push it to GitHub. GitHub Action will deploy a new release version to Maven Central (Sonatype). +To publish a new version, add a new git tag and push it to GitHub. GitHub Action will deploy a new release version to Maven Central (Sonatype). ```scala $ git tag v0.x.y $ git push origin v0.x.y ``` -A draft of the next release note will be updated automatically at the [GitHub Releases](https://github.com/msgpack/msgpack-java/releases) page. For each PR merged, [release-drafter](https://github.com/release-drafter/release-drafter) will modify the release note draft. When you create a new release tag, edit and publish the draft of the release note. If necessary, adjust the version number and target tag. +A new release note will be generated automatically at the [GitHub Releases](https://github.com/msgpack/msgpack-java/releases) page. #### Publishing to Sonatype from Local Machine From ce4410df705018b7e2e1e2667b4e71906c0b727b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 25 Sep 2023 18:23:41 +0200 Subject: [PATCH 097/195] Update airframe-json, airspec to 23.9.2 (#767) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3aa3c9c7..07146754 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.9.1" +val AIRFRAME_VERSION = "23.9.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 8d514ba31f050d4a1a11d4b6df9f303833c864d5 Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 1 Oct 2023 10:45:56 +0900 Subject: [PATCH 098/195] Add MessagePackMapper#handleBigIntegerAndBigDecimalAsString (#768) * Add MessagePackMapper#handleBigIntegerAndBigDecimalAsString * Rename unit test method names --- msgpack-jackson/README.md | 11 +-- .../jackson/dataformat/MessagePackMapper.java | 12 +++ .../dataformat/MessagePackMapperTest.java | 81 +++++++++++++++++-- 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/msgpack-jackson/README.md b/msgpack-jackson/README.md index e91c6f8b..0156453e 100644 --- a/msgpack-jackson/README.md +++ b/msgpack-jackson/README.md @@ -64,10 +64,10 @@ Or more easily: ObjectMapper objectMapper = new MessagePackMapper(); ``` -We strongly recommend to call `MessagePackMapper#handleBigDecimalAsString()` if you serialize and/or deserialize BigDecimal values. See [Serialize and deserialize BigDecimal as str type internally in MessagePack format](#serialize-and-deserialize-bigdecimal-as-str-type-internally-in-messagepack-format) for details. +We strongly recommend to call `MessagePackMapper#handleBigIntegerAndBigDecimalAsString()` if you serialize and/or deserialize BigInteger/BigDecimal values. See [Serialize and deserialize BigDecimal as str type internally in MessagePack format](#serialize-and-deserialize-bigdecimal-as-str-type-internally-in-messagepack-format) for details. ```java - ObjectMapper objectMapper = new MessagePackMapper().handleBigDecimalAsString(); + ObjectMapper objectMapper = new MessagePackMapper().handleBigIntegerAndBigDecimalAsString(); ``` ### Serialization/Deserialization of List @@ -232,10 +232,10 @@ When you want to use non-String value as a key of Map, use `MessagePackKeySerial ### Serialize and deserialize BigDecimal as str type internally in MessagePack format -`jackson-dataformat-msgpack` represents BigDecimal values as float type in MessagePack format by default for backward compatibility. But the default behavior could fail when handling too large value for `double` type. So we strongly recommend to call `MessagePackMapper#handleBigDecimalAsString()` to internally handle BigDecimal values as String. +`jackson-dataformat-msgpack` represents BigDecimal values as float type in MessagePack format by default for backward compatibility. But the default behavior could fail when handling too large value for `double` type. So we strongly recommend to call `MessagePackMapper#handleBigIntegerAndBigDecimalAsString()` to internally handle BigDecimal values as String. ```java - ObjectMapper objectMapper = new MessagePackMapper().handleBigDecimalAsString(); + ObjectMapper objectMapper = new MessagePackMapper().handleBigIntegerAndBigDecimalAsString(); Pojo obj = new Pojo(); // This value is too large to be serialized as double @@ -245,10 +245,11 @@ When you want to use non-String value as a key of Map, use `MessagePackKeySerial System.out.println(objectMapper.readValue(converted, Pojo.class)); // => Pojo{value=1234567890.98765432100} ``` -`MessagePackMapper#handleBigDecimalAsString()` is equivalent to the following configuration. +`MessagePackMapper#handleBigIntegerAndDecimalAsString()` is equivalent to the following configuration. ```java ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + objectMapper.configOverride(BigInteger.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); objectMapper.configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); ``` diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java index 52af0372..144c8d1a 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackMapper.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.cfg.MapperBuilder; import java.math.BigDecimal; +import java.math.BigInteger; public class MessagePackMapper extends ObjectMapper { @@ -43,12 +44,23 @@ public MessagePackMapper(MessagePackFactory f) super(f); } + public MessagePackMapper handleBigIntegerAsString() + { + configOverride(BigInteger.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); + return this; + } + public MessagePackMapper handleBigDecimalAsString() { configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING)); return this; } + public MessagePackMapper handleBigIntegerAndBigDecimalAsString() + { + return handleBigIntegerAsString().handleBigDecimalAsString(); + } + public static Builder builder() { return new Builder(new MessagePackMapper()); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java index 6dfd41cf..68721fce 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java @@ -15,30 +15,97 @@ // package org.msgpack.jackson.dataformat; +import com.fasterxml.jackson.core.JsonProcessingException; import org.junit.Test; import java.io.IOException; import java.math.BigDecimal; +import java.math.BigInteger; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class MessagePackMapperTest { - static class Pojo + static class PojoWithBigInteger + { + public BigInteger value; + } + + static class PojoWithBigDecimal { public BigDecimal value; } - @Test - public void handleBigDecimalAsString() throws IOException + private void shouldFailToHandleBigInteger(MessagePackMapper messagePackMapper) throws JsonProcessingException + { + PojoWithBigInteger obj = new PojoWithBigInteger(); + obj.value = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(10)); + + try { + messagePackMapper.writeValueAsBytes(obj); + fail(); + } + catch (IllegalArgumentException e) { + // Expected + } + } + + private void shouldSuccessToHandleBigInteger(MessagePackMapper messagePackMapper) throws IOException { - MessagePackMapper mapper = new MessagePackMapper().handleBigDecimalAsString(); - Pojo obj = new Pojo(); + PojoWithBigInteger obj = new PojoWithBigInteger(); + obj.value = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(10)); + + byte[] converted = messagePackMapper.writeValueAsBytes(obj); + + PojoWithBigInteger deserialized = messagePackMapper.readValue(converted, PojoWithBigInteger.class); + assertEquals(obj.value, deserialized.value); + } + + private void shouldFailToHandleBigDecimal(MessagePackMapper messagePackMapper) throws JsonProcessingException + { + PojoWithBigDecimal obj = new PojoWithBigDecimal(); obj.value = new BigDecimal("1234567890.98765432100"); - byte[] converted = mapper.writeValueAsBytes(obj); + try { + messagePackMapper.writeValueAsBytes(obj); + fail(); + } + catch (IllegalArgumentException e) { + // Expected + } + } - Pojo deserialized = mapper.readValue(converted, Pojo.class); + private void shouldSuccessToHandleBigDecimal(MessagePackMapper messagePackMapper) throws IOException + { + PojoWithBigDecimal obj = new PojoWithBigDecimal(); + obj.value = new BigDecimal("1234567890.98765432100"); + + byte[] converted = messagePackMapper.writeValueAsBytes(obj); + + PojoWithBigDecimal deserialized = messagePackMapper.readValue(converted, PojoWithBigDecimal.class); assertEquals(obj.value, deserialized.value); } + + @Test + public void handleBigIntegerAsString() throws IOException + { + shouldFailToHandleBigInteger(new MessagePackMapper()); + shouldSuccessToHandleBigInteger(new MessagePackMapper().handleBigIntegerAsString()); + } + + @Test + public void handleBigDecimalAsString() throws IOException + { + shouldFailToHandleBigDecimal(new MessagePackMapper()); + shouldSuccessToHandleBigDecimal(new MessagePackMapper().handleBigDecimalAsString()); + } + + @Test + public void handleBigIntegerAndBigDecimalAsString() throws IOException + { + MessagePackMapper messagePackMapper = new MessagePackMapper().handleBigIntegerAndBigDecimalAsString(); + shouldSuccessToHandleBigInteger(messagePackMapper); + shouldSuccessToHandleBigDecimal(messagePackMapper); + } } From f9ca6d45fa75b916e450925faeb78341d0a4c6c1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 4 Oct 2023 01:34:37 +0200 Subject: [PATCH 099/195] Update airframe-json, airspec to 23.9.3 (#769) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 07146754..29b1b6fe 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.9.2" +val AIRFRAME_VERSION = "23.9.3" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From bb16a9287f22474ada0d1f468c34a332908a2571 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:01:59 +0200 Subject: [PATCH 100/195] Update airframe-json, airspec to 23.10.0 (#772) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 29b1b6fe..939ba2a3 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.9.3" +val AIRFRAME_VERSION = "23.10.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 89391fcbd0a9a3d7fd5d7bc6c93880260a02c4fc Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Fri, 20 Oct 2023 04:02:22 +0900 Subject: [PATCH 101/195] use `setup-java` instead of deprecated `olafurpg/setup-scala` (#770) use setup-java instead of deprecated olafurpg/setup-scala --- .github/workflows/release.yml | 5 +++-- .github/workflows/snapshot.yml | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d105d9d1..1f04d480 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,10 +17,11 @@ jobs: # Fetch all tags so that sbt-dynver can find the previous release version - run: git fetch --tags -f # Install OpenJDK 8 - - uses: olafurpg/setup-scala@v10 + - uses: actions/setup-java@v3 with: # We need to use JDK8 for Android compatibility https://github.com/msgpack/msgpack-java/issues/516 - java-version: adopt@1.8 + java-version: 8 + distribution: adopt - name: Setup GPG env: PGP_SECRET: ${{ secrets.PGP_SECRET }} diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index e244adfd..779f3878 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -21,9 +21,10 @@ jobs: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version - run: git fetch --tags - - uses: olafurpg/setup-scala@v10 + - uses: actions/setup-java@v3 with: - java-version: adopt@1.11 + java-version: 11 + distribution: adopt - name: Publish snapshots env: SONATYPE_USERNAME: '${{ secrets.SONATYPE_USER }}' From 8b1cbfb3676f55198a2aa7ccd1458828cbc8ae2c Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:02:49 +0200 Subject: [PATCH 102/195] Update sbt-osgi to 0.9.7 (#773) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index dd508b3b..e0d54272 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") -addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.9.6") +addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.7") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") From f3ecdb0582a8782432c28f0f6a9d6cf52000439d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:03:00 +0200 Subject: [PATCH 103/195] Update jackson-databind to 2.15.3 (#771) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 939ba2a3..cd65409f 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.15.2", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.15.3", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 85ffcca77adfcb90250f8a5b46dc4a0e1671e711 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 24 Oct 2023 06:03:09 +0200 Subject: [PATCH 104/195] Update sbt-osgi to 0.9.8 (#774) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index e0d54272..326aaa78 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") -addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.7") +addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.8") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") From 25be735d83bb2855cdc4537860c476dec9ead851 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:21:22 +0200 Subject: [PATCH 105/195] Update sbt to 1.9.7 (#775) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 07960c01..d9282559 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.6 +sbt.version=1.9.7 From d9ed10348a388c0b8e86f65536c9334c989a2e0f Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sat, 28 Oct 2023 05:45:33 +0900 Subject: [PATCH 106/195] (internal): Add `dependabot.yml` for GitHub Actions update (#776) add dependabot.yml --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5ace4600 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From b35e7ee6eb56f18dcb8f9a50f473b3d808af47de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:01:52 -0700 Subject: [PATCH 107/195] Bump actions/checkout from 2 to 4 (#777) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 10 +++++----- .github/workflows/release.yml | 2 +- .github/workflows/snapshot.yml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 57cc4eec..44e8ff07 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -24,14 +24,14 @@ jobs: name: Code Format runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: jcheckstyle run: ./sbt jcheckStyle test_jdk21: name: Test JDK21 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-java@v3 with: distribution: 'zulu' @@ -49,7 +49,7 @@ jobs: name: Test JDK17 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-java@v3 with: distribution: 'zulu' @@ -67,7 +67,7 @@ jobs: name: Test JDK11 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-java@v3 with: distribution: 'zulu' @@ -85,7 +85,7 @@ jobs: name: Test JDK8 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-java@v3 with: distribution: 'zulu' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f04d480..0060b06f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: name: Release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 779f3878..e24088f7 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -16,7 +16,7 @@ jobs: name: Publish snapshots runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version From 7826391dfdbfd18fdaa523c933e43a7c44f3716a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:02:04 -0700 Subject: [PATCH 108/195] Bump actions/cache from 2 to 3 (#778) Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 44e8ff07..6a18e486 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -36,7 +36,7 @@ jobs: with: distribution: 'zulu' java-version: '21' - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: ~/.cache key: ${{ runner.os }}-jdk21-${{ hashFiles('**/*.sbt') }} @@ -54,7 +54,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: ~/.cache key: ${{ runner.os }}-jdk17-${{ hashFiles('**/*.sbt') }} @@ -72,7 +72,7 @@ jobs: with: distribution: 'zulu' java-version: '11' - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: ~/.cache key: ${{ runner.os }}-jdk11-${{ hashFiles('**/*.sbt') }} @@ -90,7 +90,7 @@ jobs: with: distribution: 'zulu' java-version: '8' - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: ~/.cache key: ${{ runner.os }}-jdk8-${{ hashFiles('**/*.sbt') }} From 6c8d683c9203e58f118a4a04eb954f58921d27f6 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 16 Nov 2023 06:09:11 +0100 Subject: [PATCH 109/195] Update airframe-json, airspec to 23.11.3 (#781) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index cd65409f..dc5a2c23 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.10.0" +val AIRFRAME_VERSION = "23.11.3" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 8d6ab473a1db518d458d8f6e653db06ee0d4f886 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 16 Nov 2023 06:09:24 +0100 Subject: [PATCH 110/195] Update sbt-osgi to 0.9.9 (#779) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 326aaa78..9ab759bd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") -addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.8") +addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.9") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") From 87cac7173f3ef410b14362a6bf3a43a3ac3cdece Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 18 Nov 2023 23:38:57 +0100 Subject: [PATCH 111/195] Update sbt-sonatype to 3.10.0 (#783) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 9ab759bd..ba0a0c26 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.21") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.10.0") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From 938a43755643e1c6159aac1b9523c7e00fa70250 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:19:46 -0800 Subject: [PATCH 112/195] Bump actions/setup-java from 3 to 4 (#784) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 8 ++++---- .github/workflows/release.yml | 2 +- .github/workflows/snapshot.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6a18e486..7732559a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '21' @@ -50,7 +50,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '17' @@ -68,7 +68,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '11' @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '8' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0060b06f..b214d8ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: # Fetch all tags so that sbt-dynver can find the previous release version - run: git fetch --tags -f # Install OpenJDK 8 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: # We need to use JDK8 for Android compatibility https://github.com/msgpack/msgpack-java/issues/516 java-version: 8 diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index e24088f7..cbce4c14 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -21,7 +21,7 @@ jobs: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version - run: git fetch --tags - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: java-version: 11 distribution: adopt From 41168e92efa8623e3e7e518bb72d4ae8978f9a27 Mon Sep 17 00:00:00 2001 From: Fang Zheng Date: Tue, 9 Jan 2024 15:22:34 -0800 Subject: [PATCH 113/195] Fix fixint test in MessagePackTest. (#785) --- .../src/test/scala/org/msgpack/core/MessagePackTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 4f6949bd..c2993f96 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -78,7 +78,7 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { test("detect fixint values") { - for (i <- 0 until 0x79) { + for (i <- 0 until 0x7f) { Code.isPosFixInt(i.toByte) shouldBe true } From cc2ce77c70df9210c41269deaf43f041768e0541 Mon Sep 17 00:00:00 2001 From: Fang Zheng Date: Tue, 9 Jan 2024 15:24:29 -0800 Subject: [PATCH 114/195] internal: Remove dead code in MessagePacker. (#787) --- .../src/main/java/org/msgpack/core/MessagePacker.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java index 4cf789d9..72c26eca 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java @@ -774,10 +774,6 @@ else if (s.length() < (1 << 16)) { position += written; } else { - if (written >= (1L << 32)) { // this check does nothing because (1L << 32) is larger than Integer.MAX_VALUE - // this must not happen because s.length() is less than 2^16 and (2^16) * UTF_8_MAX_CHAR_SIZE is less than 2^32 - throw new IllegalArgumentException("Unexpected UTF-8 encoder state"); - } // move 2 bytes backward to expand 3-byte header region to 5 bytes buffer.putMessageBuffer(position + 5, buffer, position + 3, written); // write 3-byte header header From 532199e454ec912082cecb08d3cf08cf0a277d74 Mon Sep 17 00:00:00 2001 From: Fang Zheng Date: Tue, 9 Jan 2024 15:35:11 -0800 Subject: [PATCH 115/195] Fix bug in ImmutableTimestampValueImpl. (#786) * Fix bug in ImmutableTimestampValueImpl. * Fix code style --------- Co-authored-by: Taro L. Saito --- .../org/msgpack/value/impl/ImmutableTimestampValueImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java index 227c85d0..1891d9a7 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java +++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java @@ -93,7 +93,7 @@ public byte[] getData() long sec = getEpochSecond(); int nsec = getNano(); if (sec >>> 34 == 0) { - long data64 = (nsec << 34) | sec; + long data64 = ((long) nsec << 34) | sec; if ((data64 & 0xffffffff00000000L) == 0L) { bytes = new byte[4]; MessageBuffer.wrap(bytes).putInt(0, (int) sec); From 69354a047e789c9bf5f24dcb4ace4875d0569e9b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 13 Jan 2024 01:34:40 +0100 Subject: [PATCH 116/195] Update sbt to 1.9.8 (#790) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index d9282559..e5ca1ff5 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.7 +sbt.version=1.9.8 From dc7d6031aaa603db3f622c54da7a8feb6fb256c2 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 13 Jan 2024 01:34:49 +0100 Subject: [PATCH 117/195] Update sbt-osgi to 0.9.10 (#789) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index ba0a0c26..7f518088 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") -addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.9") +addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.10") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") From cedc35ceaef2ae0ea67a9a9df3747c4d18d70a3e Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 13 Jan 2024 01:34:57 +0100 Subject: [PATCH 118/195] Update airframe-json, airspec to 23.12.1 (#791) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index dc5a2c23..77dd06dd 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.11.3" +val AIRFRAME_VERSION = "23.12.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From a1a61f855b46e60e6fa3de7c6ffec7e7f03eb666 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sun, 14 Jan 2024 22:27:46 +0100 Subject: [PATCH 119/195] Update airframe-json, airspec to 24.1.0 (#792) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 77dd06dd..9716d20c 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "23.12.1" +val AIRFRAME_VERSION = "24.1.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 42daf717347d774b478a8ab0950c7f8a4c816534 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 18 Jan 2024 19:22:18 +0100 Subject: [PATCH 120/195] Update airframe-json, airspec to 24.1.1 (#793) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 9716d20c..4ad39cd8 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.1.0" +val AIRFRAME_VERSION = "24.1.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 4bdaf8e35f130e561ca964b578bbe696c4d1dd9f Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 18 Jan 2024 19:23:33 +0100 Subject: [PATCH 121/195] Update jackson-databind to 2.16.1 (#788) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4ad39cd8..3bfc9133 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.15.3", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.16.1", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 480fd736bac5b02657c566af2d32a0674c64d370 Mon Sep 17 00:00:00 2001 From: Naoki Takezoe Date: Sun, 21 Jan 2024 14:49:03 +0900 Subject: [PATCH 122/195] Fix ClassCastException when array values is set as List (#794) --- msgpack-core/src/main/java/org/msgpack/value/Variable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack-core/src/main/java/org/msgpack/value/Variable.java b/msgpack-core/src/main/java/org/msgpack/value/Variable.java index ae88170c..85d2fb3b 100644 --- a/msgpack-core/src/main/java/org/msgpack/value/Variable.java +++ b/msgpack-core/src/main/java/org/msgpack/value/Variable.java @@ -817,7 +817,7 @@ public Variable setArrayValue(List v) { this.type = Type.LIST; this.accessor = arrayAccessor; - this.objectValue = v.toArray(); + this.objectValue = v.toArray(new Value[v.size()]); return this; } From a2ff390cea9f0e92dc0805ebeff05b9e70b264ba Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:12:21 +0100 Subject: [PATCH 123/195] Update sbt-osgi to 0.9.11 (#796) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 7f518088..33b8bfb5 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") -addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.10") +addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.11") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") From 964800ec3abc4f2f64b0598083cbf0ef51c0a3a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:12:30 -0800 Subject: [PATCH 124/195] Bump actions/cache from 3 to 4 (#795) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7732559a..7ff24e9b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -36,7 +36,7 @@ jobs: with: distribution: 'zulu' java-version: '21' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.cache key: ${{ runner.os }}-jdk21-${{ hashFiles('**/*.sbt') }} @@ -54,7 +54,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.cache key: ${{ runner.os }}-jdk17-${{ hashFiles('**/*.sbt') }} @@ -72,7 +72,7 @@ jobs: with: distribution: 'zulu' java-version: '11' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.cache key: ${{ runner.os }}-jdk11-${{ hashFiles('**/*.sbt') }} @@ -90,7 +90,7 @@ jobs: with: distribution: 'zulu' java-version: '8' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.cache key: ${{ runner.os }}-jdk8-${{ hashFiles('**/*.sbt') }} From a1796398f331a8f94316a3ab9e52e0869d3ddb62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:34:11 -0800 Subject: [PATCH 125/195] Bump release-drafter/release-drafter from 5 to 6 (#798) Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5 to 6. - [Release notes](https://github.com/release-drafter/release-drafter/releases) - [Commits](https://github.com/release-drafter/release-drafter/compare/v5...v6) --- updated-dependencies: - dependency-name: release-drafter/release-drafter dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 42d3901d..f77373a9 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -22,6 +22,6 @@ jobs: runs-on: ubuntu-latest steps: # Drafts your next Release notes as Pull Requests are merged into "master" - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From fd386138fec6f2a469516dcb2b113dc66e6247e8 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 6 Feb 2024 01:34:21 +0100 Subject: [PATCH 126/195] Update sbt-osgi to 0.10.0 (#797) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 33b8bfb5..aa41287b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") -addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.9.11") +addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") From 750a07c73329f9ab1e1b6d55c6b199093df9be0b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 21 Feb 2024 18:21:12 +0100 Subject: [PATCH 127/195] Update airframe-json, airspec to 24.1.2 (#801) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3bfc9133..e4bf7dad 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.1.1" +val AIRFRAME_VERSION = "24.1.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From b917abce56c83beca17a28e6a9f005206b4a9a48 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 6 Mar 2024 06:11:47 +0100 Subject: [PATCH 128/195] Update sbt to 1.9.9 (#803) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index e5ca1ff5..b089b60c 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.8 +sbt.version=1.9.9 From 55d774a0976ce7bad569deabdb88c62b336880fb Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 6 Mar 2024 06:12:06 +0100 Subject: [PATCH 129/195] Update airframe-json, airspec to 24.3.0 (#807) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index e4bf7dad..69cac77a 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.1.2" +val AIRFRAME_VERSION = "24.3.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 690f5effcb731353a28b34cdd441eddd1931564e Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 24 Apr 2024 00:23:06 +0200 Subject: [PATCH 130/195] Update airframe-json, airspec to 24.4.2 (#817) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 69cac77a..35eb5564 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.3.0" +val AIRFRAME_VERSION = "24.4.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 5f273cf4f6ff1ec327701fef613dabc968230ac7 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 24 Apr 2024 00:23:16 +0200 Subject: [PATCH 131/195] Update scalacheck to 1.17.1 (#815) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 35eb5564..4987196b 100644 --- a/build.sbt +++ b/build.sbt @@ -87,7 +87,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.17.0" % "test", + "org.scalacheck" %% "scalacheck" % "1.17.1" % "test", // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka From d13e6b10e648fbe41bf3f6aa555aa11fb7168a9a Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 24 Apr 2024 00:23:25 +0200 Subject: [PATCH 132/195] Update scala-collection-compat to 2.12.0 (#814) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4987196b..c63a53fa 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.11.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.12.0" % "test" ) ) From 6d0516ec9e53d269f1f208d5af99f439bfda8e5f Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:56:54 +0200 Subject: [PATCH 133/195] Update airframe-json, airspec to 24.4.3 (#820) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c63a53fa..a1c02e10 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.4.2" +val AIRFRAME_VERSION = "24.4.3" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 577c474a9d069ce855772a13c56a7c8b3bbe2d5c Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:57:01 +0200 Subject: [PATCH 134/195] Update scalacheck to 1.18.0 (#819) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index a1c02e10..fa2cb782 100644 --- a/build.sbt +++ b/build.sbt @@ -87,7 +87,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.17.1" % "test", + "org.scalacheck" %% "scalacheck" % "1.18.0" % "test", // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka From 141f66dd615e797c96113169371d1767b251a0ae Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:57:20 +0200 Subject: [PATCH 135/195] Update jackson-databind to 2.16.2 (#811) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index fa2cb782..6042dbcd 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.16.1", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.16.2", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), From 29a44afbc1cbbe7be771897f322cb0b5649dee0b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 8 May 2024 02:46:22 +0200 Subject: [PATCH 136/195] Update sbt to 1.10.0 (#823) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index b089b60c..16c8f5b8 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.9.9 +sbt.version=1.10.0 From 50cf4098c398026a5afe8fd11f43f96f3756cf91 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 8 May 2024 02:46:33 +0200 Subject: [PATCH 137/195] Update airframe-json, airspec to 24.5.0 (#824) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6042dbcd..a456a489 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.4.3" +val AIRFRAME_VERSION = "24.5.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From fedf7ac8c57f4e73b74d30980472a468bbc0a715 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:01:42 +0200 Subject: [PATCH 138/195] Update airframe-json, airspec to 24.5.2 (#826) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index a456a489..0c9f0898 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.5.0" +val AIRFRAME_VERSION = "24.5.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From a3590929a04c91b93db1c9be51589b3ca5275e69 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:31:44 +0200 Subject: [PATCH 139/195] Update airframe-json, airspec to 24.7.0 (#829) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 0c9f0898..5ecd8cdc 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.5.2" +val AIRFRAME_VERSION = "24.7.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From abdab0deae9d0c52742f7271a85db53c8dc382ef Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 16 Jul 2024 19:42:36 +0200 Subject: [PATCH 140/195] Update sbt to 1.10.1 (#831) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 16c8f5b8..74d800f2 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.0 +sbt.version=1.10.1 From ba386c3a7c4ad1e973510a44d6c6a2652675d331 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 22 Jul 2024 20:03:33 +0200 Subject: [PATCH 141/195] Update airframe-json, airspec to 24.7.1 (#832) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5ecd8cdc..4087d23b 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.7.0" +val AIRFRAME_VERSION = "24.7.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 72ead7ea34e0171de1c82d43b3faeeb33ca999fc Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:55:52 +0200 Subject: [PATCH 142/195] Update airframe-json, airspec to 24.9.0 (#837) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4087d23b..b57a6e10 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.7.1" +val AIRFRAME_VERSION = "24.9.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 4fb85a52caf17703053351e786fc688d4cad6aca Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 26 Sep 2024 01:33:40 +0200 Subject: [PATCH 143/195] Update sbt to 1.10.2 (#839) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 74d800f2..a1ff42a6 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.1 +sbt.version=1.10.2 From 1b51be899ad61b1a1e7cae9d8ae9ca478274b99b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 26 Sep 2024 01:33:49 +0200 Subject: [PATCH 144/195] Update scalacheck to 1.18.1 (#840) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index b57a6e10..a102c0c4 100644 --- a/build.sbt +++ b/build.sbt @@ -87,7 +87,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.18.0" % "test", + "org.scalacheck" %% "scalacheck" % "1.18.1" % "test", // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka From 6b26ad66c869493b960a8ab7a28571068ac982f2 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 8 Oct 2024 02:21:04 +0200 Subject: [PATCH 145/195] Update airframe-json, airspec to 24.9.3 (#844) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index a102c0c4..f76b603a 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.9.0" +val AIRFRAME_VERSION = "24.9.3" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 76bc7d0caac175cf55db47c2a76c2b0af9689283 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 8 Oct 2024 02:23:43 +0200 Subject: [PATCH 146/195] Update sbt-pgp to 2.3.0 (#845) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index aa41287b..5d631aae 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.10.0") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") From c48f6594accf3467ce1e97f42a16dd788733ae01 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:45:04 +0200 Subject: [PATCH 147/195] Update sbt-sonatype to 3.12.0 (#846) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 5d631aae..34401fa5 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.10.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.0") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From 933b0f2b717f7835095fef2a8b499ed42409ea98 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:53:06 +0100 Subject: [PATCH 148/195] Update sbt, scripted-plugin to 1.10.4 (#852) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index a1ff42a6..3769c4af 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.2 +sbt.version=1.10.4 From 093837ea3f96ec12a0c0475b67f83c4a7c929d7d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:53:19 +0100 Subject: [PATCH 149/195] Update airframe-json, airspec to 24.10.0 (#850) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index f76b603a..c94b9c3a 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.9.3" +val AIRFRAME_VERSION = "24.10.0" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 067e0d9b05905805dc65f19cbb6c6da7dae7bbb0 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:53:28 +0100 Subject: [PATCH 150/195] Update sbt-sonatype to 3.12.2 (#847) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 34401fa5..3df907dc 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter From b6bae5b101ba021f2a139d8dbb60160a75822d7c Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:53:38 +0100 Subject: [PATCH 151/195] Update sbt-dynver to 5.1.0 (#848) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 3df907dc..912d52f1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,6 +6,6 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") -addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1") +addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.0") scalacOptions ++= Seq("-deprecation", "-feature") From ba0c44fe09313431db0c08fd8f98496cbed3aae7 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Tue, 5 Nov 2024 04:56:37 +0900 Subject: [PATCH 152/195] internal: Avoid deprecated `java.net.URL` constructor (#853) avoid deprecated java.net.URL constructor --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c94b9c3a..ff396aa2 100644 --- a/build.sbt +++ b/build.sbt @@ -15,7 +15,7 @@ ThisBuild / dynverSeparator := "-" val buildSettings = Seq[Setting[_]]( organization := "org.msgpack", organizationName := "MessagePack", - organizationHomepage := Some(new URL("http://msgpack.org/")), + organizationHomepage := Some(url("http://msgpack.org/")), description := "MessagePack for Java", scalaVersion := "2.13.12", Test / logBuffered := false, From 84fd19761feeb5ec073ed238fb00498bd04994bd Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 5 Nov 2024 21:16:37 +0100 Subject: [PATCH 153/195] Update sbt, scripted-plugin to 1.10.5 (#854) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 3769c4af..30c85e4f 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.4 +sbt.version=1.10.5 From 5161c53c1d3d7760bff84287ecae98c72b9190ea Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sat, 30 Nov 2024 16:35:36 +0900 Subject: [PATCH 154/195] Bump the version of `jackson-databind` (#858) --- build.sbt | 2 +- .../jackson/dataformat/JsonArrayFormat.java | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/build.sbt b/build.sbt index ff396aa2..4a4b2301 100644 --- a/build.sbt +++ b/build.sbt @@ -109,7 +109,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.16.2", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.18.2", junitInterface, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JsonArrayFormat.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JsonArrayFormat.java index 9711e1b8..39155030 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JsonArrayFormat.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JsonArrayFormat.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.AnnotatedClass; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import static com.fasterxml.jackson.annotation.JsonFormat.Shape.ARRAY; @@ -33,21 +32,4 @@ public JsonFormat.Value findFormat(Annotated ann) return ARRAY_FORMAT; } - - /** - * Defines that unknown properties will be ignored, and won't fail the un-marshalling process. - * Happens in case of de-serialization of a payload that contains more properties than the actual - * value type - */ - @Override - public Boolean findIgnoreUnknownProperties(AnnotatedClass ac) - { - // If the entity contains JsonIgnoreProperties annotation, give it higher priority. - final Boolean precedenceIgnoreUnknownProperties = super.findIgnoreUnknownProperties(ac); - if (precedenceIgnoreUnknownProperties != null) { - return precedenceIgnoreUnknownProperties; - } - - return true; - } } From 33ba1ea6260230a5d46ccd2fe1f64071733eee30 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 11 Dec 2024 19:05:02 +0100 Subject: [PATCH 155/195] Update sbt-pgp to 2.3.1 (#862) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 912d52f1..e702479f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") From c7907ad886cbf734ae18131ac0553d51baf5965b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 11 Dec 2024 19:05:11 +0100 Subject: [PATCH 156/195] Update airframe-json, airspec to 24.12.1 (#860) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4a4b2301..ff74b955 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.10.0" +val AIRFRAME_VERSION = "24.12.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From d2b328e105b567d394d4e58b8d87fdad392db874 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Wed, 11 Dec 2024 19:05:21 +0100 Subject: [PATCH 157/195] Update sbt, scripted-plugin to 1.10.6 (#859) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 30c85e4f..e0a0e7d1 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.5 +sbt.version=1.10.6 From e03d60d0808a021273bdab3a43e59330f6eb8e5c Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:32:44 +0100 Subject: [PATCH 158/195] Update airframe-json, airspec to 24.12.2 (#863) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index ff74b955..31280a69 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.12.1" +val AIRFRAME_VERSION = "24.12.2" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 56c0e5ac95c8037958b29eaf53fe591978e20c7d Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 24 Dec 2024 00:23:58 +0100 Subject: [PATCH 159/195] Update sbt, scripted-plugin to 1.10.7 (#865) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index e0a0e7d1..8fc29878 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.6 +sbt.version=1.10.7 From 59219838ffb6236eca84601dad1dd267541c070b Mon Sep 17 00:00:00 2001 From: Mitsunori Komatsu Date: Sun, 5 Jan 2025 19:48:24 +0900 Subject: [PATCH 160/195] Improve the performance of `jackson-dataformat-msgpack` (#866) * Improve the perf of msgpack-jackson * Refactoring --- .../ExtensionTypeCustomDeserializers.java | 10 +- .../msgpack/jackson/dataformat/JavaInfo.java | 41 ++ .../dataformat/MessagePackExtensionType.java | 5 +- .../dataformat/MessagePackFactory.java | 20 +- .../dataformat/MessagePackGenerator.java | 646 +++++++++++------- .../dataformat/MessagePackKeySerializer.java | 3 +- .../jackson/dataformat/MessagePackParser.java | 277 +++----- .../dataformat/MessagePackReadContext.java | 269 ++++++++ .../MessagePackSerializedString.java | 8 +- .../MessagePackDataformatForPojoTest.java | 36 +- .../MessagePackDataformatTestBase.java | 44 +- .../dataformat/MessagePackGeneratorTest.java | 49 +- ...essagePackDataformatPojoBenchmarkTest.java | 28 +- 13 files changed, 946 insertions(+), 490 deletions(-) create mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JavaInfo.java create mode 100644 msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackReadContext.java diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/ExtensionTypeCustomDeserializers.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/ExtensionTypeCustomDeserializers.java index ae2e6353..aa587975 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/ExtensionTypeCustomDeserializers.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/ExtensionTypeCustomDeserializers.java @@ -35,15 +35,7 @@ public ExtensionTypeCustomDeserializers(ExtensionTypeCustomDeserializers src) public void addCustomDeser(byte type, final Deser deser) { - deserTable.put(type, new Deser() - { - @Override - public Object deserialize(byte[] data) - throws IOException - { - return deser.deserialize(data); - } - }); + deserTable.put(type, deser); } public Deser getDeser(byte type) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JavaInfo.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JavaInfo.java new file mode 100644 index 00000000..f5fda8c2 --- /dev/null +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/JavaInfo.java @@ -0,0 +1,41 @@ +// +// MessagePack for Java +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.jackson.dataformat; + +import java.lang.reflect.Field; +import java.util.function.Supplier; + +public final class JavaInfo +{ + static final Supplier STRING_VALUE_FIELD_IS_CHARS; + static { + boolean stringValueFieldIsChars = false; + try { + Field stringValueField = String.class.getDeclaredField("value"); + stringValueFieldIsChars = stringValueField.getType() == char[].class; + } + catch (NoSuchFieldException ignored) { + } + if (stringValueFieldIsChars) { + STRING_VALUE_FIELD_IS_CHARS = () -> true; + } + else { + STRING_VALUE_FIELD_IS_CHARS = () -> false; + } + } + + private JavaInfo() {} +} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java index 00b4f7de..e11c2cd0 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackExtensionType.java @@ -1,7 +1,6 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -52,7 +51,7 @@ public boolean equals(Object o) @Override public int hashCode() { - int result = (int) type; + int result = type; result = 31 * result + Arrays.hashCode(data); return result; } @@ -61,7 +60,7 @@ public static class Serializer extends JsonSerializer { @Override public void serialize(MessagePackExtensionType value, JsonGenerator gen, SerializerProvider serializers) - throws IOException, JsonProcessingException + throws IOException { if (gen instanceof MessagePackGenerator) { MessagePackGenerator msgpackGenerator = (MessagePackGenerator) gen; diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index 1e7acc5e..bb5064f1 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -18,7 +18,6 @@ import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.io.IOContext; import org.msgpack.core.MessagePack; @@ -97,14 +96,13 @@ public JsonGenerator createGenerator(File f, JsonEncoding enc) @Override public JsonGenerator createGenerator(Writer w) - throws IOException { throw new UnsupportedOperationException(); } @Override public JsonParser createParser(byte[] data) - throws IOException, JsonParseException + throws IOException { IOContext ioContext = _createContext(data, false); return _createParser(data, 0, data.length, ioContext); @@ -112,7 +110,7 @@ public JsonParser createParser(byte[] data) @Override public JsonParser createParser(InputStream in) - throws IOException, JsonParseException + throws IOException { IOContext ioContext = _createContext(in, false); return _createParser(in, ioContext); @@ -131,7 +129,7 @@ protected MessagePackParser _createParser(InputStream in, IOContext ctxt) @Override protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt) - throws IOException, JsonParseException + throws IOException { if (offset != 0 || len != data.length) { data = Arrays.copyOfRange(data, offset, offset + len); @@ -155,12 +153,6 @@ MessagePack.PackerConfig getPackerConfig() return packerConfig; } - @VisibleForTesting - boolean isReuseResourceInGenerator() - { - return reuseResourceInGenerator; - } - @VisibleForTesting boolean isReuseResourceInParser() { @@ -178,4 +170,10 @@ public String getFormatName() { return "msgpack"; } + + @Override + public boolean canHandleBinaryNatively() + { + return true; + } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 96aa6a06..11aba6e5 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -16,14 +16,14 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.core.Base64Variant; -import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.SerializableString; import com.fasterxml.jackson.core.base.GeneratorBase; import com.fasterxml.jackson.core.io.SerializedString; -import com.fasterxml.jackson.core.json.JsonWriteContext; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; +import org.msgpack.core.annotations.Nullable; +import org.msgpack.core.buffer.MessageBufferOutput; import org.msgpack.core.buffer.OutputStreamBufferOutput; import java.io.ByteArrayOutputStream; @@ -33,73 +33,170 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; +import static org.msgpack.jackson.dataformat.JavaInfo.STRING_VALUE_FIELD_IS_CHARS; + public class MessagePackGenerator extends GeneratorBase { - private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + private static final int IN_ROOT = 0; + private static final int IN_OBJECT = 1; + private static final int IN_ARRAY = 2; private final MessagePacker messagePacker; - private static ThreadLocal messageBufferOutputHolder = new ThreadLocal(); + private static final ThreadLocal messageBufferOutputHolder = new ThreadLocal<>(); private final OutputStream output; private final MessagePack.PackerConfig packerConfig; - private LinkedList stack; - private StackItem rootStackItem; - private abstract static class StackItem + private int currentParentElementIndex = -1; + private int currentState = IN_ROOT; + private final List nodes; + private boolean isElementsClosed = false; + + private static final class AsciiCharString + { + public final byte[] bytes; + + public AsciiCharString(byte[] bytes) + { + this.bytes = bytes; + } + } + + private abstract static class Node + { + // Root containers have -1. + final int parentIndex; + + public Node(int parentIndex) + { + this.parentIndex = parentIndex; + } + + abstract void incrementChildCount(); + + abstract int currentStateAsParent(); + } + + private abstract static class NodeContainer extends Node { - protected List objectKeys = new ArrayList(); - protected List objectValues = new ArrayList(); + // Only for containers. + int childCount; + + public NodeContainer(int parentIndex) + { + super(parentIndex); + } + + @Override + void incrementChildCount() + { + childCount++; + } + } - abstract void addKey(Object key); + private static final class NodeArray extends NodeContainer + { + public NodeArray(int parentIndex) + { + super(parentIndex); + } - void addValue(Object value) + @Override + int currentStateAsParent() { - objectValues.add(value); + return IN_ARRAY; } + } - abstract List getKeys(); + private static final class NodeObject extends NodeContainer + { + public NodeObject(int parentIndex) + { + super(parentIndex); + } - List getValues() + @Override + int currentStateAsParent() { - return objectValues; + return IN_OBJECT; } } - private static class StackItemForObject - extends StackItem + private static final class NodeEntryInArray extends Node { + final Object value; + + public NodeEntryInArray(int parentIndex, Object value) + { + super(parentIndex); + this.value = value; + } + @Override - void addKey(Object key) + void incrementChildCount() { - objectKeys.add(key); + throw new UnsupportedOperationException(); } @Override - List getKeys() + int currentStateAsParent() { - return objectKeys; + throw new UnsupportedOperationException(); } } - private static class StackItemForArray - extends StackItem + private static final class NodeEntryInObject extends Node { + final Object key; + // Lazily initialized. + Object value; + + public NodeEntryInObject(int parentIndex, Object key) + { + super(parentIndex); + this.key = key; + } + @Override - void addKey(Object key) + void incrementChildCount() { - throw new IllegalStateException("This method shouldn't be called"); + assert value instanceof NodeContainer; + ((NodeContainer) value).childCount++; } @Override - List getKeys() + int currentStateAsParent() { - throw new IllegalStateException("This method shouldn't be called"); + if (value instanceof NodeObject) { + return IN_OBJECT; + } + else if (value instanceof NodeArray) { + return IN_ARRAY; + } + else { + throw new AssertionError(); + } } } + // This is an internal constructor for nested serialization. + private MessagePackGenerator( + int features, + ObjectCodec codec, + OutputStream out, + MessagePack.PackerConfig packerConfig) + { + super(features, codec); + this.output = out; + this.messagePacker = packerConfig.newPacker(out); + this.packerConfig = packerConfig; + this.nodes = new ArrayList<>(); + } + public MessagePackGenerator( int features, ObjectCodec codec, @@ -110,7 +207,16 @@ public MessagePackGenerator( { super(features, codec); this.output = out; + this.messagePacker = packerConfig.newPacker(getMessageBufferOutputForOutputStream(out, reuseResourceInGenerator)); + this.packerConfig = packerConfig; + this.nodes = new ArrayList<>(); + } + private MessageBufferOutput getMessageBufferOutputForOutputStream( + OutputStream out, + boolean reuseResourceInGenerator) + throws IOException + { OutputStreamBufferOutput messageBufferOutput; if (reuseResourceInGenerator) { messageBufferOutput = messageBufferOutputHolder.get(); @@ -125,91 +231,106 @@ public MessagePackGenerator( else { messageBufferOutput = new OutputStreamBufferOutput(out); } - this.messagePacker = packerConfig.newPacker(messageBufferOutput); - - this.packerConfig = packerConfig; + return messageBufferOutput; + } - this.stack = new LinkedList(); + private String currentStateStr() + { + switch (currentState) { + case IN_OBJECT: + return "IN_OBJECT"; + case IN_ARRAY: + return "IN_ARRAY"; + default: + return "IN_ROOT"; + } } @Override public void writeStartArray() - throws IOException, JsonGenerationException { - _writeContext = _writeContext.createChildArrayContext(); - stack.push(new StackItemForArray()); + if (currentState == IN_OBJECT) { + Node node = nodes.get(nodes.size() - 1); + assert node instanceof NodeEntryInObject; + NodeEntryInObject nodeEntryInObject = (NodeEntryInObject) node; + nodeEntryInObject.value = new NodeArray(currentParentElementIndex); + } + else { + nodes.add(new NodeArray(currentParentElementIndex)); + } + currentParentElementIndex = nodes.size() - 1; + currentState = IN_ARRAY; } @Override public void writeEndArray() - throws IOException, JsonGenerationException + throws IOException { - if (!_writeContext.inArray()) { - _reportError("Current context not an array but " + _writeContext.getTypeDesc()); + if (currentState != IN_ARRAY) { + _reportError("Current context not an array but " + currentStateStr()); } - - getStackTopForArray(); - - _writeContext = _writeContext.getParent(); - - popStackAndStoreTheItemAsValue(); + endCurrentContainer(); } @Override public void writeStartObject() - throws IOException, JsonGenerationException { - _writeContext = _writeContext.createChildObjectContext(); - stack.push(new StackItemForObject()); + if (currentState == IN_OBJECT) { + Node node = nodes.get(nodes.size() - 1); + assert node instanceof NodeEntryInObject; + NodeEntryInObject nodeEntryInObject = (NodeEntryInObject) node; + nodeEntryInObject.value = new NodeObject(currentParentElementIndex); + } + else { + nodes.add(new NodeObject(currentParentElementIndex)); + } + currentParentElementIndex = nodes.size() - 1; + currentState = IN_OBJECT; } @Override public void writeEndObject() - throws IOException, JsonGenerationException + throws IOException { - if (!_writeContext.inObject()) { - _reportError("Current context not an object but " + _writeContext.getTypeDesc()); + if (currentState != IN_OBJECT) { + _reportError("Current context not an object but " + currentStateStr()); } + endCurrentContainer(); + } - StackItemForObject stackTop = getStackTopForObject(); - - if (stackTop.getKeys().size() != stackTop.getValues().size()) { - throw new IllegalStateException( - String.format( - "objectKeys.size() and objectValues.size() is not same: depth=%d, key=%d, value=%d", - stack.size(), stackTop.getKeys().size(), stackTop.getValues().size())); + private void endCurrentContainer() + { + Node parent = nodes.get(currentParentElementIndex); + if (currentParentElementIndex == 0) { + isElementsClosed = true; + currentParentElementIndex = parent.parentIndex; + return; } - _writeContext = _writeContext.getParent(); - popStackAndStoreTheItemAsValue(); + currentParentElementIndex = parent.parentIndex; + assert currentParentElementIndex >= 0; + Node currentParent = nodes.get(currentParentElementIndex); + currentParent.incrementChildCount(); + currentState = currentParent.currentStateAsParent(); } - private void pack(Object v) + private void packNonContainer(Object v) throws IOException { MessagePacker messagePacker = getMessagePacker(); - if (v == null) { - messagePacker.packNil(); + if (v instanceof String) { + messagePacker.packString((String) v); + } + else if (v instanceof AsciiCharString) { + byte[] bytes = ((AsciiCharString) v).bytes; + messagePacker.packRawStringHeader(bytes.length); + messagePacker.writePayload(bytes); } else if (v instanceof Integer) { messagePacker.packInt((Integer) v); } - else if (v instanceof ByteBuffer) { - ByteBuffer bb = (ByteBuffer) v; - int len = bb.remaining(); - if (bb.hasArray()) { - messagePacker.packBinaryHeader(len); - messagePacker.writePayload(bb.array(), bb.arrayOffset(), len); - } - else { - byte[] data = new byte[len]; - bb.get(data); - messagePacker.packBinaryHeader(len); - messagePacker.addPayload(data); - } - } - else if (v instanceof String) { - messagePacker.packString((String) v); + else if (v == null) { + messagePacker.packNil(); } else if (v instanceof Float) { messagePacker.packFloat((Float) v); @@ -217,12 +338,6 @@ else if (v instanceof Float) { else if (v instanceof Long) { messagePacker.packLong((Long) v); } - else if (v instanceof StackItemForObject) { - packObject((StackItemForObject) v); - } - else if (v instanceof StackItemForArray) { - packArray((StackItemForArray) v); - } else if (v instanceof Double) { messagePacker.packDouble((Double) v); } @@ -235,6 +350,20 @@ else if (v instanceof BigDecimal) { else if (v instanceof Boolean) { messagePacker.packBoolean((Boolean) v); } + else if (v instanceof ByteBuffer) { + ByteBuffer bb = (ByteBuffer) v; + int len = bb.remaining(); + if (bb.hasArray()) { + messagePacker.packBinaryHeader(len); + messagePacker.writePayload(bb.array(), bb.arrayOffset(), len); + } + else { + byte[] data = new byte[len]; + bb.get(data); + messagePacker.packBinaryHeader(len); + messagePacker.addPayload(data); + } + } else if (v instanceof MessagePackExtensionType) { MessagePackExtensionType extensionType = (MessagePackExtensionType) v; byte[] extData = extensionType.getData(); @@ -244,7 +373,7 @@ else if (v instanceof MessagePackExtensionType) { else { messagePacker.flush(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - MessagePackGenerator messagePackGenerator = new MessagePackGenerator(getFeatureMask(), getCodec(), outputStream, packerConfig, false); + MessagePackGenerator messagePackGenerator = new MessagePackGenerator(getFeatureMask(), getCodec(), outputStream, packerConfig); getCodec().writeValue(messagePackGenerator, v); output.write(outputStream.toByteArray()); } @@ -260,10 +389,7 @@ private void packBigDecimal(BigDecimal decimal) BigInteger integer = decimal.toBigIntegerExact(); messagePacker.packBigInteger(integer); } - catch (ArithmeticException e) { - failedToPackAsBI = true; - } - catch (IllegalArgumentException e) { + catch (ArithmeticException | IllegalArgumentException e) { failedToPackAsBI = true; } @@ -278,200 +404,297 @@ private void packBigDecimal(BigDecimal decimal) } } - private void packObject(StackItemForObject stackItem) + private void packObject(NodeObject container) throws IOException { - List keys = stackItem.getKeys(); - List values = stackItem.getValues(); + MessagePacker messagePacker = getMessagePacker(); + messagePacker.packMapHeader(container.childCount); + } + private void packArray(NodeArray container) + throws IOException + { MessagePacker messagePacker = getMessagePacker(); - messagePacker.packMapHeader(keys.size()); + messagePacker.packArrayHeader(container.childCount); + } - for (int i = 0; i < keys.size(); i++) { - pack(keys.get(i)); - pack(values.get(i)); + private void addKeyNode(Object key) + { + if (currentState != IN_OBJECT) { + throw new IllegalStateException(); } + Node node = new NodeEntryInObject(currentParentElementIndex, key); + nodes.add(node); } - private void packArray(StackItemForArray stackItem) - throws IOException + private void addValueNode(Object value) throws IOException { - List values = stackItem.getValues(); + switch (currentState) { + case IN_OBJECT: { + Node node = nodes.get(nodes.size() - 1); + assert node instanceof NodeEntryInObject; + NodeEntryInObject nodeEntryInObject = (NodeEntryInObject) node; + nodeEntryInObject.value = value; + nodes.get(node.parentIndex).incrementChildCount(); + break; + } + case IN_ARRAY: { + Node node = new NodeEntryInArray(currentParentElementIndex, value); + nodes.add(node); + nodes.get(node.parentIndex).incrementChildCount(); + break; + } + default: + packNonContainer(value); + flushMessagePacker(); + break; + } + } - MessagePacker messagePacker = getMessagePacker(); - messagePacker.packArrayHeader(values.size()); + @Nullable + private byte[] getBytesIfAscii(char[] chars, int offset, int len) + { + byte[] bytes = new byte[len]; + for (int i = offset; i < offset + len; i++) { + char c = chars[i]; + if (c >= 0x80) { + return null; + } + bytes[i] = (byte) c; + } + return bytes; + } - for (int i = 0; i < values.size(); i++) { - Object v = values.get(i); - pack(v); + private boolean areAllAsciiBytes(byte[] bytes, int offset, int len) + { + for (int i = offset; i < offset + len; i++) { + if ((bytes[i] & 0x80) != 0) { + return false; + } } + return true; + } + + private void writeCharArrayTextKey(char[] text, int offset, int len) + { + byte[] bytes = getBytesIfAscii(text, offset, len); + if (bytes != null) { + addKeyNode(new AsciiCharString(bytes)); + return; + } + addKeyNode(new String(text, offset, len)); + } + + private void writeCharArrayTextValue(char[] text, int offset, int len) throws IOException + { + byte[] bytes = getBytesIfAscii(text, offset, len); + if (bytes != null) { + addValueNode(new AsciiCharString(bytes)); + return; + } + addValueNode(new String(text, offset, len)); + } + + private void writeByteArrayTextValue(byte[] text, int offset, int len) throws IOException + { + if (areAllAsciiBytes(text, offset, len)) { + addValueNode(new AsciiCharString(text)); + return; + } + addValueNode(new String(text, offset, len, DEFAULT_CHARSET)); + } + + private void writeByteArrayTextKey(byte[] text, int offset, int len) throws IOException + { + if (areAllAsciiBytes(text, offset, len)) { + addValueNode(new AsciiCharString(text)); + return; + } + addValueNode(new String(text, offset, len, DEFAULT_CHARSET)); } @Override public void writeFieldName(String name) - throws IOException, JsonGenerationException { - addKeyToStackTop(name); + if (STRING_VALUE_FIELD_IS_CHARS.get()) { + char[] chars = name.toCharArray(); + writeCharArrayTextKey(chars, 0, chars.length); + } + else { + addKeyNode(name); + } } @Override public void writeFieldName(SerializableString name) - throws IOException { - if (name instanceof MessagePackSerializedString) { - addKeyToStackTop(((MessagePackSerializedString) name).getRawValue()); + if (name instanceof SerializedString) { + writeFieldName(name.getValue()); } - else if (name instanceof SerializedString) { - addKeyToStackTop(name.getValue()); + else if (name instanceof MessagePackSerializedString) { + addKeyNode(((MessagePackSerializedString) name).getRawValue()); } else { - System.out.println(name.getClass()); throw new IllegalArgumentException("Unsupported key: " + name); } } @Override public void writeString(String text) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(text); + if (STRING_VALUE_FIELD_IS_CHARS.get()) { + char[] chars = text.toCharArray(); + writeCharArrayTextValue(chars, 0, chars.length); + } + else { + addValueNode(text); + } } @Override public void writeString(char[] text, int offset, int len) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(new String(text, offset, len)); + writeCharArrayTextValue(text, offset, len); } @Override public void writeRawUTF8String(byte[] text, int offset, int length) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(new String(text, offset, length, DEFAULT_CHARSET)); + writeByteArrayTextValue(text, offset, length); } @Override public void writeUTF8String(byte[] text, int offset, int length) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(new String(text, offset, length, DEFAULT_CHARSET)); + writeByteArrayTextValue(text, offset, length); } @Override public void writeRaw(String text) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(text); + if (STRING_VALUE_FIELD_IS_CHARS.get()) { + char[] chars = text.toCharArray(); + writeCharArrayTextValue(chars, 0, chars.length); + } + else { + addValueNode(text); + } } @Override public void writeRaw(String text, int offset, int len) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(text.substring(0, len)); + // TODO: There is room to optimize this. + char[] chars = text.toCharArray(); + writeCharArrayTextValue(chars, offset, len); } @Override public void writeRaw(char[] text, int offset, int len) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(new String(text, offset, len)); + writeCharArrayTextValue(text, offset, len); } @Override public void writeRaw(char c) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(String.valueOf(c)); + writeCharArrayTextValue(new char[] { c }, 0, 1); } @Override public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(ByteBuffer.wrap(data, offset, len)); + addValueNode(ByteBuffer.wrap(data, offset, len)); } @Override public void writeNumber(int v) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(Integer.valueOf(v)); + addValueNode(v); } @Override public void writeNumber(long v) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(Long.valueOf(v)); + addValueNode(v); } @Override public void writeNumber(BigInteger v) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(v); + addValueNode(v); } @Override public void writeNumber(double d) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(Double.valueOf(d)); + addValueNode(d); } @Override public void writeNumber(float f) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(Float.valueOf(f)); + addValueNode(f); } @Override public void writeNumber(BigDecimal dec) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(dec); + addValueNode(dec); } @Override public void writeNumber(String encodedValue) - throws IOException, JsonGenerationException, UnsupportedOperationException + throws IOException, UnsupportedOperationException { // There is a room to improve this API's performance while the implementation is robust. // If users can use other MessagePackGenerator#writeNumber APIs that accept // proper numeric types not String, it's better to use the other APIs instead. try { long l = Long.parseLong(encodedValue); - addValueToStackTop(l); + addValueNode(l); return; } - catch (NumberFormatException e) { + catch (NumberFormatException ignored) { } try { double d = Double.parseDouble(encodedValue); - addValueToStackTop(d); + addValueNode(d); return; } - catch (NumberFormatException e) { + catch (NumberFormatException ignored) { } try { BigInteger bi = new BigInteger(encodedValue); - addValueToStackTop(bi); + addValueNode(bi); return; } - catch (NumberFormatException e) { + catch (NumberFormatException ignored) { } try { BigDecimal bc = new BigDecimal(encodedValue); - addValueToStackTop(bc); + addValueNode(bc); return; } - catch (NumberFormatException e) { + catch (NumberFormatException ignored) { } throw new NumberFormatException(encodedValue); @@ -479,22 +702,22 @@ public void writeNumber(String encodedValue) @Override public void writeBoolean(boolean state) - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(Boolean.valueOf(state)); + addValueNode(state); } @Override public void writeNull() - throws IOException, JsonGenerationException + throws IOException { - addValueToStackTop(null); + addValueNode(null); } public void writeExtensionType(MessagePackExtensionType extensionType) throws IOException { - addValueToStackTop(extensionType); + addValueNode(extensionType); } @Override @@ -516,19 +739,42 @@ public void close() public void flush() throws IOException { - if (rootStackItem != null) { - if (rootStackItem instanceof StackItemForObject) { - packObject((StackItemForObject) rootStackItem); + if (!isElementsClosed) { + // The whole elements are not closed yet. + return; + } + + for (int i = 0; i < nodes.size(); i++) { + Node node = nodes.get(i); + if (node instanceof NodeEntryInObject) { + NodeEntryInObject nodeEntry = (NodeEntryInObject) node; + packNonContainer(nodeEntry.key); + if (nodeEntry.value instanceof NodeObject) { + packObject((NodeObject) nodeEntry.value); + } + else if (nodeEntry.value instanceof NodeArray) { + packArray((NodeArray) nodeEntry.value); + } + else { + packNonContainer(nodeEntry.value); + } + } + else if (node instanceof NodeObject) { + packObject((NodeObject) node); + } + else if (node instanceof NodeEntryInArray) { + packNonContainer(((NodeEntryInArray) node).value); } - else if (rootStackItem instanceof StackItemForArray) { - packArray((StackItemForArray) rootStackItem); + else if (node instanceof NodeArray) { + packArray((NodeArray) node); } else { - throw new IllegalStateException("Unexpected rootStackItem: " + rootStackItem); + throw new AssertionError(); } - rootStackItem = null; - flushMessagePacker(); } + flushMessagePacker(); + nodes.clear(); + isElementsClosed = false; } private void flushMessagePacker() @@ -541,76 +787,18 @@ private void flushMessagePacker() @Override protected void _releaseBuffers() { - } - - @Override - protected void _verifyValueWrite(String typeMsg) - throws IOException, JsonGenerationException - { - int status = _writeContext.writeValue(); - if (status == JsonWriteContext.STATUS_EXPECT_NAME) { - _reportError("Can not " + typeMsg + ", expecting field name"); - } - } - - private StackItem getStackTop() - { - if (stack.isEmpty()) { - throw new IllegalStateException("The stack is empty"); - } - return stack.getFirst(); - } - - private StackItemForObject getStackTopForObject() - { - StackItem stackTop = getStackTop(); - if (!(stackTop instanceof StackItemForObject)) { - throw new IllegalStateException("The stack top should be Object: " + stackTop); - } - return (StackItemForObject) stackTop; - } - - private StackItemForArray getStackTopForArray() - { - StackItem stackTop = getStackTop(); - if (!(stackTop instanceof StackItemForArray)) { - throw new IllegalStateException("The stack top should be Array: " + stackTop); - } - return (StackItemForArray) stackTop; - } - - private void addKeyToStackTop(Object key) - { - getStackTop().addKey(key); - } - - private void addValueToStackTop(Object value) - throws IOException - { - if (stack.isEmpty()) { - pack(value); - flushMessagePacker(); + try { + messagePacker.close(); } - else { - getStackTop().addValue(value); + catch (IOException e) { + throw new RuntimeException("Failed to close MessagePacker", e); } } - private void popStackAndStoreTheItemAsValue() - throws IOException + @Override + protected void _verifyValueWrite(String typeMsg) throws IOException { - StackItem child = stack.pop(); - if (stack.size() > 0) { - addValueToStackTop(child); - } - else { - if (rootStackItem != null) { - throw new IllegalStateException("rootStackItem is not null"); - } - else { - rootStackItem = child; - } - } + // FIXME? } private MessagePacker getMessagePacker() diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackKeySerializer.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackKeySerializer.java index 8eaa8014..36fb235d 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackKeySerializer.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackKeySerializer.java @@ -15,7 +15,6 @@ // package org.msgpack.jackson.dataformat; -import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; @@ -32,7 +31,7 @@ public MessagePackKeySerializer() @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) - throws JsonGenerationException, IOException + throws IOException { jgen.writeFieldName(new MessagePackSerializedString(value)); } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 2a95b69a..4876c797 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -17,9 +17,7 @@ import com.fasterxml.jackson.core.Base64Variant; import com.fasterxml.jackson.core.JsonLocation; -import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonStreamContext; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.ObjectCodec; @@ -28,7 +26,6 @@ import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.io.JsonEOFException; import com.fasterxml.jackson.core.json.DupDetector; -import com.fasterxml.jackson.core.json.JsonReadContext; import org.msgpack.core.ExtensionTypeHeader; import org.msgpack.core.MessageFormat; import org.msgpack.core.MessagePack; @@ -42,27 +39,29 @@ import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.LinkedList; +import java.nio.charset.StandardCharsets; + +import static org.msgpack.jackson.dataformat.JavaInfo.STRING_VALUE_FIELD_IS_CHARS; public class MessagePackParser extends ParserMinimalBase { - private static final ThreadLocal> messageUnpackerHolder = - new ThreadLocal>(); + private static final ThreadLocal> messageUnpackerHolder = new ThreadLocal<>(); private final MessageUnpacker messageUnpacker; - private static final BigInteger LONG_MIN = BigInteger.valueOf((long) Long.MIN_VALUE); - private static final BigInteger LONG_MAX = BigInteger.valueOf((long) Long.MAX_VALUE); + private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE); + private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE); private ObjectCodec codec; - private JsonReadContext parsingContext; + private MessagePackReadContext streamReadContext; - private final LinkedList stack = new LinkedList(); private boolean isClosed; private long tokenPosition; private long currentPosition; private final IOContext ioContext; private ExtensionTypeCustomDeserializers extTypeCustomDesers; + private final byte[] tempBytes = new byte[64]; + private final char[] tempChars = new char[64]; private enum Type { @@ -76,51 +75,6 @@ private enum Type private String stringValue; private BigInteger biValue; private MessagePackExtensionType extensionTypeValue; - private boolean reuseResourceInParser; - - private abstract static class StackItem - { - private long numOfElements; - - protected StackItem(long numOfElements) - { - this.numOfElements = numOfElements; - } - - public void consume() - { - numOfElements--; - } - - public boolean isEmpty() - { - return numOfElements == 0; - } - } - - private static class StackItemForObject - extends StackItem - { - StackItemForObject(long numOfElements) - { - super(numOfElements); - } - } - - private static class StackItemForArray - extends StackItem - { - StackItemForArray(long numOfElements) - { - super(numOfElements); - } - } - - public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, InputStream in) - throws IOException - { - this(ctxt, features, objectCodec, in, true); - } public MessagePackParser( IOContext ctxt, @@ -133,12 +87,6 @@ public MessagePackParser( this(ctxt, features, new InputStreamBufferInput(in), objectCodec, in, reuseResourceInParser); } - public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, byte[] bytes) - throws IOException - { - this(ctxt, features, objectCodec, bytes, true); - } - public MessagePackParser( IOContext ctxt, int features, @@ -164,17 +112,12 @@ private MessagePackParser(IOContext ctxt, ioContext = ctxt; DupDetector dups = Feature.STRICT_DUPLICATE_DETECTION.enabledIn(features) ? DupDetector.rootDetector(this) : null; - parsingContext = JsonReadContext.createRootContext(dups); - this.reuseResourceInParser = reuseResourceInParser; + streamReadContext = MessagePackReadContext.createRootContext(dups); if (!reuseResourceInParser) { - this.messageUnpacker = MessagePack.newDefaultUnpacker(input); + messageUnpacker = MessagePack.newDefaultUnpacker(input); return; } - else { - this.messageUnpacker = null; - } - MessageUnpacker messageUnpacker; Tuple messageUnpackerTuple = messageUnpackerHolder.get(); if (messageUnpackerTuple == null) { messageUnpacker = MessagePack.newDefaultUnpacker(input); @@ -189,7 +132,7 @@ private MessagePackParser(IOContext ctxt, } messageUnpacker = messageUnpackerTuple.second(); } - messageUnpackerHolder.set(new Tuple(src, messageUnpacker)); + messageUnpackerHolder.set(new Tuple<>(src, messageUnpacker)); } public void setExtensionTypeCustomDeserializers(ExtensionTypeCustomDeserializers extTypeCustomDesers) @@ -215,21 +158,47 @@ public Version version() return null; } + private String unpackString(MessageUnpacker messageUnpacker) throws IOException + { + int strLen = messageUnpacker.unpackRawStringHeader(); + if (strLen <= tempBytes.length) { + messageUnpacker.readPayload(tempBytes, 0, strLen); + if (STRING_VALUE_FIELD_IS_CHARS.get()) { + for (int i = 0; i < strLen; i++) { + byte b = tempBytes[i]; + if ((0x80 & b) != 0) { + return new String(tempBytes, 0, strLen, StandardCharsets.UTF_8); + } + tempChars[i] = (char) b; + } + return new String(tempChars, 0, strLen); + } + else { + return new String(tempBytes, 0, strLen); + } + } + else { + byte[] bytes = messageUnpacker.readPayload(strLen); + return new String(bytes, 0, strLen, StandardCharsets.UTF_8); + } + } + @Override - public JsonToken nextToken() - throws IOException, JsonParseException + public JsonToken nextToken() throws IOException { - MessageUnpacker messageUnpacker = getMessageUnpacker(); tokenPosition = messageUnpacker.getTotalReadBytes(); - JsonToken nextToken = null; - if (parsingContext.inObject() || parsingContext.inArray()) { - if (stack.getFirst().isEmpty()) { - stack.pop(); - _currToken = parsingContext.inObject() ? JsonToken.END_OBJECT : JsonToken.END_ARRAY; - parsingContext = parsingContext.getParent(); - - return _currToken; + boolean isObjectValueSet = streamReadContext.inObject() && _currToken != JsonToken.FIELD_NAME; + if (isObjectValueSet) { + if (!streamReadContext.expectMoreValues()) { + streamReadContext = streamReadContext.getParent(); + return _updateToken(JsonToken.END_OBJECT); + } + } + else if (streamReadContext.inArray()) { + if (!streamReadContext.expectMoreValues()) { + streamReadContext = streamReadContext.getParent(); + return _updateToken(JsonToken.END_ARRAY); } } @@ -238,24 +207,19 @@ public JsonToken nextToken() } MessageFormat format = messageUnpacker.getNextFormat(); - ValueType valueType = messageUnpacker.getNextFormat().getValueType(); - - // We should push a new StackItem lazily after updating the current stack. - StackItem newStack = null; + ValueType valueType = format.getValueType(); + JsonToken nextToken; switch (valueType) { - case NIL: - messageUnpacker.unpackNil(); - nextToken = JsonToken.VALUE_NULL; - break; - case BOOLEAN: - boolean b = messageUnpacker.unpackBoolean(); - if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(Boolean.toString(b)); + case STRING: + type = Type.STRING; + stringValue = unpackString(messageUnpacker); + if (isObjectValueSet) { + streamReadContext.setCurrentName(stringValue); nextToken = JsonToken.FIELD_NAME; } else { - nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; + nextToken = JsonToken.VALUE_STRING; } break; case INTEGER: @@ -289,42 +253,45 @@ public JsonToken nextToken() break; } - if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(String.valueOf(v)); + if (isObjectValueSet) { + streamReadContext.setCurrentName(String.valueOf(v)); nextToken = JsonToken.FIELD_NAME; } else { nextToken = JsonToken.VALUE_NUMBER_INT; } break; - case FLOAT: - type = Type.DOUBLE; - doubleValue = messageUnpacker.unpackDouble(); - if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(String.valueOf(doubleValue)); + case NIL: + messageUnpacker.unpackNil(); + nextToken = JsonToken.VALUE_NULL; + break; + case BOOLEAN: + boolean b = messageUnpacker.unpackBoolean(); + if (isObjectValueSet) { + streamReadContext.setCurrentName(Boolean.toString(b)); nextToken = JsonToken.FIELD_NAME; } else { - nextToken = JsonToken.VALUE_NUMBER_FLOAT; + nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; } break; - case STRING: - type = Type.STRING; - stringValue = messageUnpacker.unpackString(); - if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(stringValue); + case FLOAT: + type = Type.DOUBLE; + doubleValue = messageUnpacker.unpackDouble(); + if (isObjectValueSet) { + streamReadContext.setCurrentName(String.valueOf(doubleValue)); nextToken = JsonToken.FIELD_NAME; } else { - nextToken = JsonToken.VALUE_STRING; + nextToken = JsonToken.VALUE_NUMBER_FLOAT; } break; case BINARY: type = Type.BYTES; int len = messageUnpacker.unpackBinaryHeader(); bytesValue = messageUnpacker.readPayload(len); - if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(new String(bytesValue, MessagePack.UTF8)); + if (isObjectValueSet) { + streamReadContext.setCurrentName(new String(bytesValue, MessagePack.UTF8)); nextToken = JsonToken.FIELD_NAME; } else { @@ -332,17 +299,19 @@ public JsonToken nextToken() } break; case ARRAY: - newStack = new StackItemForArray(messageUnpacker.unpackArrayHeader()); + nextToken = JsonToken.START_ARRAY; + streamReadContext = streamReadContext.createChildArrayContext(messageUnpacker.unpackArrayHeader()); break; case MAP: - newStack = new StackItemForObject(messageUnpacker.unpackMapHeader()); + nextToken = JsonToken.START_OBJECT; + streamReadContext = streamReadContext.createChildObjectContext(messageUnpacker.unpackMapHeader()); break; case EXTENSION: type = Type.EXT; ExtensionTypeHeader header = messageUnpacker.unpackExtensionTypeHeader(); extensionTypeValue = new MessagePackExtensionType(header.getType(), messageUnpacker.readPayload(header.getLength())); - if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) { - parsingContext.setCurrentName(deserializedExtensionTypeValue().toString()); + if (isObjectValueSet) { + streamReadContext.setCurrentName(deserializedExtensionTypeValue().toString()); nextToken = JsonToken.FIELD_NAME; } else { @@ -354,35 +323,18 @@ public JsonToken nextToken() } currentPosition = messageUnpacker.getTotalReadBytes(); - if (parsingContext.inObject() && nextToken != JsonToken.FIELD_NAME || parsingContext.inArray()) { - stack.getFirst().consume(); - } - - if (newStack != null) { - stack.push(newStack); - if (newStack instanceof StackItemForArray) { - nextToken = JsonToken.START_ARRAY; - parsingContext = parsingContext.createChildArrayContext(-1, -1); - } - else if (newStack instanceof StackItemForObject) { - nextToken = JsonToken.START_OBJECT; - parsingContext = parsingContext.createChildObjectContext(-1, -1); - } - } - _currToken = nextToken; + _updateToken(nextToken); return nextToken; } @Override protected void _handleEOF() - throws JsonParseException { } @Override - public String getText() - throws IOException, JsonParseException + public String getText() throws IOException { switch (type) { case STRING: @@ -405,8 +357,7 @@ public String getText() } @Override - public char[] getTextCharacters() - throws IOException, JsonParseException + public char[] getTextCharacters() throws IOException { return getText().toCharArray(); } @@ -418,22 +369,19 @@ public boolean hasTextCharacters() } @Override - public int getTextLength() - throws IOException, JsonParseException + public int getTextLength() throws IOException { return getText().length(); } @Override public int getTextOffset() - throws IOException, JsonParseException { return 0; } @Override public byte[] getBinaryValue(Base64Variant b64variant) - throws IOException, JsonParseException { switch (type) { case BYTES: @@ -449,7 +397,6 @@ public byte[] getBinaryValue(Base64Variant b64variant) @Override public Number getNumberValue() - throws IOException, JsonParseException { switch (type) { case INT: @@ -467,7 +414,6 @@ public Number getNumberValue() @Override public int getIntValue() - throws IOException, JsonParseException { switch (type) { case INT: @@ -485,7 +431,6 @@ public int getIntValue() @Override public long getLongValue() - throws IOException, JsonParseException { switch (type) { case INT: @@ -503,7 +448,6 @@ public long getLongValue() @Override public BigInteger getBigIntegerValue() - throws IOException, JsonParseException { switch (type) { case INT: @@ -521,7 +465,6 @@ public BigInteger getBigIntegerValue() @Override public float getFloatValue() - throws IOException, JsonParseException { switch (type) { case INT: @@ -539,11 +482,10 @@ public float getFloatValue() @Override public double getDoubleValue() - throws IOException, JsonParseException { switch (type) { case INT: - return (double) intValue; + return intValue; case LONG: return (double) longValue; case DOUBLE: @@ -557,7 +499,6 @@ public double getDoubleValue() @Override public BigDecimal getDecimalValue() - throws IOException { switch (type) { case INT: @@ -586,8 +527,7 @@ private Object deserializedExtensionTypeValue() } @Override - public Object getEmbeddedObject() - throws IOException, JsonParseException + public Object getEmbeddedObject() throws IOException { switch (type) { case BYTES: @@ -601,7 +541,6 @@ public Object getEmbeddedObject() @Override public NumberType getNumberType() - throws IOException, JsonParseException { switch (type) { case INT: @@ -623,7 +562,6 @@ public void close() { try { if (isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) { - MessageUnpacker messageUnpacker = getMessageUnpacker(); messageUnpacker.close(); } } @@ -641,7 +579,7 @@ public boolean isClosed() @Override public JsonStreamContext getParsingContext() { - return parsingContext; + return streamReadContext; } @Override @@ -659,41 +597,34 @@ public JsonLocation getCurrentLocation() @Override public void overrideCurrentName(String name) { + // Simple, but need to look for START_OBJECT/ARRAY's "off-by-one" thing: + MessagePackReadContext ctxt = streamReadContext; + if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { + ctxt = ctxt.getParent(); + } + // Unfortunate, but since we did not expose exceptions, need to wrap try { - if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { - JsonReadContext parent = parsingContext.getParent(); - parent.setCurrentName(name); - } - else { - parsingContext.setCurrentName(name); - } + ctxt.setCurrentName(name); } - catch (JsonProcessingException e) { + catch (IOException e) { throw new IllegalStateException(e); } } @Override - public String getCurrentName() - throws IOException + public String currentName() { if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { - JsonReadContext parent = parsingContext.getParent(); + MessagePackReadContext parent = streamReadContext.getParent(); return parent.getCurrentName(); } - return parsingContext.getCurrentName(); + return streamReadContext.getCurrentName(); } - private MessageUnpacker getMessageUnpacker() + @Override + public String getCurrentName() + throws IOException { - if (!reuseResourceInParser) { - return this.messageUnpacker; - } - - Tuple messageUnpackerTuple = messageUnpackerHolder.get(); - if (messageUnpackerTuple == null) { - throw new IllegalStateException("messageUnpacker is null"); - } - return messageUnpackerTuple.second(); + return currentName(); } } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackReadContext.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackReadContext.java new file mode 100644 index 00000000..403f1b36 --- /dev/null +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackReadContext.java @@ -0,0 +1,269 @@ +package org.msgpack.jackson.dataformat; + +import com.fasterxml.jackson.core.JsonLocation; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonStreamContext; +import com.fasterxml.jackson.core.io.CharTypes; +import com.fasterxml.jackson.core.io.ContentReference; +import com.fasterxml.jackson.core.json.DupDetector; + +/** + * Replacement of {@link com.fasterxml.jackson.core.json.JsonReadContext} + * to support features needed by MessagePack format. + */ +public final class MessagePackReadContext + extends JsonStreamContext +{ + /** + * Parent context for this context; null for root context. + */ + protected final MessagePackReadContext parent; + + // // // Optional duplicate detection + + protected final DupDetector dups; + + /** + * For fixed-size Arrays, Objects, this indicates expected number of entries. + */ + protected int expEntryCount; + + // // // Location information (minus source reference) + + protected String currentName; + + protected Object currentValue; + + /* + /********************************************************** + /* Simple instance reuse slots + /********************************************************** + */ + + protected MessagePackReadContext child = null; + + /* + /********************************************************** + /* Instance construction, reuse + /********************************************************** + */ + + public MessagePackReadContext(MessagePackReadContext parent, DupDetector dups, + int type, int expEntryCount) + { + super(); + this.parent = parent; + this.dups = dups; + _type = type; + this.expEntryCount = expEntryCount; + _index = -1; + _nestingDepth = parent == null ? 0 : parent._nestingDepth + 1; + } + + protected void reset(int type, int expEntryCount) + { + _type = type; + this.expEntryCount = expEntryCount; + _index = -1; + currentName = null; + currentValue = null; + if (dups != null) { + dups.reset(); + } + } + + @Override + public Object getCurrentValue() + { + return currentValue; + } + + @Override + public void setCurrentValue(Object v) + { + currentValue = v; + } + + // // // Factory methods + + public static MessagePackReadContext createRootContext(DupDetector dups) + { + return new MessagePackReadContext(null, dups, TYPE_ROOT, -1); + } + + public MessagePackReadContext createChildArrayContext(int expEntryCount) + { + MessagePackReadContext ctxt = child; + if (ctxt == null) { + ctxt = new MessagePackReadContext(this, + (dups == null) ? null : dups.child(), + TYPE_ARRAY, expEntryCount); + child = ctxt; + } + else { + ctxt.reset(TYPE_ARRAY, expEntryCount); + } + return ctxt; + } + + public MessagePackReadContext createChildObjectContext(int expEntryCount) + { + MessagePackReadContext ctxt = child; + if (ctxt == null) { + ctxt = new MessagePackReadContext(this, + (dups == null) ? null : dups.child(), + TYPE_OBJECT, expEntryCount); + child = ctxt; + return ctxt; + } + ctxt.reset(TYPE_OBJECT, expEntryCount); + return ctxt; + } + + /* + /********************************************************** + /* Abstract method implementation + /********************************************************** + */ + + @Override + public String getCurrentName() + { + return currentName; + } + + @Override + public MessagePackReadContext getParent() + { + return parent; + } + + /* + /********************************************************** + /* Extended API + /********************************************************** + */ + + public boolean hasExpectedLength() + { + return (expEntryCount >= 0); + } + + public int getExpectedLength() + { + return expEntryCount; + } + + public boolean isEmpty() + { + return expEntryCount == 0; + } + + public int getRemainingExpectedLength() + { + int diff = expEntryCount - _index; + // Negative values would occur when expected count is -1 + return Math.max(0, diff); + } + + public boolean acceptsBreakMarker() + { + return (expEntryCount < 0) && _type != TYPE_ROOT; + } + + /** + * Method called to increment the current entry count (Object property, Array + * element or Root value) for this context level + * and then see if more entries are accepted. + * The only case where more entries are NOT expected is for fixed-count + * Objects and Arrays that just reached the entry count. + *

+ * Note that since the entry count is updated this is a state-changing method. + */ + public boolean expectMoreValues() + { + if (++_index == expEntryCount) { + return false; + } + return true; + } + + /** + * @return Location pointing to the point where the context + * start marker was found + */ + @Override + public JsonLocation startLocation(ContentReference srcRef) + { + return new JsonLocation(srcRef, 1L, -1, -1); + } + + @Override + @Deprecated // since 2.13 + public JsonLocation getStartLocation(Object rawSrc) + { + return startLocation(ContentReference.rawReference(rawSrc)); + } + + /* + /********************************************************** + /* State changes + /********************************************************** + */ + + public void setCurrentName(String name) throws JsonProcessingException + { + currentName = name; + if (dups != null) { + _checkDup(dups, name); + } + } + + private void _checkDup(DupDetector dd, String name) throws JsonProcessingException + { + if (dd.isDup(name)) { + throw new JsonParseException(null, + "Duplicate field '" + name + "'", dd.findLocation()); + } + } + + /* + /********************************************************** + /* Overridden standard methods + /********************************************************** + */ + + /** + * Overridden to provide developer readable "JsonPath" representation + * of the context. + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(64); + switch (_type) { + case TYPE_ROOT: + sb.append("/"); + break; + case TYPE_ARRAY: + sb.append('['); + sb.append(getCurrentIndex()); + sb.append(']'); + break; + case TYPE_OBJECT: + sb.append('{'); + if (currentName != null) { + sb.append('"'); + CharTypes.appendQuoted(sb, currentName); + sb.append('"'); + } + else { + sb.append('?'); + } + sb.append('}'); + break; + } + return sb.toString(); + } +} diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializedString.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializedString.java index c7c65ff2..72ed5d8d 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializedString.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializedString.java @@ -17,15 +17,15 @@ import com.fasterxml.jackson.core.SerializableString; -import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; public class MessagePackSerializedString implements SerializableString { - private static final Charset UTF8 = Charset.forName("UTF-8"); + private static final Charset UTF8 = StandardCharsets.UTF_8; private final Object value; public MessagePackSerializedString(Object value) @@ -89,28 +89,24 @@ public int appendUnquoted(char[] chars, int i) @Override public int writeQuotedUTF8(OutputStream outputStream) - throws IOException { return 0; } @Override public int writeUnquotedUTF8(OutputStream outputStream) - throws IOException { return 0; } @Override public int putQuotedUTF8(ByteBuffer byteBuffer) - throws IOException { return 0; } @Override public int putUnquotedUTF8(ByteBuffer byteBuffer) - throws IOException { return 0; } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java index c6b02068..52269a7d 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java @@ -46,6 +46,7 @@ public void testNormal() assertArrayEquals(normalPojo.b, value.b); assertEquals(normalPojo.bi, value.bi); assertEquals(normalPojo.suit, Suit.HEART); + assertEquals(normalPojo.sMultibyte, value.sMultibyte); } @Test @@ -59,13 +60,38 @@ public void testNestedList() } @Test - public void testNestedListComplex() + public void testNestedListComplex1() throws IOException { - byte[] bytes = objectMapper.writeValueAsBytes(nestedListComplexPojo); - NestedListComplexPojo value = objectMapper.readValue(bytes, NestedListComplexPojo.class); - assertEquals(nestedListPojo.s, value.s); - assertEquals(nestedListComplexPojo.foos.get(0).t, value.foos.get(0).t); + byte[] bytes = objectMapper.writeValueAsBytes(nestedListComplexPojo1); + NestedListComplexPojo1 value = objectMapper.readValue(bytes, NestedListComplexPojo1.class); + assertEquals(nestedListComplexPojo1.s, value.s); + assertEquals(1, nestedListComplexPojo1.foos.size()); + assertEquals(nestedListComplexPojo1.foos.get(0).t, value.foos.get(0).t); + } + + @Test + public void testNestedListComplex2() + throws IOException + { + byte[] bytes = objectMapper.writeValueAsBytes(nestedListComplexPojo2); + NestedListComplexPojo2 value = objectMapper.readValue(bytes, NestedListComplexPojo2.class); + assertEquals(nestedListComplexPojo2.s, value.s); + assertEquals(2, nestedListComplexPojo2.foos.size()); + assertEquals(nestedListComplexPojo2.foos.get(0).t, value.foos.get(0).t); + assertEquals(nestedListComplexPojo2.foos.get(1).t, value.foos.get(1).t); + } + + @Test + public void testStrings() + throws IOException + { + byte[] bytes = objectMapper.writeValueAsBytes(stringPojo); + StringPojo value = objectMapper.readValue(bytes, StringPojo.class); + assertEquals(stringPojo.shortSingleByte, value.shortSingleByte); + assertEquals(stringPojo.longSingleByte, value.longSingleByte); + assertEquals(stringPojo.shortMultiByte, value.shortMultiByte); + assertEquals(stringPojo.longMultiByte, value.longMultiByte); } @Test diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java index d2d3d456..b9ef4cf3 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatTestBase.java @@ -43,7 +43,9 @@ public class MessagePackDataformatTestBase protected ObjectMapper objectMapper; protected NormalPojo normalPojo; protected NestedListPojo nestedListPojo; - protected NestedListComplexPojo nestedListComplexPojo; + protected NestedListComplexPojo1 nestedListComplexPojo1; + protected NestedListComplexPojo2 nestedListComplexPojo2; + protected StringPojo stringPojo; protected TinyPojo tinyPojo; protected ComplexPojo complexPojo; @@ -65,18 +67,31 @@ public void setup() normalPojo.b = new byte[] {0x01, 0x02, (byte) 0xFE, (byte) 0xFF}; normalPojo.bi = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE); normalPojo.suit = Suit.HEART; + normalPojo.sMultibyte = "text文字"; nestedListPojo = new NestedListPojo(); nestedListPojo.s = "a string"; - nestedListPojo.strs = Arrays.asList("string", "another string", "another string"); + nestedListPojo.strs = Arrays.asList("string#1", "string#2", "string#3"); tinyPojo = new TinyPojo(); tinyPojo.t = "t string"; - nestedListComplexPojo = new NestedListComplexPojo(); - nestedListComplexPojo.s = "a string"; - nestedListComplexPojo.foos = new ArrayList(); - nestedListComplexPojo.foos.add(tinyPojo); + nestedListComplexPojo1 = new NestedListComplexPojo1(); + nestedListComplexPojo1.s = "a string"; + nestedListComplexPojo1.foos = new ArrayList<>(); + nestedListComplexPojo1.foos.add(tinyPojo); + + nestedListComplexPojo2 = new NestedListComplexPojo2(); + nestedListComplexPojo2.foos = new ArrayList<>(); + nestedListComplexPojo2.foos.add(tinyPojo); + nestedListComplexPojo2.foos.add(tinyPojo); + nestedListComplexPojo2.s = "another string"; + + stringPojo = new StringPojo(); + stringPojo.shortSingleByte = "hello"; + stringPojo.longSingleByte = "helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld"; + stringPojo.shortMultiByte = "こんにちは"; + stringPojo.longMultiByte = "こんにちは、世界!!こんにちは、世界!!こんにちは、世界!!こんにちは、世界!!こんにちは、世界!!"; complexPojo = new ComplexPojo(); complexPojo.name = "komamitsu"; @@ -131,12 +146,26 @@ public static class TinyPojo public String t; } - public static class NestedListComplexPojo + public static class NestedListComplexPojo1 { public String s; public List foos; } + public static class NestedListComplexPojo2 + { + public List foos; + public String s; + } + + public static class StringPojo + { + public String shortSingleByte; + public String longSingleByte; + public String shortMultiByte; + public String longMultiByte; + } + public static class NormalPojo { String s; @@ -148,6 +177,7 @@ public static class NormalPojo public byte[] b; public BigInteger bi; public Suit suit; + public String sMultibyte; public String getS() { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 931a33f5..7ba48a61 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -40,6 +40,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -283,6 +284,8 @@ public void testWritePrimitives() generator.writeNumber(0); generator.writeString("one"); generator.writeNumber(2.0f); + generator.writeString("三"); + generator.writeString("444④"); generator.flush(); generator.close(); @@ -291,6 +294,8 @@ public void testWritePrimitives() assertEquals(0, unpacker.unpackInt()); assertEquals("one", unpacker.unpackString()); assertEquals(2.0f, unpacker.unpackFloat(), 0.001f); + assertEquals("三", unpacker.unpackString()); + assertEquals("444④", unpacker.unpackString()); assertFalse(unpacker.hasNext()); } @@ -382,23 +387,24 @@ public void testWritePrimitiveObjectViaObjectMapper() throws Exception { File tempFile = createTempFile(); - OutputStream out = new FileOutputStream(tempFile); - - ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); - objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); - objectMapper.writeValue(out, 1); - objectMapper.writeValue(out, "two"); - objectMapper.writeValue(out, 3.14); - objectMapper.writeValue(out, Arrays.asList(4)); - objectMapper.writeValue(out, 5L); - - MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(new FileInputStream(tempFile)); - assertEquals(1, unpacker.unpackInt()); - assertEquals("two", unpacker.unpackString()); - assertEquals(3.14, unpacker.unpackFloat(), 0.0001); - assertEquals(1, unpacker.unpackArrayHeader()); - assertEquals(4, unpacker.unpackInt()); - assertEquals(5, unpacker.unpackLong()); + try (OutputStream out = Files.newOutputStream(tempFile.toPath())) { + ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); + objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); + objectMapper.writeValue(out, 1); + objectMapper.writeValue(out, "two"); + objectMapper.writeValue(out, 3.14); + objectMapper.writeValue(out, Arrays.asList(4)); + objectMapper.writeValue(out, 5L); + } + + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(new FileInputStream(tempFile))) { + assertEquals(1, unpacker.unpackInt()); + assertEquals("two", unpacker.unpackString()); + assertEquals(3.14, unpacker.unpackFloat(), 0.0001); + assertEquals(1, unpacker.unpackArrayHeader()); + assertEquals(4, unpacker.unpackInt()); + assertEquals(5, unpacker.unpackLong()); + } } @Test @@ -442,10 +448,11 @@ public Exception call() throw exception; } else { - ByteArrayOutputStream outputStream = buffers.get(ti); - MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(outputStream.toByteArray()); - for (int i = 0; i < loopCount; i++) { - assertEquals(ti, unpacker.unpackInt()); + try (ByteArrayOutputStream outputStream = buffers.get(ti); + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(outputStream.toByteArray())) { + for (int i = 0; i < loopCount; i++) { + assertEquals(ti, unpacker.unpackInt()); + } } } } diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index 179b0989..2713eaea 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -15,7 +15,6 @@ // package org.msgpack.jackson.dataformat.benchmark; -import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; @@ -23,9 +22,6 @@ import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo; import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -45,9 +41,6 @@ public class MessagePackDataformatPojoBenchmarkTest public MessagePackDataformatPojoBenchmarkTest() { - origObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); - msgpackObjectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); - for (int i = 0; i < LOOP_MAX; i++) { NormalPojo pojo = new NormalPojo(); pojo.i = i; @@ -76,6 +69,7 @@ public MessagePackDataformatPojoBenchmarkTest() break; } pojo.b = new byte[] {(byte) i}; + pojo.sMultibyte = "012345678Ⅸ"; pojos.add(pojo); } @@ -104,14 +98,6 @@ public void testBenchmark() { Benchmarker benchmarker = new Benchmarker(); - File tempFileJackson = File.createTempFile("msgpack-jackson-", "-huge-jackson"); - tempFileJackson.deleteOnExit(); - final OutputStream outputStreamJackson = new FileOutputStream(tempFileJackson); - - File tempFileMsgpack = File.createTempFile("msgpack-jackson-", "-huge-msgpack"); - tempFileMsgpack.deleteOnExit(); - final OutputStream outputStreamMsgpack = new FileOutputStream(tempFileMsgpack); - benchmarker.addBenchmark(new Benchmarker.Benchmarkable("serialize(pojo) with JSON") { @Override public void run() @@ -119,7 +105,7 @@ public void run() { for (int j = 0; j < LOOP_FACTOR_SER; j++) { for (int i = 0; i < LOOP_MAX; i++) { - origObjectMapper.writeValue(outputStreamJackson, pojos.get(i)); + origObjectMapper.writeValueAsBytes(pojos.get(i)); } } } @@ -132,7 +118,7 @@ public void run() { for (int j = 0; j < LOOP_FACTOR_SER; j++) { for (int i = 0; i < LOOP_MAX; i++) { - msgpackObjectMapper.writeValue(outputStreamMsgpack, pojos.get(i)); + msgpackObjectMapper.writeValueAsBytes(pojos.get(i)); } } } @@ -164,12 +150,6 @@ public void run() } }); - try { - benchmarker.run(COUNT, WARMUP_COUNT); - } - finally { - outputStreamJackson.close(); - outputStreamMsgpack.close(); - } + benchmarker.run(COUNT, WARMUP_COUNT); } } From ae7a883b3d3c3fee028dc944300ecd94d2969f7b Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:56:46 +0100 Subject: [PATCH 161/195] Update airframe-json, airspec to 2025.1.1 (#872) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 31280a69..82ec44f0 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "24.12.2" +val AIRFRAME_VERSION = "2025.1.1" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 91bc7f2029c4bb6e8c489fecf8c1525f0111012e Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:56:56 +0100 Subject: [PATCH 162/195] Update scala-collection-compat to 2.13.0 (#871) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 82ec44f0..235f6286 100644 --- a/build.sbt +++ b/build.sbt @@ -92,7 +92,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.12.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0" % "test" ) ) From f480b7bf828f08961f85a671758bd7f383136956 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:57:07 +0100 Subject: [PATCH 163/195] Update sbt-scalafmt to 2.5.4 (#869) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index e702479f..01d5e0ad 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.4") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.0") scalacOptions ++= Seq("-deprecation", "-feature") From 1cbd05f7ad1a44d8d78f6a6d55f0ce0fe78f386c Mon Sep 17 00:00:00 2001 From: brenbar <12563144+brenbar@users.noreply.github.com> Date: Mon, 10 Feb 2025 19:55:08 -0600 Subject: [PATCH 164/195] Add support for jackson field ids (#868) * Add test demonstrating field id case * Fix java 8 error * Add missing import * Add missing throws * Cleanup unused imports * Cleanup test * Implement jackson field ids * Address feedback from @komamitsu * Address feedback from @komamitsu * Address feedback from @komamitsu --- .../dataformat/MessagePackFactory.java | 9 +- .../dataformat/MessagePackGenerator.java | 22 ++- .../jackson/dataformat/MessagePackParser.java | 5 + .../MessagePackDataformatForFieldIdTest.java | 132 ++++++++++++++++++ 4 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index bb5064f1..dbd2a465 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -39,6 +39,7 @@ public class MessagePackFactory private final MessagePack.PackerConfig packerConfig; private boolean reuseResourceInGenerator = true; private boolean reuseResourceInParser = true; + private boolean supportIntegerKeys = false; private ExtensionTypeCustomDeserializers extTypeCustomDesers; public MessagePackFactory() @@ -74,6 +75,12 @@ public MessagePackFactory setReuseResourceInParser(boolean reuseResourceInParser return this; } + public MessagePackFactory setSupportIntegerKeys(boolean supportIntegerKeys) + { + this.supportIntegerKeys = supportIntegerKeys; + return this; + } + public MessagePackFactory setExtTypeCustomDesers(ExtensionTypeCustomDeserializers extTypeCustomDesers) { this.extTypeCustomDesers = extTypeCustomDesers; @@ -84,7 +91,7 @@ public MessagePackFactory setExtTypeCustomDesers(ExtensionTypeCustomDeserializer public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException { - return new MessagePackGenerator(_generatorFeatures, _objectCodec, out, packerConfig, reuseResourceInGenerator); + return new MessagePackGenerator(_generatorFeatures, _objectCodec, out, packerConfig, reuseResourceInGenerator, supportIntegerKeys); } @Override diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index 11aba6e5..abb5089e 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -50,6 +50,7 @@ public class MessagePackGenerator private static final ThreadLocal messageBufferOutputHolder = new ThreadLocal<>(); private final OutputStream output; private final MessagePack.PackerConfig packerConfig; + private final boolean supportIntegerKeys; private int currentParentElementIndex = -1; private int currentState = IN_ROOT; @@ -188,13 +189,15 @@ private MessagePackGenerator( int features, ObjectCodec codec, OutputStream out, - MessagePack.PackerConfig packerConfig) + MessagePack.PackerConfig packerConfig, + boolean supportIntegerKeys) { super(features, codec); this.output = out; this.messagePacker = packerConfig.newPacker(out); this.packerConfig = packerConfig; this.nodes = new ArrayList<>(); + this.supportIntegerKeys = supportIntegerKeys; } public MessagePackGenerator( @@ -202,7 +205,8 @@ public MessagePackGenerator( ObjectCodec codec, OutputStream out, MessagePack.PackerConfig packerConfig, - boolean reuseResourceInGenerator) + boolean reuseResourceInGenerator, + boolean supportIntegerKeys) throws IOException { super(features, codec); @@ -210,6 +214,7 @@ public MessagePackGenerator( this.messagePacker = packerConfig.newPacker(getMessageBufferOutputForOutputStream(out, reuseResourceInGenerator)); this.packerConfig = packerConfig; this.nodes = new ArrayList<>(); + this.supportIntegerKeys = supportIntegerKeys; } private MessageBufferOutput getMessageBufferOutputForOutputStream( @@ -373,7 +378,7 @@ else if (v instanceof MessagePackExtensionType) { else { messagePacker.flush(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - MessagePackGenerator messagePackGenerator = new MessagePackGenerator(getFeatureMask(), getCodec(), outputStream, packerConfig); + MessagePackGenerator messagePackGenerator = new MessagePackGenerator(getFeatureMask(), getCodec(), outputStream, packerConfig, supportIntegerKeys); getCodec().writeValue(messagePackGenerator, v); output.write(outputStream.toByteArray()); } @@ -513,6 +518,17 @@ private void writeByteArrayTextKey(byte[] text, int offset, int len) throws IOEx addValueNode(new String(text, offset, len, DEFAULT_CHARSET)); } + @Override + public void writeFieldId(long id) throws IOException + { + if (this.supportIntegerKeys) { + addKeyNode(id); + } + else { + super.writeFieldId(id); + } + } + @Override public void writeFieldName(String name) { diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 4876c797..e59b7f57 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -621,6 +621,11 @@ public String currentName() return streamReadContext.getCurrentName(); } + public boolean isCurrentFieldId() + { + return this.type == Type.INT || this.type == Type.LONG; + } + @Override public String getCurrentName() throws IOException diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java new file mode 100644 index 00000000..0e102ba8 --- /dev/null +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java @@ -0,0 +1,132 @@ +// +// MessagePack for Java +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package org.msgpack.jackson.dataformat; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.KeyDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.NullValueProvider; +import com.fasterxml.jackson.databind.deser.impl.JDKValueInstantiators; +import com.fasterxml.jackson.databind.deser.std.MapDeserializer; +import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.type.TypeFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.LinkedHashMap; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MessagePackDataformatForFieldIdTest +{ + static class MessagePackMapDeserializer extends MapDeserializer + { + public static KeyDeserializer keyDeserializer = new KeyDeserializer() + { + @Override + public Object deserializeKey(String s, DeserializationContext deserializationContext) + throws IOException + { + JsonParser parser = deserializationContext.getParser(); + if (parser instanceof MessagePackParser) { + MessagePackParser p = (MessagePackParser) parser; + if (p.isCurrentFieldId()) { + return Integer.valueOf(s); + } + } + return s; + } + }; + + public MessagePackMapDeserializer() + { + super( + TypeFactory.defaultInstance().constructMapType(Map.class, Object.class, Object.class), + JDKValueInstantiators.findStdValueInstantiator(null, LinkedHashMap.class), + keyDeserializer, null, null); + } + + public MessagePackMapDeserializer(MapDeserializer src, KeyDeserializer keyDeser, + JsonDeserializer valueDeser, TypeDeserializer valueTypeDeser, NullValueProvider nuller, + Set ignorable, Set includable) + { + super(src, keyDeser, valueDeser, valueTypeDeser, nuller, ignorable, includable); + } + + @Override + protected MapDeserializer withResolved(KeyDeserializer keyDeser, TypeDeserializer valueTypeDeser, + JsonDeserializer valueDeser, NullValueProvider nuller, Set ignorable, + Set includable) + { + return new MessagePackMapDeserializer(this, keyDeser, (JsonDeserializer) valueDeser, valueTypeDeser, + nuller, ignorable, includable); + } + } + + @Test + public void testMixedKeys() + throws IOException + { + ObjectMapper mapper = new ObjectMapper( + new MessagePackFactory() + .setSupportIntegerKeys(true) + ) + .registerModule(new SimpleModule() + .addDeserializer(Map.class, new MessagePackMapDeserializer())); + + Map map = new HashMap<>(); + map.put(1, "one"); + map.put("2", "two"); + + byte[] bytes = mapper.writeValueAsBytes(map); + Map deserializedInit = mapper.readValue(bytes, new TypeReference>() {}); + + Map expected = new HashMap<>(map); + Map actual = new HashMap<>(deserializedInit); + + assertEquals(expected, actual); + } + + @Test + public void testMixedKeysBackwardsCompatiable() + throws IOException + { + ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()) + .registerModule(new SimpleModule() + .addDeserializer(Map.class, new MessagePackMapDeserializer())); + + Map map = new HashMap<>(); + map.put(1, "one"); + map.put("2", "two"); + + byte[] bytes = mapper.writeValueAsBytes(map); + Map deserializedInit = mapper.readValue(bytes, new TypeReference>() {}); + + Map expected = new HashMap<>(); + expected.put("1", "one"); + expected.put("2", "two"); + Map actual = new HashMap<>(deserializedInit); + + assertEquals(expected, actual); + } +} From f73e394e48fa8e0556e8b9739ca1a5c6424db168 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 08:49:31 -0700 Subject: [PATCH 165/195] Add CLAUDE.md for AI-assisted development (#894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This file provides essential guidance for Claude Code when working with the msgpack-java codebase, including common development commands and high-level architecture overview. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- CLAUDE.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..e01643b5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,93 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +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 + +## Essential Development Commands + +### Build and Compile +```bash +./sbt compile # Compile source code +./sbt test:compile # Compile source and test code +./sbt package # Create JAR files +``` + +### Testing +```bash +./sbt test # Run all tests +./sbt ~test # Run tests continuously on file changes +./sbt testOnly *TestClass # Run specific test class +./sbt "testOnly *TestClass -- -z pattern" # Run tests matching pattern + +# Test with universal buffer mode (for compatibility testing) +./sbt test -J-Dmsgpack.universal-buffer=true +``` + +### Code Quality +```bash +./sbt jcheckStyle # Run checkstyle (Facebook Presto style) +./sbt scalafmtAll # Format Scala test code +``` + +### Publishing +```bash +./sbt publishLocal # Install to local .ivy2 repository +./sbt publishM2 # Install to local .m2 Maven repository +``` + +## Architecture Overview + +### Core API Structure +The main entry point is the `MessagePack` factory class which creates: +- **MessagePacker**: Serializes objects to MessagePack binary format +- **MessageUnpacker**: Deserializes MessagePack binary data + +Key locations: +- Core interfaces: `msgpack-core/src/main/java/org/msgpack/core/` +- Jackson integration: `msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/` + +### Buffer Management System +MessagePack uses an efficient buffer abstraction layer: +- **MessageBuffer**: Platform-optimized buffer implementations + - Uses `sun.misc.Unsafe` for performance when available + - Falls back to ByteBuffer on restricted platforms +- **MessageBufferInput/Output**: Manages buffer sequences for streaming + +### Jackson Integration +The msgpack-jackson module provides: +- **MessagePackFactory**: Jackson JsonFactory implementation +- **MessagePackMapper**: Pre-configured ObjectMapper for MessagePack +- Support for field IDs (integer keys) for compact serialization +- Extension type support including timestamps + +### Testing Structure +- **msgpack-core tests**: Written in Scala using AirSpec framework + - Location: `msgpack-core/src/test/scala/` +- **msgpack-jackson tests**: Written in Java using JUnit + - Location: `msgpack-jackson/src/test/java/` + +## Important JVM Options + +For JDK 17+ compatibility, these options are automatically added: +``` +--add-opens=java.base/java.nio=ALL-UNNAMED +--add-opens=java.base/sun.nio.ch=ALL-UNNAMED +``` + +## Code Style Requirements +- Java code follows Facebook Presto style (enforced by checkstyle) +- Scala test code uses Scalafmt with 180 character line limit +- Checkstyle runs automatically during compilation +- No external dependencies allowed in msgpack-core + +## Key Design Principles +1. **Zero Dependencies**: msgpack-core has no external dependencies +2. **Platform Optimization**: Uses platform-specific optimizations when available +3. **Streaming Support**: Both streaming and object-based APIs +4. **Type Safety**: Immutable Value hierarchy for type-safe data handling +5. **Extension Support**: Extensible type system for custom data types \ No newline at end of file From 032823bd60f2f5b859f4ae962f3cb96cbe2ae7a0 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 09:18:02 -0700 Subject: [PATCH 166/195] Refactor CI to use matrix strategy and add JDK 24 support (#895) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace individual JDK test jobs with a single matrix-based job - Add JDK 24 to the test matrix (now tests JDK 8, 11, 17, 21, and 24) - Simplifies CI configuration and makes it easier to add new JDK versions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- .github/workflows/CI.yml | 70 ++++++---------------------------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7ff24e9b..31f824e4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -27,75 +27,25 @@ jobs: - uses: actions/checkout@v4 - name: jcheckstyle run: ./sbt jcheckStyle - test_jdk21: - name: Test JDK21 + + test: + name: Test JDK${{ matrix.java }} runs-on: ubuntu-latest + strategy: + matrix: + java: ['8', '11', '17', '21', '24'] steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: '21' + java-version: ${{ matrix.java }} - uses: actions/cache@v4 with: path: ~/.cache - key: ${{ runner.os }}-jdk21-${{ hashFiles('**/*.sbt') }} - restore-keys: ${{ runner.os }}-jdk21- + key: ${{ runner.os }}-jdk${{ matrix.java }}-${{ hashFiles('**/*.sbt') }} + restore-keys: ${{ runner.os }}-jdk${{ matrix.java }}- - name: Test run: ./sbt test - name: Universal Buffer Test - run: ./sbt test -J-Dmsgpack.universal-buffer=true - test_jdk17: - name: Test JDK17 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '17' - - uses: actions/cache@v4 - with: - path: ~/.cache - key: ${{ runner.os }}-jdk17-${{ hashFiles('**/*.sbt') }} - restore-keys: ${{ runner.os }}-jdk17- - - name: Test - run: ./sbt test - - name: Universal Buffer Test - run: ./sbt test -J-Dmsgpack.universal-buffer=true - test_jdk11: - name: Test JDK11 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '11' - - uses: actions/cache@v4 - with: - path: ~/.cache - key: ${{ runner.os }}-jdk11-${{ hashFiles('**/*.sbt') }} - restore-keys: ${{ runner.os }}-jdk11- - - name: Test - run: ./sbt test - - name: Universal Buffer Test - run: ./sbt test -J-Dmsgpack.universal-buffer=true - test_jdk8: - name: Test JDK8 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '8' - - uses: actions/cache@v4 - with: - path: ~/.cache - key: ${{ runner.os }}-jdk8-${{ hashFiles('**/*.sbt') }} - restore-keys: ${{ runner.os }}-jdk8- - - name: Test - run: ./sbt test - - name: Universal Buffer Test - run: ./sbt test -J-Dmsgpack.universal-buffer=true + run: ./sbt test -J-Dmsgpack.universal-buffer=true \ No newline at end of file From 18ab7b7eae2aee3d50205fce1926823930622541 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 19 Jul 2025 18:21:43 +0200 Subject: [PATCH 167/195] Update sbt-scalafmt to 2.5.5 (#893) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 01d5e0ad..a15bdf51 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,7 +5,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.4") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.0") scalacOptions ++= Seq("-deprecation", "-feature") From 8f1dddde88d5dcec0734224ddb447a0b893cc026 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 09:33:44 -0700 Subject: [PATCH 168/195] Update sbt-dynver to 5.1.1 (#896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #892 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index a15bdf51..d6844375 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,6 +6,6 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5") -addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.0") +addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.1") scalacOptions ++= Seq("-deprecation", "-feature") From 736765333c4043bea7a5e1157194b1f22e407a54 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 09:39:43 -0700 Subject: [PATCH 169/195] Migrate from JUnit 4 to JUnit 5 to resolve deprecation warnings (#897) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update build.sbt to use JUnit 5 dependencies (jupiter + vintage) - Replace JUnit 4 imports with JUnit 5 equivalents - Convert @Test(expected=Exception.class) to assertThrows() - Update @Before to @BeforeEach annotation - Replace deprecated org.junit.Assert.assertThat with Hamcrest assertThat - Maintain backward compatibility with JUnit Vintage engine Fixes all JUnit deprecation warnings in msgpack-jackson tests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- build.sbt | 9 +++++--- .../MessagePackDataformatForFieldIdTest.java | 4 ++-- .../MessagePackDataformatForPojoTest.java | 8 +++---- .../dataformat/MessagePackFactoryTest.java | 6 ++--- .../dataformat/MessagePackGeneratorTest.java | 23 +++++++++++-------- .../dataformat/MessagePackMapperTest.java | 6 ++--- .../dataformat/MessagePackParserTest.java | 17 ++++++++------ .../TimestampExtensionModuleTest.java | 8 +++---- ...gePackDataformatHugeDataBenchmarkTest.java | 2 +- ...essagePackDataformatPojoBenchmarkTest.java | 2 +- 10 files changed, 47 insertions(+), 38 deletions(-) diff --git a/build.sbt b/build.sbt index 235f6286..d4645a11 100644 --- a/build.sbt +++ b/build.sbt @@ -46,7 +46,8 @@ val buildSettings = Seq[Setting[_]]( Test / compile := ((Test / compile) dependsOn (Test / jcheckStyle)).value ) -val junitInterface = "com.github.sbt" % "junit-interface" % "0.13.3" % "test" +val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.11.4" % "test" +val junitVintage = "org.junit.vintage" % "junit-vintage-engine" % "5.11.4" % "test" // Project settings lazy val root = Project(id = "msgpack-java", base = file(".")) @@ -83,7 +84,8 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) Test / fork := true, libraryDependencies ++= Seq( // msgpack-core should have no external dependencies - junitInterface, + junitJupiter, + junitVintage, "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods @@ -110,7 +112,8 @@ lazy val msgpackJackson = ), libraryDependencies ++= Seq( "com.fasterxml.jackson.core" % "jackson-databind" % "2.18.2", - junitInterface, + junitJupiter, + junitVintage, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java index 0e102ba8..bbac6fb9 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForFieldIdTest.java @@ -33,9 +33,9 @@ import java.util.Map; import java.util.Set; import java.util.LinkedHashMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class MessagePackDataformatForFieldIdTest { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java index 52269a7d..e899e4f4 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackDataformatForPojoTest.java @@ -16,7 +16,7 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.nio.charset.Charset; @@ -24,9 +24,9 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.hamcrest.MatcherAssert.assertThat; public class MessagePackDataformatForPojoTest extends MessagePackDataformatTestBase diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java index f8d7ac3c..9e376541 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackFactoryTest.java @@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.AnnotationIntrospector; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.msgpack.core.MessagePack; import java.io.IOException; @@ -35,8 +35,8 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.hamcrest.MatcherAssert.assertThat; public class MessagePackFactoryTest extends MessagePackDataformatTestBase diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java index 7ba48a61..a13951b2 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java @@ -24,7 +24,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.module.SimpleModule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.msgpack.core.ExtensionTypeHeader; import org.msgpack.core.MessagePack; import org.msgpack.core.MessageUnpacker; @@ -53,13 +53,14 @@ import java.util.concurrent.TimeUnit; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.hamcrest.MatcherAssert.assertThat; public class MessagePackGeneratorTest extends MessagePackDataformatTestBase @@ -349,7 +350,7 @@ public void testBigDecimal() } } - @Test(expected = IOException.class) + @Test public void testEnableFeatureAutoCloseTarget() throws IOException { @@ -358,7 +359,9 @@ public void testEnableFeatureAutoCloseTarget() ObjectMapper objectMapper = new ObjectMapper(messagePackFactory); List integers = Arrays.asList(1); objectMapper.writeValue(out, integers); - objectMapper.writeValue(out, integers); + assertThrows(IOException.class, () -> { + objectMapper.writeValue(out, integers); + }); } @Test diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java index 68721fce..d14f97f2 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackMapperTest.java @@ -16,14 +16,14 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.core.JsonProcessingException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; public class MessagePackMapperTest { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index a416c92b..c0bab053 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -27,7 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.value.ExtensionValue; @@ -52,10 +52,11 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; public class MessagePackParserTest extends MessagePackDataformatTestBase @@ -450,7 +451,7 @@ public void setup(File f) return tempFile; } - @Test(expected = IOException.class) + @Test public void testEnableFeatureAutoCloseSource() throws Exception { @@ -459,7 +460,9 @@ public void testEnableFeatureAutoCloseSource() FileInputStream in = new FileInputStream(tempFile); ObjectMapper objectMapper = new ObjectMapper(factory); objectMapper.readValue(in, new TypeReference>() {}); - objectMapper.readValue(in, new TypeReference>() {}); + assertThrows(IOException.class, () -> { + objectMapper.readValue(in, new TypeReference>() {}); + }); } @Test diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java index 05851dbc..074d7bf5 100755 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/TimestampExtensionModuleTest.java @@ -16,8 +16,8 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageUnpacker; @@ -26,7 +26,7 @@ import java.io.IOException; import java.time.Instant; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class TimestampExtensionModuleTest { @@ -46,7 +46,7 @@ private static class TripleInstants public Instant c; } - @Before + @BeforeEach public void setUp() throws Exception { diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java index fea34fd8..8ae73d0b 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatHugeDataBenchmarkTest.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.msgpack.jackson.dataformat.MessagePackFactory; import java.io.File; diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java index 2713eaea..8042153d 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/benchmark/MessagePackDataformatPojoBenchmarkTest.java @@ -17,7 +17,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.msgpack.jackson.dataformat.MessagePackFactory; import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.NormalPojo; import static org.msgpack.jackson.dataformat.MessagePackDataformatTestBase.Suit; From faabef5592c6e25d750b28bc001131261b9fb5b9 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 19 Jul 2025 18:40:00 +0200 Subject: [PATCH 170/195] Update airframe-json, airspec to 2025.1.14 (#889) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index d4645a11..301b88b4 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ Global / concurrentRestrictions := Seq( Tags.limit(Tags.Test, 1) ) -val AIRFRAME_VERSION = "2025.1.1" +val AIRFRAME_VERSION = "2025.1.14" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 7a31503f71a269fff6bb238858a169934316ecd6 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 19 Jul 2025 18:40:10 +0200 Subject: [PATCH 171/195] Update sbt, scripted-plugin to 1.10.11 (#881) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 8fc29878..fa5667a7 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.7 +sbt.version=1.10.11 From 5c57bcffc27c0f10a294d6b9e4fa8039d595820d Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 09:41:32 -0700 Subject: [PATCH 172/195] Upgrade sbt to 1.11.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update from sbt 1.10.11 to the latest stable version 1.11.3. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index fa5667a7..138bc7a5 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.10.11 +sbt.version=1.11.3 From 83a18920dac1baa101b1063801560fb37cec2071 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 10:11:44 -0700 Subject: [PATCH 173/195] Migrate from sbt-sonatype to built-in sonaRelease (#898) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update sbt-dynver to 5.1.1 Fixes #892 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Migrate from sbt-sonatype to built-in sonaRelease - Remove sbt-sonatype plugin dependency from project/plugins.sbt - Move publishing metadata from sonatype.sbt to build.sbt - Update publishTo configuration to use direct Sonatype URLs - Use built-in sbt functionality instead of plugin for Sonatype publishing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Update to sbt 1.11.3 and fix publishTo configuration - Update sbt version to 1.11.3 for built-in localStaging support - Fix publishTo setting to use correct Sonatype Central URLs - Use localStaging.value for releases and central-snapshots for snapshots 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Format code with scalafmt and fix scalafmt configuration - Fix .scalafmt.conf with version 3.9.8 and scala213 dialect - Format Scala test code according to project style - Maintain 180 character line limit and alignment style 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Update GitHub Actions workflows for Sonatype Central migration - Fix secret names to use SONATYPE_USERNAME and SONATYPE_PASSWORD - Remove deprecated sonatypeBundleRelease command from release workflow - Consolidate release steps to use publishSigned with correct environment - Update both release.yml and snapshot.yml workflows 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Use sonaRelease command in release workflow - Replace publishSigned with sonaRelease for proper release flow - sonaRelease handles both publishing and release to Central Portal 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Add publishSigned step back to release workflow - First step: publishSigned to stage signed artifacts - Second step: sonaRelease to release staged artifacts to Central - Both steps needed for proper release flow 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Revert to original workflow structure with updated secrets - Restore "Build bundle" and "Release to Sonatype" step names - Keep publishSigned in Build bundle step - Use sonaRelease in Release step with correct secret names - Maintain original workflow structure with modern functionality 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --------- Co-authored-by: Claude --- .github/workflows/release.yml | 6 ++--- .github/workflows/snapshot.yml | 4 ++-- .scalafmt.conf | 2 ++ build.sbt | 24 ++++++++++++++++++- .../msgpack/core/InvalidDataReadTest.scala | 3 +-- .../org/msgpack/core/MessageFormatTest.scala | 3 +-- .../org/msgpack/core/MessagePackSpec.scala | 2 +- .../org/msgpack/core/MessagePackTest.scala | 23 +++++++++--------- .../org/msgpack/core/MessagePackerTest.scala | 15 ++++++------ .../msgpack/core/MessageUnpackerTest.scala | 4 ++-- .../core/buffer/MessageBufferInputTest.scala | 2 +- .../core/buffer/MessageBufferTest.scala | 3 +-- .../core/example/MessagePackExampleTest.scala | 3 +-- .../org/msgpack/value/ValueFactoryTest.scala | 3 +-- .../org/msgpack/value/ValueTypeTest.scala | 3 +-- .../org/msgpack/value/VariableTest.scala | 10 ++++---- project/plugins.sbt | 1 - sonatype.sbt | 18 -------------- 18 files changed, 62 insertions(+), 67 deletions(-) delete mode 100644 sonatype.sbt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b214d8ec..c3dca7c2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,6 +33,6 @@ jobs: ./sbt publishSigned - name: Release to Sonatype env: - SONATYPE_USERNAME: '${{ secrets.SONATYPE_USER }}' - SONATYPE_PASSWORD: '${{ secrets.SONATYPE_PASS }}' - run: ./sbt sonatypeBundleRelease + SONATYPE_USERNAME: '${{ secrets.SONATYPE_USERNAME }}' + SONATYPE_PASSWORD: '${{ secrets.SONATYPE_PASSWORD }}' + run: ./sbt sonaRelease diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index cbce4c14..4cc85866 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -27,6 +27,6 @@ jobs: distribution: adopt - name: Publish snapshots env: - SONATYPE_USERNAME: '${{ secrets.SONATYPE_USER }}' - SONATYPE_PASSWORD: '${{ secrets.SONATYPE_PASS }}' + SONATYPE_USERNAME: '${{ secrets.SONATYPE_USERNAME }}' + SONATYPE_PASSWORD: '${{ secrets.SONATYPE_PASSWORD }}' run: ./sbt publish diff --git a/.scalafmt.conf b/.scalafmt.conf index bda502a5..eccdf1c2 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,3 +1,5 @@ +version = 3.9.8 +runner.dialect = scala213 maxColumn = 180 style = defaultWithAlign optIn.breaksInsideChains = true diff --git a/build.sbt b/build.sbt index 301b88b4..70c8161e 100644 --- a/build.sbt +++ b/build.sbt @@ -12,6 +12,24 @@ ThisBuild / dynverSonatypeSnapshots := true // Use coursier friendly version separator ThisBuild / dynverSeparator := "-" +// Publishing metadata +ThisBuild / homepage := Some(url("https://msgpack.org/")) +ThisBuild / licenses := Seq("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")) +ThisBuild / scmInfo := Some( + ScmInfo( + url("https://github.com/msgpack/msgpack-java"), + "scm:git@github.com:msgpack/msgpack-java.git" + ) +) +ThisBuild / developers := List( + Developer(id = "frsyuki", name = "Sadayuki Furuhashi", email = "frsyuki@users.sourceforge.jp", url = url("https://github.com/frsyuki")), + Developer(id = "muga", name = "Muga Nishizawa", email = "muga.nishizawa@gmail.com", url = url("https://github.com/muga")), + Developer(id = "oza", name = "Tsuyoshi Ozawa", email = "ozawa.tsuyoshi@gmail.com", url = url("https://github.com/oza")), + Developer(id = "komamitsu", name = "Mitsunori Komatsu", email = "komamitsu@gmail.com", url = url("https://github.com/komamitsu")), + Developer(id = "xerial", name = "Taro L. Saito", email = "leo@xerial.org", url = url("https://github.com/xerial")) +) + + val buildSettings = Seq[Setting[_]]( organization := "org.msgpack", organizationName := "MessagePack", @@ -38,7 +56,11 @@ val buildSettings = Seq[Setting[_]]( } }, // Add sonatype repository settings - publishTo := sonatypePublishToBundle.value, + publishTo := { + val centralSnapshots = "https://central.sonatype.com/repository/maven-snapshots/" + if (isSnapshot.value) Some("central-snapshots" at centralSnapshots) + else localStaging.value + }, // Style check config: (sbt-jchekcstyle) jcheckStyleConfig := "facebook", // Run jcheckstyle both for main and test codes diff --git a/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala index 6f013838..1c43bb33 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala @@ -3,8 +3,7 @@ package org.msgpack.core import org.msgpack.core.MessagePackSpec.createMessagePackData import wvlet.airspec.AirSpec -/** - */ +/** */ class InvalidDataReadTest extends AirSpec { test("Reading long EXT32") { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala index 06a58e11..782b2e40 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala @@ -22,8 +22,7 @@ import wvlet.airspec.spi.AirSpecException import scala.util.Random -/** - * Created on 2014/05/07. +/** Created on 2014/05/07. */ class MessageFormatTest extends AirSpec with Benchmark { test("MessageFormat") { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala index dee315cd..c4fb23b4 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala @@ -21,7 +21,7 @@ import wvlet.log.io.{TimeReport, Timer} import java.io.ByteArrayOutputStream object MessagePackSpec { - def toHex(arr: Array[Byte]) = arr.map(x => f"$x%02x").mkString(" ") + def toHex(arr: Array[Byte]) = arr.map(x => f"$x%02x").mkString(" ") def createMessagePackData(f: MessagePacker => Unit): Array[Byte] = { val b = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(b) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index c2993f96..0cec1b4b 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -30,8 +30,7 @@ import java.nio.charset.{CodingErrorAction, UnmappableCharacterException} import java.time.Instant import scala.util.Random -/** - * Created on 2014/05/07. +/** Created on 2014/05/07. */ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { @@ -396,7 +395,7 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { test("report errors when packing/unpacking malformed strings") { pending("We need to produce malformed utf-8 strings in Java 8") // Create 100 malformed UTF8 Strings - val r = new Random(0) + val r = new Random(0) val malformedStrings = Iterator .continually { val b = new Array[Byte](10) @@ -433,7 +432,7 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { test("report errors when packing/unpacking strings that contain unmappable characters") { val unmappable = Array[Byte](0xfc.toByte, 0x0a.toByte) - //val unmappableChar = Array[Char](new Character(0xfc0a).toChar) + // val unmappableChar = Array[Char](new Character(0xfc0a).toChar) // Report error on unmappable character val unpackerConfig = new UnpackerConfig() @@ -534,10 +533,9 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { m, { packer => packer.packMapHeader(v.length) - m.map { - case (k: Int, v: String) => - packer.packInt(k) - packer.packString(v) + m.map { case (k: Int, v: String) => + packer.packInt(k) + packer.packString(v) } }, { unpacker => @@ -666,13 +664,14 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { val posLong = Gen.chooseNum[Long](-31557014167219200L, 31556889864403199L) forAll(posLong) { (millis: Long) => val v = Instant.ofEpochMilli(millis) - check(v, { _.packTimestamp(millis) }, + check( + v, + { _.packTimestamp(millis) }, { u => val extHeader = u.unpackExtensionTypeHeader() - if(extHeader.isTimestampType) { + if (extHeader.isTimestampType) { u.unpackTimestamp(extHeader) - } - else { + } else { fail("Cannot reach here") } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index dea3e4ea..7d762149 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -24,8 +24,7 @@ import wvlet.log.io.IOUtil.withResource import java.io.{ByteArrayOutputStream, File, FileInputStream, FileOutputStream} import scala.util.Random -/** - */ +/** */ class MessagePackerTest extends AirSpec with Benchmark { private def verifyIntSeq(answer: Array[Int], packed: Array[Byte]): Unit = { @@ -141,8 +140,8 @@ class MessagePackerTest extends AirSpec with Benchmark { 32 -> 31, 34 -> 32 ) - testCases.foreach { - case (bufferSize, stringSize) => test(bufferSize, stringSize) + testCases.foreach { case (bufferSize, stringSize) => + test(bufferSize, stringSize) } } @@ -234,7 +233,7 @@ class MessagePackerTest extends AirSpec with Benchmark { } test("compute totalWrittenBytes") { - val out = new ByteArrayOutputStream + val out = new ByteArrayOutputStream val packerTotalWrittenBytes = withResource(MessagePack.newDefaultPacker(out)) { packer => packer @@ -255,7 +254,7 @@ class MessagePackerTest extends AirSpec with Benchmark { test("support read-only buffer") { val payload = Array[Byte](1) val out = new ByteArrayOutputStream() - val packer = MessagePack + val packer = MessagePack .newDefaultPacker(out) .packBinaryHeader(1) .writePayload(payload) @@ -299,14 +298,14 @@ class MessagePackerTest extends AirSpec with Benchmark { test("write raw binary") { val packer = new MessagePack.PackerConfig().newBufferPacker() - val msg = + val msg = Array[Byte](-127, -92, 116, 121, 112, 101, -92, 112, 105, 110, 103) packer.writePayload(msg) } test("append raw binary") { val packer = new MessagePack.PackerConfig().newBufferPacker() - val msg = + val msg = Array[Byte](-127, -92, 116, 121, 112, 101, -92, 112, 105, 110, 103) packer.addPayload(msg) } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 3ea5e911..620e7dbe 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -30,7 +30,7 @@ import scala.util.Random object MessageUnpackerTest { class SplitMessageBufferInput(array: Array[Array[Byte]]) extends MessageBufferInput { - var cursor = 0 + var cursor = 0 override def next(): MessageBuffer = { if (cursor < array.length) { val a = array(cursor) @@ -49,7 +49,7 @@ import org.msgpack.core.MessageUnpackerTest._ class MessageUnpackerTest extends AirSpec with Benchmark { - private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] + private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] private def testData: Array[Byte] = { val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala index dd1cdb97..a43704fb 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala @@ -33,7 +33,7 @@ class MessageBufferInputTest extends AirSpec { Seq(0, 10, 500, 1000, 2000, 4000, 8000, 10000, 30000, 50000, 100000) private def testData(size: Int): Array[Byte] = { - //debug(s"test data size: ${size}") + // debug(s"test data size: ${size}") val b = new Array[Byte](size) Random.nextBytes(b) b diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 4de05995..03e93b89 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -21,8 +21,7 @@ import wvlet.airspec.AirSpec import java.nio.ByteBuffer import scala.util.Random -/** - * Created on 2014/05/01. +/** Created on 2014/05/01. */ class MessageBufferTest extends AirSpec with Benchmark { diff --git a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala index 99876275..d0b0e08e 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala @@ -17,8 +17,7 @@ package org.msgpack.core.example import wvlet.airspec.AirSpec -/** - */ +/** */ class MessagePackExampleTest extends AirSpec { test("example") { diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 3fe2a07f..3568ba5b 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -19,8 +19,7 @@ import org.scalacheck.Gen import wvlet.airspec.AirSpec import wvlet.airspec.spi.PropertyCheck -/** - */ +/** */ class ValueFactoryTest extends AirSpec with PropertyCheck { private def isValid( diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index e8b04d5f..fc81bdeb 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -19,8 +19,7 @@ import org.msgpack.core.MessagePack.Code._ import org.msgpack.core.{MessageFormat, MessageFormatException} import wvlet.airspec.AirSpec -/** - * Created on 2014/05/06. +/** Created on 2014/05/06. */ class ValueTypeTest extends AirSpec { diff --git a/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala index 5d97d871..f9a1c2a0 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala @@ -23,8 +23,7 @@ import java.time.Instant import java.util import scala.jdk.CollectionConverters._ -/** - */ +/** */ class VariableTest extends AirSpec with PropertyCheck { private def check(pack: MessagePacker => Unit, checker: Variable => Unit): Unit = { val packer = MessagePack.newDefaultBufferPacker() @@ -38,8 +37,7 @@ class VariableTest extends AirSpec with PropertyCheck { unpacker.close() } - /** - * Test Value -> MsgPack -> Value + /** Test Value -> MsgPack -> Value */ private def roundTrip(v: Value): Unit = { val packer = MessagePack.newDefaultBufferPacker() @@ -210,8 +208,8 @@ class VariableTest extends AirSpec with PropertyCheck { _.packDouble(x), checker = { v => val iv = validateValue(v.asFloatValue(), asFloat = true) - //iv.toDouble shouldBe v - //iv.toFloat shouldBe x.toFloat + // iv.toDouble shouldBe v + // iv.toFloat shouldBe x.toFloat } ) } diff --git a/project/plugins.sbt b/project/plugins.sbt index d6844375..5bc49937 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,3 @@ -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter diff --git a/sonatype.sbt b/sonatype.sbt deleted file mode 100644 index 3fcb592f..00000000 --- a/sonatype.sbt +++ /dev/null @@ -1,18 +0,0 @@ -import xerial.sbt.Sonatype._ - -ThisBuild / sonatypeProfileName := "org.msgpack" -ThisBuild / homepage := Some(url("https://msgpack.org/")) -ThisBuild / licenses := Seq("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")) -ThisBuild / scmInfo := Some( - ScmInfo( - url("https://github.com/msgpack/msgpack-java"), - "scm:git@github.com:msgpack/msgpack-java.git" - ) -) -ThisBuild / developers := List( - Developer(id = "frsyuki", name = "Sadayuki Furuhashi", email = "frsyuki@users.sourceforge.jp", url = url("https://github.com/frsyuki")), - Developer(id = "muga", name = "Muga Nishizawa", email = "muga.nishizawa@gmail.com", url = url("https://github.com/muga")), - Developer(id = "oza", name = "Tsuyoshi Ozawa", email = "ozawa.tsuyoshi@gmail.com", url = url("https://github.com/oza")), - Developer(id = "komamitsu", name = "Mitsunori Komatsu", email = "komamitsu@gmail.com", url = url("https://github.com/komamitsu")), - Developer(id = "xerial", name = "Taro L. Saito", email = "leo@xerial.org", url = url("https://github.com/xerial")) -) From 4bcc43e5e539fdc05cc790852f82fb53618892dd Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 10:24:00 -0700 Subject: [PATCH 174/195] Upgrade Scala to 3.7.1 and update code format style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgrade Scala version from 2.13.12 to 3.7.1 in build.sbt - Update scalafmt.conf to use Scala 3 dialect and modern formatting rules - Fix Scala 3 compatibility issues in test files: - Update lambda syntax to use parentheses around parameters - Remove deprecated underscore suffix from function references - Apply Scala 3 formatting with scalafmt 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .scalafmt.conf | 18 +- build.sbt | 2 +- .../msgpack/core/InvalidDataReadTest.scala | 18 +- .../core/MessageBufferPackerTest.scala | 5 +- .../org/msgpack/core/MessageFormatTest.scala | 45 +- .../org/msgpack/core/MessagePackSpec.scala | 26 +- .../org/msgpack/core/MessagePackTest.scala | 312 +++++---- .../org/msgpack/core/MessagePackerTest.scala | 151 ++--- .../msgpack/core/MessageUnpackerTest.scala | 628 +++++++++--------- .../org/msgpack/core/StringLimitTest.scala | 5 +- .../msgpack/core/buffer/ByteStringTest.scala | 29 +- .../core/buffer/DirectBufferAccessTest.scala | 3 +- .../core/buffer/MessageBufferInputTest.scala | 128 ++-- .../core/buffer/MessageBufferOutputTest.scala | 19 +- .../core/buffer/MessageBufferTest.scala | 95 ++- .../core/example/MessagePackExampleTest.scala | 6 +- .../value/RawStringValueImplTest.scala | 3 +- .../org/msgpack/value/ValueFactoryTest.scala | 60 +- .../scala/org/msgpack/value/ValueTest.scala | 25 +- .../org/msgpack/value/ValueTypeTest.scala | 49 +- .../org/msgpack/value/VariableTest.scala | 226 +++---- 21 files changed, 904 insertions(+), 949 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index eccdf1c2..fcadd98d 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,5 +1,17 @@ -version = 3.9.8 -runner.dialect = scala213 -maxColumn = 180 +version = 3.9.4 +project.layout = StandardConvention +runner.dialect = scala3 +maxColumn = 100 style = defaultWithAlign +docstrings.blankFirstLine = yes +rewrite.scala3.convertToNewSyntax = true +rewrite.scala3.removeOptionalBraces = yes +rewrite.scala3.insertEndMarkerMinLines = 30 +# Add a new line before case class +newlines.topLevelStatementBlankLines = [ + { + blanks { after = 1 } + } +] +newlines.source = unfold optIn.breaksInsideChains = true diff --git a/build.sbt b/build.sbt index 70c8161e..3d6ba320 100644 --- a/build.sbt +++ b/build.sbt @@ -35,7 +35,7 @@ val buildSettings = Seq[Setting[_]]( organizationName := "MessagePack", organizationHomepage := Some(url("http://msgpack.org/")), description := "MessagePack for Java", - scalaVersion := "2.13.12", + scalaVersion := "3.7.1", Test / logBuffered := false, // msgpack-java should be a pure-java library, so remove Scala specific configurations autoScalaLibrary := false, diff --git a/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala index 1c43bb33..76f04c97 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala @@ -3,21 +3,21 @@ package org.msgpack.core import org.msgpack.core.MessagePackSpec.createMessagePackData import wvlet.airspec.AirSpec -/** */ -class InvalidDataReadTest extends AirSpec { +/** + */ +class InvalidDataReadTest extends AirSpec: test("Reading long EXT32") { // Prepare an EXT32 data with 2GB (Int.MaxValue size) payload for testing the behavior of MessageUnpacker.skipValue() // Actually preparing 2GB of data, however, is too much for CI, so we create only the header part. - val msgpack = createMessagePackData(p => p.packExtensionTypeHeader(MessagePack.Code.EXT32, Int.MaxValue)) - val u = MessagePack.newDefaultUnpacker(msgpack) - try { + val msgpack = createMessagePackData(p => + p.packExtensionTypeHeader(MessagePack.Code.EXT32, Int.MaxValue) + ) + val u = MessagePack.newDefaultUnpacker(msgpack) + try // This error will be thrown after reading the header as the input has no EXT32 body intercept[MessageInsufficientBufferException] { u.skipValue() } - } finally { - u.close() - } + finally u.close() } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageBufferPackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageBufferPackerTest.scala index 58b29f43..f4b74986 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageBufferPackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageBufferPackerTest.scala @@ -17,10 +17,10 @@ package org.msgpack.core import java.io.ByteArrayOutputStream import java.util.Arrays -import org.msgpack.value.ValueFactory._ +import org.msgpack.value.ValueFactory.* import wvlet.airspec.AirSpec -class MessageBufferPackerTest extends AirSpec { +class MessageBufferPackerTest extends AirSpec: test("MessageBufferPacker") { test("be equivalent to ByteArrayOutputStream") { val packer1 = MessagePack.newDefaultBufferPacker @@ -48,4 +48,3 @@ class MessageBufferPackerTest extends AirSpec { } } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala index 782b2e40..a626978d 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala @@ -22,48 +22,41 @@ import wvlet.airspec.spi.AirSpecException import scala.util.Random -/** Created on 2014/05/07. +/** + * Created on 2014/05/07. */ -class MessageFormatTest extends AirSpec with Benchmark { +class MessageFormatTest extends AirSpec with Benchmark: test("MessageFormat") { test("cover all byte codes") { - def checkV(b: Byte, tpe: ValueType): Unit = { - try MessageFormat.valueOf(b).getValueType shouldBe tpe - catch { + def checkV(b: Byte, tpe: ValueType): Unit = + try + MessageFormat.valueOf(b).getValueType shouldBe tpe + catch case e: AirSpecException => error(f"Failure when looking at byte ${b}%02x") throw e - } - } - def checkF(b: Byte, f: MessageFormat): Unit = { - MessageFormat.valueOf(b) shouldBe f - } + def checkF(b: Byte, f: MessageFormat): Unit = MessageFormat.valueOf(b) shouldBe f - def check(b: Byte, tpe: ValueType, f: MessageFormat): Unit = { + def check(b: Byte, tpe: ValueType, f: MessageFormat): Unit = checkV(b, tpe) checkF(b, f) - } - for (i <- 0 until 0x7f) { + for i <- 0 until 0x7f do check(i.toByte, ValueType.INTEGER, MessageFormat.POSFIXINT) - } - for (i <- 0x80 until 0x8f) { + for i <- 0x80 until 0x8f do check(i.toByte, ValueType.MAP, MessageFormat.FIXMAP) - } - for (i <- 0x90 until 0x9f) { + for i <- 0x90 until 0x9f do check(i.toByte, ValueType.ARRAY, MessageFormat.FIXARRAY) - } check(Code.NIL, ValueType.NIL, MessageFormat.NIL) MessageFormat.valueOf(Code.NEVER_USED) shouldBe MessageFormat.NEVER_USED - for (i <- Seq(Code.TRUE, Code.FALSE)) { + for i <- Seq(Code.TRUE, Code.FALSE) do check(i, ValueType.BOOLEAN, MessageFormat.BOOLEAN) - } check(Code.BIN8, ValueType.BINARY, MessageFormat.BIN8) check(Code.BIN16, ValueType.BINARY, MessageFormat.BIN16) @@ -97,9 +90,8 @@ class MessageFormatTest extends AirSpec with Benchmark { check(Code.ARRAY16, ValueType.ARRAY, MessageFormat.ARRAY16) check(Code.ARRAY32, ValueType.ARRAY, MessageFormat.ARRAY32) - for (i <- 0xe0 to 0xff) { + for i <- 0xe0 to 0xff do check(i.toByte, ValueType.INTEGER, MessageFormat.NEGFIXINT) - } } test("improve the valueOf performance") { @@ -112,20 +104,19 @@ class MessageFormatTest extends AirSpec with Benchmark { time("lookup", repeat = 10) { block("switch") { var i = 0 - while (i < N) { + while i < N do MessageFormat.toMessageFormat(idx(i)) i += 1 - } } block("table") { var i = 0 - while (i < N) { + while i < N do MessageFormat.valueOf(idx(i)) i += 1 - } } } } } -} + +end MessageFormatTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala index c4fb23b4..135c4921 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackSpec.scala @@ -20,31 +20,29 @@ import wvlet.log.io.{TimeReport, Timer} import java.io.ByteArrayOutputStream -object MessagePackSpec { - def toHex(arr: Array[Byte]) = arr.map(x => f"$x%02x").mkString(" ") - def createMessagePackData(f: MessagePacker => Unit): Array[Byte] = { +object MessagePackSpec: + def toHex(arr: Array[Byte]) = arr.map(x => f"$x%02x").mkString(" ") + def createMessagePackData(f: MessagePacker => Unit): Array[Byte] = val b = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(b) f(packer) packer.close() b.toByteArray - } -} -trait Benchmark extends Timer { +trait Benchmark extends Timer: private val numWarmUpRuns = 10 - override protected def time[A](blockName: String, logLevel: LogLevel = LogLevel.INFO, repeat: Int = 1, blockRepeat: Int = 1)(f: => A): TimeReport = { - super.time(blockName, logLevel = LogLevel.INFO, repeat)(f) - } + override protected def time[A]( + blockName: String, + logLevel: LogLevel = LogLevel.INFO, + repeat: Int = 1, + blockRepeat: Int = 1 + )(f: => A): TimeReport = super.time(blockName, logLevel = LogLevel.INFO, repeat)(f) - override protected def block[A](name: String)(f: => A): TimeReport = { + override protected def block[A](name: String)(f: => A): TimeReport = var i = 0 - while (i < numWarmUpRuns) { + while i < numWarmUpRuns do f i += 1 - } super.block(name)(f) - } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 0cec1b4b..0a4328d8 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -30,27 +30,26 @@ import java.nio.charset.{CodingErrorAction, UnmappableCharacterException} import java.time.Instant import scala.util.Random -/** Created on 2014/05/07. +/** + * Created on 2014/05/07. */ -class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { +class MessagePackTest extends AirSpec with PropertyCheck with Benchmark: - private def isValidUTF8(s: String) = { - MessagePack.UTF8.newEncoder().canEncode(s) - } + private def isValidUTF8(s: String) = MessagePack.UTF8.newEncoder().canEncode(s) - private def containsUnmappableCharacter(s: String): Boolean = { - try { - MessagePack.UTF8 + private def containsUnmappableCharacter(s: String): Boolean = + try + MessagePack + .UTF8 .newEncoder() .onUnmappableCharacter(CodingErrorAction.REPORT) .encode(CharBuffer.wrap(s)) false - } catch { + catch case e: UnmappableCharacterException => true - case _: Exception => false - } - } + case _: Exception => + false test("clone packer config") { val config = new PackerConfig() @@ -77,13 +76,11 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { test("detect fixint values") { - for (i <- 0 until 0x7f) { + for i <- 0 until 0x7f do Code.isPosFixInt(i.toByte) shouldBe true - } - for (i <- 0x80 until 0xff) { + for i <- 0x80 until 0xff do Code.isPosFixInt(i.toByte) shouldBe false - } } test("detect fixarray values") { @@ -92,12 +89,11 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { packer.close val bytes = packer.toByteArray MessagePack.newDefaultUnpacker(bytes).unpackArrayHeader() shouldBe 0 - try { + try MessagePack.newDefaultUnpacker(bytes).unpackMapHeader() fail("Shouldn't reach here") - } catch { + catch case e: MessageTypeException => // OK - } } test("detect fixmap values") { @@ -106,12 +102,11 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { packer.close val bytes = packer.toByteArray MessagePack.newDefaultUnpacker(bytes).unpackMapHeader() shouldBe 0 - try { + try MessagePack.newDefaultUnpacker(bytes).unpackArrayHeader() fail("Shouldn't reach here") - } catch { + catch case e: MessageTypeException => // OK - } } test("detect fixint quickly") { @@ -124,34 +119,28 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { block("mask") { var i = 0 var count = 0 - while (i < N) { - if ((idx(i) & Code.POSFIXINT_MASK) == 0) { + while i < N do + if (idx(i) & Code.POSFIXINT_MASK) == 0 then count += 1 - } i += 1 - } } block("mask in func") { var i = 0 var count = 0 - while (i < N) { - if (Code.isPosFixInt(idx(i))) { + while i < N do + if Code.isPosFixInt(idx(i)) then count += 1 - } i += 1 - } } block("shift cmp") { var i = 0 var count = 0 - while (i < N) { - if ((idx(i) >>> 7) == 0) { + while i < N do + if (idx(i) >>> 7) == 0 then count += 1 - } i += 1 - } } @@ -161,13 +150,11 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { test("detect neg fix int values") { - for (i <- 0 until 0xe0) { + for i <- 0 until 0xe0 do Code.isNegFixInt(i.toByte) shouldBe false - } - for (i <- 0xe0 until 0xff) { + for i <- 0xe0 until 0xff do Code.isNegFixInt(i.toByte) shouldBe true - } } @@ -177,9 +164,9 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { unpack: MessageUnpacker => A, packerConfig: PackerConfig = new PackerConfig(), unpackerConfig: UnpackerConfig = new UnpackerConfig() - ): Boolean = { + ): Boolean = var b: Array[Byte] = null - try { + try val bs = new ByteArrayOutputStream() val packer = packerConfig.newPacker(bs) pack(packer) @@ -191,15 +178,12 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { val ret = unpack(unpacker) ret shouldBe v true - } catch { + catch case e: Exception => warn(e.getMessage) - if (b != null) { + if b != null then warn(s"packed data (size:${b.length}): ${toHex(b)}") - } throw e - } - } private def checkException[A]( v: A, @@ -207,7 +191,7 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { unpack: MessageUnpacker => A, packerConfig: PackerConfig = new PackerConfig(), unpaackerConfig: UnpackerConfig = new UnpackerConfig() - ): Unit = { + ): Unit = var b: Array[Byte] = null val bs = new ByteArrayOutputStream() val packer = packerConfig.newPacker(bs) @@ -220,15 +204,16 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { val ret = unpack(unpacker) fail("cannot not reach here") - } - private def checkOverflow[A](v: A, pack: MessagePacker => Unit, unpack: MessageUnpacker => A): Unit = { - try { + private def checkOverflow[A]( + v: A, + pack: MessagePacker => Unit, + unpack: MessageUnpacker => A + ): Unit = + try checkException[A](v, pack, unpack) - } catch { + catch case e: MessageIntegerOverflowException => // OK - } - } test("pack/unpack primitive values") { forAll { (v: Boolean) => @@ -256,7 +241,8 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { null, _.packNil, { unpacker => - unpacker.unpackNil(); null + unpacker.unpackNil(); + null } ) } @@ -278,29 +264,35 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { packer.packString("val") }, { unpacker => - unpacker.tryUnpackNil(); unpacker.unpackString() + unpacker.tryUnpackNil(); + unpacker.unpackString() } ) check( "val", { packer => - packer.packNil(); packer.packString("val") + packer.packNil(); + packer.packString("val") }, { unpacker => - unpacker.tryUnpackNil(); unpacker.unpackString() + unpacker.tryUnpackNil(); + unpacker.unpackString() } ) - try { - checkException(null, { _ => }, _.tryUnpackNil) - } catch { + try + checkException( + null, + { _ => + }, + _.tryUnpackNil + ) + catch case e: MessageInsufficientBufferException => // OK - } } test("pack/unpack integer values") { val sampleData = Seq[Long]( - Int.MinValue.toLong - - 10, + Int.MinValue.toLong - 10, -65535, -8191, -1024, @@ -326,31 +318,26 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { 65536, Int.MaxValue.toLong + 10 ) - for (v <- sampleData) { + for v <- sampleData do check(v, _.packLong(v), _.unpackLong) - if (v.isValidInt) { + if v.isValidInt then val vi = v.toInt check(vi, _.packInt(vi), _.unpackInt) - } else { + else checkOverflow(v, _.packLong(v), _.unpackInt) - } - if (v.isValidShort) { + if v.isValidShort then val vi = v.toShort check(vi, _.packShort(vi), _.unpackShort) - } else { + else checkOverflow(v, _.packLong(v), _.unpackShort) - } - if (v.isValidByte) { + if v.isValidByte then val vi = v.toByte check(vi, _.packByte(vi), _.unpackByte) - } else { + else checkOverflow(v, _.packLong(v), _.unpackByte) - } - - } } @@ -360,23 +347,19 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { check(v, _.packBigInteger(v), _.unpackBigInteger) } - for (bi <- Seq(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(1)))) { + for bi <- Seq(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(1))) do check(bi, _.packBigInteger(bi), _.unpackBigInteger()) - } - for (bi <- Seq(BigInteger.valueOf(Long.MaxValue).shiftLeft(10))) { - try { + for bi <- Seq(BigInteger.valueOf(Long.MaxValue).shiftLeft(10)) do + try checkException(bi, _.packBigInteger(bi), _.unpackBigInteger()) fail("cannot reach here") - } catch { + catch case e: IllegalArgumentException => // OK - } - } - } test("pack/unpack strings") { - val utf8Strings = Arbitrary.arbitrary[String].suchThat(isValidUTF8 _) + val utf8Strings = Arbitrary.arbitrary[String].suchThat(isValidUTF8) utf8Strings.map { v => check(v, _.packString(v), _.unpackString) } @@ -385,17 +368,15 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { test("pack/unpack large strings") { // Large string val strLen = Seq(1000, 2000, 10000, 50000, 100000, 500000) - for (l <- strLen) { - val v: String = - Iterator.continually(Random.nextString(l * 10)).find(isValidUTF8).get + for l <- strLen do + val v: String = Iterator.continually(Random.nextString(l * 10)).find(isValidUTF8).get check(v, _.packString(v), _.unpackString) - } } test("report errors when packing/unpacking malformed strings") { pending("We need to produce malformed utf-8 strings in Java 8") // Create 100 malformed UTF8 Strings - val r = new Random(0) + val r = new Random(0) val malformedStrings = Iterator .continually { val b = new Array[Byte](10) @@ -405,16 +386,14 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { .filter(b => !isValidUTF8(new String(b))) .take(100) - for (malformedBytes <- malformedStrings) { + for malformedBytes <- malformedStrings do // Pack tests val malformed = new String(malformedBytes) - try { + try checkException(malformed, _.packString(malformed), _.unpackString()) - } catch { + catch case e: MessageStringCodingException => // OK - } - - try { + try checkException( malformed, { packer => @@ -423,10 +402,8 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { }, _.unpackString() ) - } catch { + catch case e: MessageStringCodingException => // OK - } - } } test("report errors when packing/unpacking strings that contain unmappable characters") { @@ -439,8 +416,8 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { .withActionOnMalformedString(CodingErrorAction.REPORT) .withActionOnUnmappableString(CodingErrorAction.REPORT) - for (bytes <- Seq(unmappable)) { - try { + for bytes <- Seq(unmappable) do + try checkException( bytes, { packer => @@ -451,10 +428,8 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { new PackerConfig(), unpackerConfig ) - } catch { + catch case e: MessageStringCodingException => // OK - } - } } test("pack/unpack binary") { @@ -462,7 +437,8 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { check( v, { packer => - packer.packBinaryHeader(v.length); packer.writePayload(v) + packer.packBinaryHeader(v.length); + packer.writePayload(v) }, { unpacker => val len = unpacker.unpackBinaryHeader() @@ -474,13 +450,14 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { } val len = Seq(1000, 2000, 10000, 50000, 100000, 500000) - for (l <- len) { + for l <- len do val v = new Array[Byte](l) Random.nextBytes(v) check( v, { packer => - packer.packBinaryHeader(v.length); packer.writePayload(v) + packer.packBinaryHeader(v.length); + packer.writePayload(v) }, { unpacker => val len = unpacker.unpackBinaryHeader() @@ -489,10 +466,11 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { out } ) - } } - val testHeaderLength = Seq(1, 2, 4, 8, 16, 17, 32, 64, 255, 256, 1000, 2000, 10000, 50000, 100000, 500000) + val testHeaderLength = Seq( + 1, 2, 4, 8, 16, 17, 32, 64, 255, 256, 1000, 2000, 10000, 50000, 100000, 500000 + ) test("pack/unpack arrays") { forAll { (v: Array[Int]) => @@ -505,24 +483,20 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { { unpacker => val len = unpacker.unpackArrayHeader() val out = new Array[Int](len) - for (i <- 0 until v.length) { + for i <- 0 until v.length do out(i) = unpacker.unpackInt - } out } ) } - for (l <- testHeaderLength) { + for l <- testHeaderLength do check(l, _.packArrayHeader(l), _.unpackArrayHeader()) - } - try { + try checkException(0, _.packArrayHeader(-1), _.unpackArrayHeader) - } catch { + catch case e: IllegalArgumentException => // OK - } - } test("pack/unpack maps") { @@ -541,40 +515,43 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { { unpacker => val len = unpacker.unpackMapHeader() val b = Seq.newBuilder[(Int, String)] - for (i <- 0 until len) { + for i <- 0 until len do b += ((unpacker.unpackInt, unpacker.unpackString)) - } b.result() } ) } - for (l <- testHeaderLength) { + for l <- testHeaderLength do check(l, _.packMapHeader(l), _.unpackMapHeader()) - } - try { + try checkException(0, _.packMapHeader(-1), _.unpackMapHeader) - } catch { + catch case e: IllegalArgumentException => // OK - } - } test("pack/unpack extension types") { forAll { (dataLen: Int, tpe: Byte) => val l = Math.abs(dataLen) l >= 0 ==> { - val ext = - new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(tpe), l) - check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) + val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(tpe), l) + check( + ext, + _.packExtensionTypeHeader(ext.getType, ext.getLength), + _.unpackExtensionTypeHeader() + ) } } - for (l <- testHeaderLength) { - val ext = new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(Random.nextInt(128)), l) - check(ext, _.packExtensionTypeHeader(ext.getType, ext.getLength), _.unpackExtensionTypeHeader()) - } + for l <- testHeaderLength do + val ext = + new ExtensionTypeHeader(ExtensionTypeHeader.checkedCastToByte(Random.nextInt(128)), l) + check( + ext, + _.packExtensionTypeHeader(ext.getType, ext.getLength), + _.unpackExtensionTypeHeader() + ) } @@ -585,31 +562,30 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { aMap, { packer => packer.packArrayHeader(aMap.size) - for (m <- aMap) { + for m <- aMap do packer.packMapHeader(m.size) - for ((k, v) <- m) { + for (k, v) <- m do packer.packString(k) packer.packString(v) - } - } }, { unpacker => val v = new Variable() unpacker.unpackValue(v) - import scala.jdk.CollectionConverters._ - v.asArrayValue().asScala + import scala.jdk.CollectionConverters.* + v.asArrayValue() + .asScala .map { m => val mv = m.asMapValue() val kvs = mv.getKeyValueArray kvs .grouped(2) - .map({ kvp: Array[Value] => + .map((kvp: Array[Value]) => val k = kvp(0) val v = kvp(1) (k.asStringValue().asString, v.asStringValue().asString) - }) + ) .toMap } .toList @@ -622,12 +598,24 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { val posInt = Gen.chooseNum(0, 1000000000 - 1) // NANOS_PER_SECOND forAll(posLong, posInt) { (second: Long, nano: Int) => val v = Instant.ofEpochSecond(second, nano) - check(v, { _.packTimestamp(v) }, { _.unpackTimestamp() }) + check( + v, { + _.packTimestamp(v) + }, { + _.unpackTimestamp() + } + ) } // Using different insterfaces forAll(posLong, posInt) { (second: Long, nano: Int) => val v = Instant.ofEpochSecond(second, nano) - check(v, { _.packTimestamp(second, nano) }, { _.unpackTimestamp() }) + check( + v, { + _.packTimestamp(second, nano) + }, { + _.unpackTimestamp() + } + ) } val secLessThan34bits = Gen.chooseNum[Long](0, 1L << 34) forAll(secLessThan34bits, posInt) { (second: Long, nano: Int) => @@ -640,23 +628,30 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { } // Corner-cases around uint32 boundaries - for ( - v <- Seq( - Instant.ofEpochSecond(Instant.now().getEpochSecond, 123456789L), // uint32 nanoseq (out of int32 range) - Instant.ofEpochSecond(-1302749144L, 0), // 1928-09-19T21:14:16Z - Instant.ofEpochSecond(-747359729L, 0), // 1946-04-27T00:04:31Z - Instant.ofEpochSecond(4257387427L, 0) // 2104-11-29T07:37:07Z + for v <- Seq( + Instant.ofEpochSecond( + Instant.now().getEpochSecond, + 123456789L + ), // uint32 nanoseq (out of int32 range) + Instant.ofEpochSecond(-1302749144L, 0), // 1928-09-19T21:14:16Z + Instant.ofEpochSecond(-747359729L, 0), // 1946-04-27T00:04:31Z + Instant.ofEpochSecond(4257387427L, 0) // 2104-11-29T07:37:07Z ) - ) { + do check(v, _.packTimestamp(v), _.unpackTimestamp()) - } } test("pack/unpack timestamp in millis") { val posLong = Gen.chooseNum[Long](-31557014167219200L, 31556889864403199L) forAll(posLong) { (millis: Long) => val v = Instant.ofEpochMilli(millis) - check(v, { _.packTimestamp(millis) }, { _.unpackTimestamp() }) + check( + v, { + _.packTimestamp(millis) + }, { + _.unpackTimestamp() + } + ) } } @@ -665,15 +660,15 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { forAll(posLong) { (millis: Long) => val v = Instant.ofEpochMilli(millis) check( - v, - { _.packTimestamp(millis) }, + v, { + _.packTimestamp(millis) + }, { u => val extHeader = u.unpackExtensionTypeHeader() - if (extHeader.isTimestampType) { + if extHeader.isTimestampType then u.unpackTimestamp(extHeader) - } else { + else fail("Cannot reach here") - } } ) } @@ -710,12 +705,11 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { a.withBufferSize(64 * 1024).equals(b) shouldBe false a.withAllowReadingStringAsBinary(false).equals(b) shouldBe false a.withAllowReadingBinaryAsString(false).equals(b) shouldBe false - a.withActionOnMalformedString(CodingErrorAction.REPORT) - .equals(b) shouldBe false - a.withActionOnUnmappableString(CodingErrorAction.REPORT) - .equals(b) shouldBe false + a.withActionOnMalformedString(CodingErrorAction.REPORT).equals(b) shouldBe false + a.withActionOnUnmappableString(CodingErrorAction.REPORT).equals(b) shouldBe false a.withStringSizeLimit(32).equals(b) shouldBe false a.withStringDecoderBufferSize(32).equals(b) shouldBe false } } -} + +end MessagePackTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index 7d762149..c1b4b0a4 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -24,37 +24,33 @@ import wvlet.log.io.IOUtil.withResource import java.io.{ByteArrayOutputStream, File, FileInputStream, FileOutputStream} import scala.util.Random -/** */ -class MessagePackerTest extends AirSpec with Benchmark { +/** + */ +class MessagePackerTest extends AirSpec with Benchmark: - private def verifyIntSeq(answer: Array[Int], packed: Array[Byte]): Unit = { + private def verifyIntSeq(answer: Array[Int], packed: Array[Byte]): Unit = val unpacker = MessagePack.newDefaultUnpacker(packed) val b = Array.newBuilder[Int] - while (unpacker.hasNext) { + while unpacker.hasNext do b += unpacker.unpackInt() - } val result = b.result() result.size shouldBe answer.size result shouldBe answer - } - private def createTempFile = { + private def createTempFile = val f = File.createTempFile("msgpackTest", "msgpack") f.deleteOnExit f - } - private def createTempFileWithOutputStream = { + private def createTempFileWithOutputStream = val f = createTempFile val out = new FileOutputStream(f) (f, out) - } - private def createTempFileWithChannel = { + private def createTempFileWithChannel = val (f, out) = createTempFileWithOutputStream val ch = out.getChannel (f, ch) - } test("MessagePacker") { @@ -69,16 +65,14 @@ class MessagePackerTest extends AirSpec with Benchmark { val intSeq2 = intSeq.reverse val b2 = new ByteArrayOutputStream - packer - .reset(new OutputStreamBufferOutput(b2)) + packer.reset(new OutputStreamBufferOutput(b2)) intSeq2 foreach packer.packInt packer.close verifyIntSeq(intSeq2, b2.toByteArray) val intSeq3 = intSeq2.sorted val b3 = new ByteArrayOutputStream - packer - .reset(new OutputStreamBufferOutput(b3)) + packer.reset(new OutputStreamBufferOutput(b3)) intSeq3 foreach packer.packInt packer.close verifyIntSeq(intSeq3, b3.toByteArray) @@ -86,43 +80,41 @@ class MessagePackerTest extends AirSpec with Benchmark { test("improve the performance via reset method") { val N = 1000 - val t = time("packer", repeat = 10) { - block("no-buffer-reset") { - val out = new ByteArrayOutputStream - withResource(MessagePack.newDefaultPacker(out)) { packer => - for (i <- 0 until N) { - val outputStream = new ByteArrayOutputStream() - packer - .reset(new OutputStreamBufferOutput(outputStream)) - packer.packInt(0) - packer.flush() + val t = + time("packer", repeat = 10) { + block("no-buffer-reset") { + val out = new ByteArrayOutputStream + withResource(MessagePack.newDefaultPacker(out)) { packer => + for i <- 0 until N do + val outputStream = new ByteArrayOutputStream() + packer.reset(new OutputStreamBufferOutput(outputStream)) + packer.packInt(0) + packer.flush() } } - } - block("buffer-reset") { - val out = new ByteArrayOutputStream - withResource(MessagePack.newDefaultPacker(out)) { packer => - val bufferOut = - new OutputStreamBufferOutput(new ByteArrayOutputStream()) - for (i <- 0 until N) { - val outputStream = new ByteArrayOutputStream() - bufferOut.reset(outputStream) - packer.reset(bufferOut) - packer.packInt(0) - packer.flush() + block("buffer-reset") { + val out = new ByteArrayOutputStream + withResource(MessagePack.newDefaultPacker(out)) { packer => + val bufferOut = new OutputStreamBufferOutput(new ByteArrayOutputStream()) + for i <- 0 until N do + val outputStream = new ByteArrayOutputStream() + bufferOut.reset(outputStream) + packer.reset(bufferOut) + packer.packInt(0) + packer.flush() } } } - } - t("buffer-reset").averageWithoutMinMax <= t("no-buffer-reset").averageWithoutMinMax shouldBe true + t("buffer-reset").averageWithoutMinMax <= t("no-buffer-reset").averageWithoutMinMax shouldBe + true } test("pack larger string array than byte buf") { // Based on https://github.com/msgpack/msgpack-java/issues/154 - def test(bufferSize: Int, stringSize: Int): Boolean = { + def test(bufferSize: Int, stringSize: Int): Boolean = val str = "a" * stringSize val rawString = ValueFactory.newString(str.getBytes("UTF-8")) val array = ValueFactory.newArray(rawString) @@ -132,14 +124,8 @@ class MessagePackerTest extends AirSpec with Benchmark { packer.close() out.toByteArray true - } - val testCases = Seq( - 32 -> 30, - 33 -> 31, - 32 -> 31, - 34 -> 32 - ) + val testCases = Seq(32 -> 30, 33 -> 31, 32 -> 31, 34 -> 32) testCases.foreach { case (bufferSize, stringSize) => test(bufferSize, stringSize) } @@ -151,24 +137,20 @@ class MessagePackerTest extends AirSpec with Benchmark { packer.packInt(99) packer.close - val up0 = MessagePack - .newDefaultUnpacker(new FileInputStream(f0)) + val up0 = MessagePack.newDefaultUnpacker(new FileInputStream(f0)) up0.unpackInt shouldBe 99 up0.hasNext shouldBe false up0.close val (f1, out1) = createTempFileWithOutputStream - packer - .reset(new OutputStreamBufferOutput(out1)) + packer.reset(new OutputStreamBufferOutput(out1)) packer.packInt(99) packer.flush - packer - .reset(new OutputStreamBufferOutput(out1)) + packer.reset(new OutputStreamBufferOutput(out1)) packer.packString("hello") packer.close - val up1 = MessagePack - .newDefaultUnpacker(new FileInputStream(f1)) + val up1 = MessagePack.newDefaultUnpacker(new FileInputStream(f1)) up1.unpackInt shouldBe 99 up1.unpackString shouldBe "hello" up1.hasNext shouldBe false @@ -181,24 +163,20 @@ class MessagePackerTest extends AirSpec with Benchmark { packer.packInt(99) packer.close - val up0 = MessagePack - .newDefaultUnpacker(new FileInputStream(f0)) + val up0 = MessagePack.newDefaultUnpacker(new FileInputStream(f0)) up0.unpackInt shouldBe 99 up0.hasNext shouldBe false up0.close val (f1, out1) = createTempFileWithChannel - packer - .reset(new ChannelBufferOutput(out1)) + packer.reset(new ChannelBufferOutput(out1)) packer.packInt(99) packer.flush - packer - .reset(new ChannelBufferOutput(out1)) + packer.reset(new ChannelBufferOutput(out1)) packer.packString("hello") packer.close - val up1 = MessagePack - .newDefaultUnpacker(new FileInputStream(f1)) + val up1 = MessagePack.newDefaultUnpacker(new FileInputStream(f1)) up1.unpackInt shouldBe 99 up1.unpackString shouldBe "hello" up1.hasNext shouldBe false @@ -208,32 +186,32 @@ class MessagePackerTest extends AirSpec with Benchmark { test("pack a lot of String within expected time") { val count = 20000 - def measureDuration(outputStream: java.io.OutputStream) = { + def measureDuration(outputStream: java.io.OutputStream) = val packer = MessagePack.newDefaultPacker(outputStream) var i = 0 - while (i < count) { + while i < count do packer.packString("0123456789ABCDEF") i += 1 - } packer.close - } - val t = time("packString into OutputStream", repeat = 10) { - block("byte-array-output-stream") { - measureDuration(new ByteArrayOutputStream()) - } + val t = + time("packString into OutputStream", repeat = 10) { + block("byte-array-output-stream") { + measureDuration(new ByteArrayOutputStream()) + } - block("file-output-stream") { - val (_, fileOutput) = createTempFileWithOutputStream - measureDuration(fileOutput) + block("file-output-stream") { + val (_, fileOutput) = createTempFileWithOutputStream + measureDuration(fileOutput) + } } - } - t("file-output-stream").averageWithoutMinMax < (t("byte-array-output-stream").averageWithoutMinMax * 5) shouldBe true + t("file-output-stream").averageWithoutMinMax < + (t("byte-array-output-stream").averageWithoutMinMax * 5) shouldBe true } } test("compute totalWrittenBytes") { - val out = new ByteArrayOutputStream + val out = new ByteArrayOutputStream val packerTotalWrittenBytes = withResource(MessagePack.newDefaultPacker(out)) { packer => packer @@ -254,11 +232,7 @@ class MessagePackerTest extends AirSpec with Benchmark { test("support read-only buffer") { val payload = Array[Byte](1) val out = new ByteArrayOutputStream() - val packer = MessagePack - .newDefaultPacker(out) - .packBinaryHeader(1) - .writePayload(payload) - .close() + val packer = MessagePack.newDefaultPacker(out).packBinaryHeader(1).writePayload(payload).close() } test("pack small string with STR8") { @@ -272,8 +246,7 @@ class MessagePackerTest extends AirSpec with Benchmark { } test("be able to disable STR8 for backward compatibility") { - val config = new PackerConfig() - .withStr8FormatSupport(false) + val config = new PackerConfig().withStr8FormatSupport(false) val packer = config.newBufferPacker() packer.packString("Hello. This is a string longer than 32 characters!") @@ -298,16 +271,14 @@ class MessagePackerTest extends AirSpec with Benchmark { test("write raw binary") { val packer = new MessagePack.PackerConfig().newBufferPacker() - val msg = - Array[Byte](-127, -92, 116, 121, 112, 101, -92, 112, 105, 110, 103) + val msg = Array[Byte](-127, -92, 116, 121, 112, 101, -92, 112, 105, 110, 103) packer.writePayload(msg) } test("append raw binary") { val packer = new MessagePack.PackerConfig().newBufferPacker() - val msg = - Array[Byte](-127, -92, 116, 121, 112, 101, -92, 112, 105, 110, 103) + val msg = Array[Byte](-127, -92, 116, 121, 112, 101, -92, 112, 105, 110, 103) packer.addPayload(msg) } -} +end MessagePackerTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index 620e7dbe..ae25d284 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -16,41 +16,37 @@ package org.msgpack.core import org.msgpack.core.MessagePackSpec.{createMessagePackData, toHex} -import org.msgpack.core.buffer._ +import org.msgpack.core.buffer.* import org.msgpack.value.ValueType import wvlet.airspec.AirSpec import wvlet.log.LogSupport import wvlet.log.io.IOUtil.withResource -import java.io._ +import java.io.* import java.nio.ByteBuffer import java.util.Collections -import scala.jdk.CollectionConverters._ +import scala.jdk.CollectionConverters.* import scala.util.Random -object MessageUnpackerTest { - class SplitMessageBufferInput(array: Array[Array[Byte]]) extends MessageBufferInput { - var cursor = 0 - override def next(): MessageBuffer = { - if (cursor < array.length) { +object MessageUnpackerTest: + class SplitMessageBufferInput(array: Array[Array[Byte]]) extends MessageBufferInput: + var cursor = 0 + override def next(): MessageBuffer = + if cursor < array.length then val a = array(cursor) cursor += 1 MessageBuffer.wrap(a) - } else { + else null - } - } override def close(): Unit = {} - } -} -import org.msgpack.core.MessageUnpackerTest._ +import org.msgpack.core.MessageUnpackerTest.* -class MessageUnpackerTest extends AirSpec with Benchmark { +class MessageUnpackerTest extends AirSpec with Benchmark: - private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] - private def testData: Array[Byte] = { + private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] + private def testData: Array[Byte] = val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) @@ -68,17 +64,18 @@ class MessageUnpackerTest extends AirSpec with Benchmark { debug(s"packed: ${toHex(arr)}, size:${arr.length}") arr - } - private val intSeq = (for (i <- 0 until 100) yield Random.nextInt()).toArray[Int] + private val intSeq = + ( + for (i <- 0 until 100) + yield Random.nextInt() + ).toArray[Int] - private def testData2: Array[Byte] = { + private def testData2: Array[Byte] = val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out); - packer - .packBoolean(true) - .packBoolean(false) + packer.packBoolean(true).packBoolean(false) intSeq.foreach(packer.packInt) packer.close() @@ -86,15 +83,15 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val arr = out.toByteArray debug(s"packed: ${toHex(arr)}") arr - } - private def write(packer: MessagePacker, r: Random): Unit = { - val tpeIndex = Iterator - .continually(r.nextInt(MessageFormat.values().length)) - .find(_ != MessageFormat.NEVER_USED.ordinal()) - .get + private def write(packer: MessagePacker, r: Random): Unit = + val tpeIndex = + Iterator + .continually(r.nextInt(MessageFormat.values().length)) + .find(_ != MessageFormat.NEVER_USED.ordinal()) + .get val tpe = MessageFormat.values()(tpeIndex) - tpe.getValueType match { + tpe.getValueType match case ValueType.INTEGER => val v = r.nextInt(Int.MaxValue) @@ -124,27 +121,27 @@ class MessageUnpackerTest extends AirSpec with Benchmark { trace(s"array len: $len") packer.packArrayHeader(len) var i = 0 - while (i < len) { + while i < len do write(packer, r) i += 1 - } case ValueType.MAP => val len = r.nextInt(5) + 1 packer.packMapHeader(len) trace(s"map len: ${len}") var i = 0 - while (i < len * 2) { + while i < len * 2 do write(packer, r) i += 1 - } case _ => val v = r.nextInt(Int.MaxValue) trace(s"int: $v") packer.packInt(v) - } - } - private def testData3(N: Int): Array[Byte] = { + end match + + end write + + private def testData3(N: Int): Array[Byte] = val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) @@ -160,11 +157,10 @@ class MessageUnpackerTest extends AirSpec with Benchmark { trace(s"packed: ${toHex(arr)}") debug(s"size:${arr.length}") arr - } - private def readValue(unpacker: MessageUnpacker): Unit = { + private def readValue(unpacker: MessageUnpacker): Unit = val f = unpacker.getNextFormat() - f.getValueType match { + f.getValueType match case ValueType.ARRAY => val arrLen = unpacker.unpackArrayHeader() debug(s"arr size: $arrLen") @@ -180,24 +176,20 @@ class MessageUnpackerTest extends AirSpec with Benchmark { case other => unpacker.skipValue() debug(s"unknown type: $f") - } - } - private def createTempFile: File = { + private def createTempFile: File = val f = File.createTempFile("msgpackTest", "msgpack") f.deleteOnExit val p = MessagePack.newDefaultPacker(new FileOutputStream(f)) p.packInt(99) p.close f - } - private def checkFile(u: MessageUnpacker): Boolean = { + private def checkFile(u: MessageUnpacker): Boolean = u.unpackInt shouldBe 99 u.hasNext shouldBe false - } - private def unpackers(data: Array[Byte]): Seq[MessageUnpacker] = { + private def unpackers(data: Array[Byte]): Seq[MessageUnpacker] = val bb = ByteBuffer.allocate(data.length) val db = ByteBuffer.allocateDirect(data.length) bb.put(data).flip() @@ -205,20 +197,21 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val builder = Seq.newBuilder[MessageUnpacker] builder += MessagePack.newDefaultUnpacker(data) builder += MessagePack.newDefaultUnpacker(bb) - if (!universal) { + if !universal then builder += MessagePack.newDefaultUnpacker(db) - } builder.result() - } - private def unpackerCollectionWithVariousBuffers(data: Array[Byte], chunkSize: Int): Seq[MessageUnpacker] = { + private def unpackerCollectionWithVariousBuffers( + data: Array[Byte], + chunkSize: Int + ): Seq[MessageUnpacker] = val seqBytes = Seq.newBuilder[MessageBufferInput] val seqByteBuffers = Seq.newBuilder[MessageBufferInput] val seqDirectBuffers = Seq.newBuilder[MessageBufferInput] var left = data.length var position = 0 - while (left > 0) { + while left > 0 do val length = Math.min(chunkSize, left) seqBytes += new ArrayBufferInput(data, position, length) val bb = ByteBuffer.allocate(length) @@ -229,52 +222,56 @@ class MessageUnpackerTest extends AirSpec with Benchmark { seqDirectBuffers += new ByteBufferInput(db) left -= length position += length - } val builder = Seq.newBuilder[MessageUnpacker] - builder += MessagePack.newDefaultUnpacker(new SequenceMessageBufferInput(Collections.enumeration(seqBytes.result().asJava))) - builder += MessagePack.newDefaultUnpacker(new SequenceMessageBufferInput(Collections.enumeration(seqByteBuffers.result().asJava))) - if (!universal) { - builder += MessagePack.newDefaultUnpacker(new SequenceMessageBufferInput(Collections.enumeration(seqDirectBuffers.result().asJava))) - } + builder += + MessagePack.newDefaultUnpacker( + new SequenceMessageBufferInput(Collections.enumeration(seqBytes.result().asJava)) + ) + builder += + MessagePack.newDefaultUnpacker( + new SequenceMessageBufferInput(Collections.enumeration(seqByteBuffers.result().asJava)) + ) + if !universal then + builder += + MessagePack.newDefaultUnpacker( + new SequenceMessageBufferInput(Collections.enumeration(seqDirectBuffers.result().asJava)) + ) builder.result() - } + + end unpackerCollectionWithVariousBuffers test("MessageUnpacker") { test("parse message packed data") { val arr = testData - for (unpacker <- unpackers(arr)) { + for unpacker <- unpackers(arr) do var count = 0 - while (unpacker.hasNext) { + while unpacker.hasNext do count += 1 readValue(unpacker) - } count shouldBe 6 unpacker.getTotalReadBytes shouldBe arr.length unpacker.close() unpacker.getTotalReadBytes shouldBe arr.length - } } test("skip reading values") { - for (unpacker <- unpackers(testData)) { + for unpacker <- unpackers(testData) do var skipCount = 0 - while (unpacker.hasNext) { + while unpacker.hasNext do unpacker.skipValue() skipCount += 1 - } skipCount shouldBe 2 unpacker.getTotalReadBytes shouldBe testData.length unpacker.close() unpacker.getTotalReadBytes shouldBe testData.length - } } test("compare skip performance") { @@ -283,23 +280,20 @@ class MessageUnpackerTest extends AirSpec with Benchmark { time("skip performance", repeat = 100) { block("switch") { - for (unpacker <- unpackers(data)) { + for unpacker <- unpackers(data) do var skipCount = 0 - while (unpacker.hasNext) { + while unpacker.hasNext do unpacker.skipValue() skipCount += 1 - } skipCount shouldBe N - } } } time("bulk skip performance", repeat = 100) { block("switch") { - for (unpacker <- unpackers(data)) { + for unpacker <- unpackers(data) do unpacker.skipValue(N) unpacker.hasNext shouldBe false - } } } @@ -308,12 +302,12 @@ class MessageUnpackerTest extends AirSpec with Benchmark { test("parse int data") { debug(intSeq.mkString(", ")) - for (unpacker <- unpackers(testData2)) { + for unpacker <- unpackers(testData2) do val ib = Seq.newBuilder[Int] - while (unpacker.hasNext) { + while unpacker.hasNext do val f = unpacker.getNextFormat - f.getValueType match { + f.getValueType match case ValueType.INTEGER => val i = unpacker.unpackInt() trace(f"read int: $i%,d") @@ -323,54 +317,48 @@ class MessageUnpackerTest extends AirSpec with Benchmark { trace(s"read boolean: $b") case other => unpacker.skipValue() - } - } ib.result() shouldBe intSeq.toSeq unpacker.getTotalReadBytes shouldBe testData2.length unpacker.close() unpacker.getTotalReadBytes shouldBe testData2.length - } } test("read data at the buffer boundary") { - trait SplitTest extends LogSupport { + trait SplitTest extends LogSupport: val data: Array[Byte] - def run: Unit = { - for (unpacker <- unpackers(data)) { - val numElems = { + def run: Unit = + for unpacker <- unpackers(data) do + val numElems = var c = 0 - while (unpacker.hasNext) { + while unpacker.hasNext do readValue(unpacker) c += 1 - } c - } - for (splitPoint <- 1 until data.length - 1) { + for splitPoint <- 1 until data.length - 1 do debug(s"split at $splitPoint") val (h, t) = data.splitAt(splitPoint) val bin = new SplitMessageBufferInput(Array(h, t)) val unpacker = MessagePack.newDefaultUnpacker(bin) var count = 0 - while (unpacker.hasNext) { + while unpacker.hasNext do count += 1 val f = unpacker.getNextFormat readValue(unpacker) - } count shouldBe numElems unpacker.getTotalReadBytes shouldBe data.length unpacker.close() unpacker.getTotalReadBytes shouldBe data.length - } - } - } - } - new SplitTest { val data = testData }.run - new SplitTest { val data = testData3(30) }.run + new SplitTest: + val data = testData + .run + new SplitTest: + val data = testData3(30) + .run } test("read integer at MessageBuffer boundaries") { @@ -382,18 +370,21 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val data = packer.toByteArray // Boundary test - withResource(MessagePack.newDefaultUnpacker(new InputStreamBufferInput(new ByteArrayInputStream(data), 8192))) { unpacker => + withResource( + MessagePack.newDefaultUnpacker( + new InputStreamBufferInput(new ByteArrayInputStream(data), 8192) + ) + ) { unpacker => (0 until 1170).foreach { i => unpacker.unpackLong() shouldBe 0x0011223344556677L } } // Boundary test for sequences of ByteBuffer, DirectByteBuffer backed MessageInput. - for (unpacker <- unpackerCollectionWithVariousBuffers(data, 32)) { + for unpacker <- unpackerCollectionWithVariousBuffers(data, 32) do (0 until 1170).foreach { i => unpacker.unpackLong() shouldBe 0x0011223344556677L } - } } test("read string at MessageBuffer boundaries") { @@ -405,36 +396,34 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val data = packer.toByteArray // Boundary test - withResource(MessagePack.newDefaultUnpacker(new InputStreamBufferInput(new ByteArrayInputStream(data), 8192))) { unpacker => + withResource( + MessagePack.newDefaultUnpacker( + new InputStreamBufferInput(new ByteArrayInputStream(data), 8192) + ) + ) { unpacker => (0 until 1170).foreach { i => unpacker.unpackString() shouldBe "hello world" } } // Boundary test for sequences of ByteBuffer, DirectByteBuffer backed MessageInput. - for (unpacker <- unpackerCollectionWithVariousBuffers(data, 32)) { + for unpacker <- unpackerCollectionWithVariousBuffers(data, 32) do (0 until 1170).foreach { i => unpacker.unpackString() shouldBe "hello world" } - } } test("be faster than msgpack-v6 skip") { - trait Fixture { + trait Fixture: val unpacker: MessageUnpacker - def run: Unit = { + def run: Unit = var count = 0 - try { - while (unpacker.hasNext) { + try + while unpacker.hasNext do unpacker.skipValue() count += 1 - } - } finally { - unpacker.close() - } - } - } + finally unpacker.close() val data = testData3(10000) val N = 100 @@ -443,64 +432,69 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val db = ByteBuffer.allocateDirect(data.length) db.put(data).flip() - val t = time("skip performance", repeat = N) { - block("v6") { - val v6 = new org.msgpack.MessagePack() - val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) - var count = 0 - try { - while (true) { - unpacker.skip() - count += 1 - } - } catch { - case e: EOFException => - } finally unpacker.close() - } + val t = + time("skip performance", repeat = N) { + block("v6") { + val v6 = new org.msgpack.MessagePack() + val unpacker = + new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) + var count = 0 + try + while true do + unpacker.skip() + count += 1 + catch + case e: EOFException => + finally + unpacker.close() + } - block("v7-array") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(data) - }.run - } + block("v7-array") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(data) + .run + } - block("v7-array-buffer") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(bb) - }.run - } - if (!universal) block("v7-direct-buffer") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(db) - }.run + block("v7-array-buffer") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(bb) + .run + } + if !universal then + block("v7-direct-buffer") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(db) + .run + } } - } t("v7-array").averageWithoutMinMax <= t("v6").averageWithoutMinMax shouldBe true t("v7-array-buffer").averageWithoutMinMax <= t("v6").averageWithoutMinMax shouldBe true - if (!universal) { + if !universal then t("v7-direct-buffer").averageWithoutMinMax <= t("v6").averageWithoutMinMax shouldBe true - } } - import org.msgpack.`type`.{ValueType => ValueTypeV6} + import org.msgpack.`type`.ValueType as ValueTypeV6 test("be faster than msgpack-v6 read value") { - def readValueV6(unpacker: org.msgpack.unpacker.MessagePackUnpacker): Unit = { + def readValueV6(unpacker: org.msgpack.unpacker.MessagePackUnpacker): Unit = val vt = unpacker.getNextType() - vt match { + vt match case ValueTypeV6.ARRAY => val len = unpacker.readArrayBegin() var i = 0 - while (i < len) { readValueV6(unpacker); i += 1 } + while i < len do + readValueV6(unpacker); + i += 1 unpacker.readArrayEnd() case ValueTypeV6.MAP => val len = unpacker.readMapBegin() var i = 0 - while (i < len) { - readValueV6(unpacker); readValueV6(unpacker); i += 1 - } + while i < len do + readValueV6(unpacker); + readValueV6(unpacker); + i += 1 unpacker.readMapEnd() case ValueTypeV6.NIL => unpacker.readNil() @@ -514,23 +508,27 @@ class MessageUnpackerTest extends AirSpec with Benchmark { unpacker.readByteArray() case _ => unpacker.skip() - } - } + end readValueV6 val buf = new Array[Byte](8192) - def readValue(unpacker: MessageUnpacker): Unit = { + def readValue(unpacker: MessageUnpacker): Unit = val f = unpacker.getNextFormat val vt = f.getValueType - vt match { + vt match case ValueType.ARRAY => val len = unpacker.unpackArrayHeader() var i = 0 - while (i < len) { readValue(unpacker); i += 1 } + while i < len do + readValue(unpacker); + i += 1 case ValueType.MAP => val len = unpacker.unpackMapHeader() var i = 0 - while (i < len) { readValue(unpacker); readValue(unpacker); i += 1 } + while i < len do + readValue(unpacker); + readValue(unpacker); + i += 1 case ValueType.NIL => unpacker.unpackNil() case ValueType.INTEGER => @@ -547,20 +545,17 @@ class MessageUnpackerTest extends AirSpec with Benchmark { unpacker.readPayload(buf, 0, len) case _ => unpacker.skipValue() - } - } - trait Fixture { + end match + end readValue + trait Fixture: val unpacker: MessageUnpacker - def run: Unit = { + def run: Unit = var count = 0 - try { - while (unpacker.hasNext) { + try + while unpacker.hasNext do readValue(unpacker) count += 1 - } - } finally unpacker.close() - } - } + finally unpacker.close() val data = testData3(10000) val N = 100 @@ -569,49 +564,55 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val db = ByteBuffer.allocateDirect(data.length) db.put(data).flip() - val t = time("unpack performance", repeat = N) { - block("v6") { - val v6 = new org.msgpack.MessagePack() - val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) - var count = 0 - try { - while (true) { - readValueV6(unpacker) - count += 1 - } - } catch { - case e: EOFException => - } finally unpacker.close() - } + val t = + time("unpack performance", repeat = N) { + block("v6") { + val v6 = new org.msgpack.MessagePack() + val unpacker = + new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) + var count = 0 + try + while true do + readValueV6(unpacker) + count += 1 + catch + case e: EOFException => + finally + unpacker.close() + } - block("v7-array") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(data) - }.run - } + block("v7-array") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(data) + .run + } - block("v7-array-buffer") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(bb) - }.run - } + block("v7-array-buffer") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(bb) + .run + } - if (!universal) block("v7-direct-buffer") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(db) - }.run + if !universal then + block("v7-direct-buffer") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(db) + .run + } } - } - if (t("v7-array").averageWithoutMinMax > t("v6").averageWithoutMinMax) { - warn(s"v7-array ${t("v7-array").averageWithoutMinMax} is slower than v6 ${t("v6").averageWithoutMinMax}") - } - if (t("v7-array-buffer").averageWithoutMinMax > t("v6").averageWithoutMinMax) { - warn(s"v7-array-buffer ${t("v7-array-buffer").averageWithoutMinMax} is slower than v6 ${t("v6").averageWithoutMinMax}") - } - if (!universal) { + if t("v7-array").averageWithoutMinMax > t("v6").averageWithoutMinMax then + warn( + s"v7-array ${t("v7-array").averageWithoutMinMax} is slower than v6 ${t("v6") + .averageWithoutMinMax}" + ) + if t("v7-array-buffer").averageWithoutMinMax > t("v6").averageWithoutMinMax then + warn( + s"v7-array-buffer ${t("v7-array-buffer").averageWithoutMinMax} is slower than v6 ${t("v6") + .averageWithoutMinMax}" + ) + if !universal then t("v7-direct-buffer").averageWithoutMinMax <= t("v6").averageWithoutMinMax shouldBe true - } } test("be faster for reading binary than v6") { @@ -626,31 +627,26 @@ class MessageUnpackerTest extends AirSpec with Benchmark { } packer.close() - trait Fixture { + trait Fixture: val unpacker: MessageUnpacker val loop: Int - def run: Unit = { + def run: Unit = var i = 0 - try { - while (i < loop) { + try + while i < loop do val len = unpacker.unpackBinaryHeader() val out = new Array[Byte](len) unpacker.readPayload(out, 0, len) i += 1 - } - } finally unpacker.close() - } - def runRef: Unit = { + finally unpacker.close() + def runRef: Unit = var i = 0 - try { - while (i < loop) { + try + while i < loop do val len = unpacker.unpackBinaryHeader() val out = unpacker.readPayloadAsReference(len) i += 1 - } - } finally unpacker.close() - } - } + finally unpacker.close() val b = bos.toByteArray val bb = ByteBuffer.allocate(b.length) bb.put(b).flip() @@ -659,66 +655,67 @@ class MessageUnpackerTest extends AirSpec with Benchmark { time("unpackBinary", repeat = 100) { block("v6") { - val v6 = new org.msgpack.MessagePack() - val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(b)) - var i = 0 - while (i < R) { + val v6 = new org.msgpack.MessagePack() + val unpacker = + new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(b)) + var i = 0 + while i < R do val out = unpacker.readByteArray() i += 1 - } unpacker.close() } block("v7-array") { - new Fixture { + new Fixture: override val unpacker = MessagePack.newDefaultUnpacker(b) override val loop = R - }.run + .run } block("v7-array-buffer") { - new Fixture { + new Fixture: override val unpacker = MessagePack.newDefaultUnpacker(bb) override val loop = R - }.run + .run } - if (!universal) block("v7-direct-buffer") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(db) - override val loop = R - }.run - } + if !universal then + block("v7-direct-buffer") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(db) + override val loop = R + .run + } block("v7-ref-array") { - new Fixture { + new Fixture: override val unpacker = MessagePack.newDefaultUnpacker(b) override val loop = R - }.runRef + .runRef } block("v7-ref-array-buffer") { - new Fixture { + new Fixture: override val unpacker = MessagePack.newDefaultUnpacker(bb) override val loop = R - }.runRef + .runRef } - if (!universal) block("v7-ref-direct-buffer") { - new Fixture { - override val unpacker = MessagePack.newDefaultUnpacker(db) - override val loop = R - }.runRef - } + if !universal then + block("v7-ref-direct-buffer") { + new Fixture: + override val unpacker = MessagePack.newDefaultUnpacker(db) + override val loop = R + .runRef + } } } test("read payload as a reference") { - val dataSizes = - Seq(0, 1, 5, 8, 16, 32, 128, 256, 1024, 2000, 10000, 100000) + val dataSizes = Seq(0, 1, 5, 8, 16, 32, 128, 256, 1024, 2000, 10000, 100000) - for (s <- dataSizes) { + for s <- dataSizes do test(f"data size is $s%,d") { val data = new Array[Byte](s) Random.nextBytes(data) @@ -728,7 +725,7 @@ class MessageUnpackerTest extends AirSpec with Benchmark { packer.writePayload(data) packer.close() - for (unpacker <- unpackers(b.toByteArray)) { + for unpacker <- unpackers(b.toByteArray) do val len = unpacker.unpackBinaryHeader() len shouldBe s val ref = unpacker.readPayloadAsReference(len) @@ -738,21 +735,18 @@ class MessageUnpackerTest extends AirSpec with Benchmark { ref.getBytes(0, stored, 0, len) stored shouldBe data - } } - } } test("reset the internal states") { val data = intSeq val b = createMessagePackData(packer => data foreach packer.packInt) - for (unpacker <- unpackers(b)) { + for unpacker <- unpackers(b) do val unpacked = Array.newBuilder[Int] - while (unpacker.hasNext) { + while unpacker.hasNext do unpacked += unpacker.unpackInt() - } unpacker.close unpacked.result() shouldBe data @@ -761,9 +755,8 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val bi = new ArrayBufferInput(b2) unpacker.reset(bi) val unpacked2 = Array.newBuilder[Int] - while (unpacker.hasNext) { + while unpacker.hasNext do unpacked2 += unpacker.unpackInt() - } unpacker.close unpacked2.result() shouldBe data2 @@ -771,12 +764,10 @@ class MessageUnpackerTest extends AirSpec with Benchmark { bi.reset(b2) unpacker.reset(bi) val unpacked3 = Array.newBuilder[Int] - while (unpacker.hasNext) { + while unpacker.hasNext do unpacked3 += unpacker.unpackInt() - } unpacker.close unpacked3.result() shouldBe data2 - } } @@ -790,42 +781,40 @@ class MessageUnpackerTest extends AirSpec with Benchmark { val mb = MessageBuffer.wrap(arr) val N = 1000 - val t = time("unpacker", repeat = 10) { - block("no-buffer-reset") { - withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => - for (i <- 0 until N) { - val buf = new ArrayBufferInput(arr) - unpacker.reset(buf) - unpacker.unpackInt - unpacker.close + val t = + time("unpacker", repeat = 10) { + block("no-buffer-reset") { + withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => + for i <- 0 until N do + val buf = new ArrayBufferInput(arr) + unpacker.reset(buf) + unpacker.unpackInt + unpacker.close } } - } - block("reuse-array-input") { - withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => - val buf = new ArrayBufferInput(arr) - for (i <- 0 until N) { - buf.reset(arr) - unpacker.reset(buf) - unpacker.unpackInt - unpacker.close + block("reuse-array-input") { + withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => + val buf = new ArrayBufferInput(arr) + for i <- 0 until N do + buf.reset(arr) + unpacker.reset(buf) + unpacker.unpackInt + unpacker.close } } - } - block("reuse-message-buffer") { - withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => - val buf = new ArrayBufferInput(arr) - for (i <- 0 until N) { - buf.reset(mb) - unpacker.reset(buf) - unpacker.unpackInt - unpacker.close + block("reuse-message-buffer") { + withResource(MessagePack.newDefaultUnpacker(arr)) { unpacker => + val buf = new ArrayBufferInput(arr) + for i <- 0 until N do + buf.reset(mb) + unpacker.reset(buf) + unpacker.unpackInt + unpacker.close } } } - } // This performance comparison is too close, so we disabled it // t("reuse-message-buffer").averageWithoutMinMax should be <= t("no-buffer-reset").averageWithoutMinMax @@ -857,24 +846,20 @@ class MessageUnpackerTest extends AirSpec with Benchmark { } test("unpack large string data") { - def createLargeData(stringLength: Int): Array[Byte] = { + def createLargeData(stringLength: Int): Array[Byte] = val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) - packer - .packArrayHeader(2) - .packString("l" * stringLength) - .packInt(1) + packer.packArrayHeader(2).packString("l" * stringLength).packInt(1) packer.close() out.toByteArray - } Seq(8191, 8192, 8193, 16383, 16384, 16385).foreach { n => val arr = createLargeData(n) - for (unpacker <- unpackers(arr)) { + for unpacker <- unpackers(arr) do unpacker.unpackArrayHeader shouldBe 2 unpacker.unpackString.length shouldBe n @@ -884,12 +869,11 @@ class MessageUnpackerTest extends AirSpec with Benchmark { unpacker.close() unpacker.getTotalReadBytes shouldBe arr.length - } } } test("unpack string crossing end of buffer") { - def check(expected: String, strLen: Int) = { + def check(expected: String, strLen: Int) = val bytes = new Array[Byte](strLen) val out = new ByteArrayOutputStream @@ -899,52 +883,58 @@ class MessageUnpackerTest extends AirSpec with Benchmark { packer.packString(expected) packer.close - val unpacker = MessagePack.newDefaultUnpacker(new InputStreamBufferInput(new ByteArrayInputStream(out.toByteArray))) - val len = unpacker.unpackBinaryHeader + val unpacker = MessagePack.newDefaultUnpacker( + new InputStreamBufferInput(new ByteArrayInputStream(out.toByteArray)) + ) + val len = unpacker.unpackBinaryHeader unpacker.readPayload(len) val got = unpacker.unpackString unpacker.close got shouldBe expected - } - Seq("\u3042", "a\u3042", "\u3042a", "\u3042\u3044\u3046\u3048\u304A\u304B\u304D\u304F\u3051\u3053\u3055\u3057\u3059\u305B\u305D") - .foreach { s => - Seq(8185, 8186, 8187, 8188, 16377, 16378, 16379, 16380).foreach { n => - check(s, n) - } + Seq( + "\u3042", + "a\u3042", + "\u3042a", + "\u3042\u3044\u3046\u3048\u304A\u304B\u304D\u304F\u3051\u3053\u3055\u3057\u3059\u305B\u305D" + ).foreach { s => + Seq(8185, 8186, 8187, 8188, 16377, 16378, 16379, 16380).foreach { n => + check(s, n) } + } } - def readTest(input: MessageBufferInput): Unit = { + def readTest(input: MessageBufferInput): Unit = withResource(MessagePack.newDefaultUnpacker(input)) { unpacker => - while (unpacker.hasNext) { + while unpacker.hasNext do unpacker.unpackValue() - } } - } test("read value length at buffer boundary") { - val input = new SplitMessageBufferInput( - Array( - Array[Byte](MessagePack.Code.STR16), - Array[Byte](0x00), - Array[Byte](0x05), // STR16 length at the boundary - "hello".getBytes(MessagePack.UTF8) + val input = + new SplitMessageBufferInput( + Array( + Array[Byte](MessagePack.Code.STR16), + Array[Byte](0x00), + Array[Byte](0x05), // STR16 length at the boundary + "hello".getBytes(MessagePack.UTF8) + ) ) - ) readTest(input) - val input2 = new SplitMessageBufferInput( - Array( - Array[Byte](MessagePack.Code.STR32), - Array[Byte](0x00), - Array[Byte](0x00, 0x00), - Array[Byte](0x05), // STR32 length at the boundary - "hello".getBytes(MessagePack.UTF8) + val input2 = + new SplitMessageBufferInput( + Array( + Array[Byte](MessagePack.Code.STR32), + Array[Byte](0x00), + Array[Byte](0x00, 0x00), + Array[Byte](0x05), // STR32 length at the boundary + "hello".getBytes(MessagePack.UTF8) + ) ) - ) readTest(input2) } } -} + +end MessageUnpackerTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala index 96319a7f..c54ce632 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/StringLimitTest.scala @@ -4,7 +4,7 @@ import org.msgpack.core.MessagePack.UnpackerConfig import org.msgpack.value.Variable import wvlet.airspec.AirSpec -class StringLimitTest extends AirSpec { +class StringLimitTest extends AirSpec: test("throws an exception when the string size exceeds a limit") { val customLimit = 100 @@ -34,4 +34,5 @@ class StringLimitTest extends AirSpec { } } } -} + +end StringLimitTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala index 42872fc4..06d363fd 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/ByteStringTest.scala @@ -20,28 +20,26 @@ import org.msgpack.core.MessagePack import org.msgpack.core.MessagePackSpec.createMessagePackData import wvlet.airspec.AirSpec -class ByteStringTest extends AirSpec { +class ByteStringTest extends AirSpec: private val unpackedString = "foo" private val byteString = ByteString(createMessagePackData(_.packString(unpackedString))) - private def unpackString(messageBuffer: MessageBuffer) = { - val input = new MessageBufferInput { + private def unpackString(messageBuffer: MessageBuffer) = + val input = + new MessageBufferInput: - private var isRead = false + private var isRead = false - override def next(): MessageBuffer = - if (isRead) { - null - } else { - isRead = true - messageBuffer - } - override def close(): Unit = {} - } + override def next(): MessageBuffer = + if isRead then + null + else + isRead = true + messageBuffer + override def close(): Unit = {} MessagePack.newDefaultUnpacker(input).unpackString() - } test("Unpacking a ByteString's ByteBuffer") { test("fail with a regular MessageBuffer") { @@ -53,4 +51,5 @@ class ByteStringTest extends AirSpec { } } } -} + +end ByteStringTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala index 40f4c770..5bb4b49d 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/DirectBufferAccessTest.scala @@ -19,11 +19,10 @@ import wvlet.airspec.AirSpec import java.nio.ByteBuffer -class DirectBufferAccessTest extends AirSpec { +class DirectBufferAccessTest extends AirSpec: test("instantiate DirectBufferAccess") { val bb = ByteBuffer.allocateDirect(1) val addr = DirectBufferAccess.getAddress(bb) } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala index a43704fb..5e6c1f96 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferInputTest.scala @@ -19,7 +19,7 @@ import org.msgpack.core.MessagePack import wvlet.airspec.AirSpec import wvlet.log.io.IOUtil.withResource -import java.io._ +import java.io.* import java.net.InetSocketAddress import java.nio.ByteBuffer import java.nio.channels.{ServerSocketChannel, SocketChannel} @@ -27,63 +27,49 @@ import java.util.concurrent.{Callable, Executors, TimeUnit} import java.util.zip.{GZIPInputStream, GZIPOutputStream} import scala.util.Random -class MessageBufferInputTest extends AirSpec { +class MessageBufferInputTest extends AirSpec: - private val targetInputSize = - Seq(0, 10, 500, 1000, 2000, 4000, 8000, 10000, 30000, 50000, 100000) + private val targetInputSize = Seq(0, 10, 500, 1000, 2000, 4000, 8000, 10000, 30000, 50000, 100000) - private def testData(size: Int): Array[Byte] = { + private def testData(size: Int): Array[Byte] = // debug(s"test data size: ${size}") val b = new Array[Byte](size) Random.nextBytes(b) b - } - private def testDataSet: Seq[Array[Byte]] = { - targetInputSize.map(testData) - } + private def testDataSet: Seq[Array[Byte]] = targetInputSize.map(testData) - private def runTest(factory: Array[Byte] => MessageBufferInput): Unit = { - for (b <- testDataSet) { + private def runTest(factory: Array[Byte] => MessageBufferInput): Unit = + for b <- testDataSet do checkInputData(b, factory(b)) - } - } - implicit class InputData(b: Array[Byte]) { - def compress = { + implicit class InputData(b: Array[Byte]): + def compress = val compressed = new ByteArrayOutputStream() val out = new GZIPOutputStream(compressed) out.write(b) out.close() compressed.toByteArray - } - def toByteBuffer = { - ByteBuffer.wrap(b) - } + def toByteBuffer = ByteBuffer.wrap(b) - def saveToTmpFile: File = { - val tmp = File - .createTempFile("testbuf", ".dat", new File("target")) + def saveToTmpFile: File = + val tmp = File.createTempFile("testbuf", ".dat", new File("target")) tmp.getParentFile.mkdirs() tmp.deleteOnExit() withResource(new FileOutputStream(tmp)) { out => out.write(b) } tmp - } - } - private def checkInputData(inputData: Array[Byte], in: MessageBufferInput): Unit = { + private def checkInputData(inputData: Array[Byte], in: MessageBufferInput): Unit = test(s"When input data size = ${inputData.length}") { var cursor = 0 - for (m <- Iterator.continually(in.next).takeWhile(_ != null)) { + for m <- Iterator.continually(in.next).takeWhile(_ != null) do m.toByteArray() shouldBe inputData.slice(cursor, cursor + m.size()) cursor += m.size() - } cursor shouldBe inputData.length } - } test("MessageBufferInput") { test("support byte arrays") { @@ -95,46 +81,40 @@ class MessageBufferInputTest extends AirSpec { } test("support InputStreams") { - runTest(b => new InputStreamBufferInput(new GZIPInputStream(new ByteArrayInputStream(b.compress)))) + runTest(b => + new InputStreamBufferInput(new GZIPInputStream(new ByteArrayInputStream(b.compress))) + ) } test("support file input channel") { runTest { b => val tmp = b.saveToTmpFile - try { - InputStreamBufferInput - .newBufferInput(new FileInputStream(tmp)) - } finally { - tmp.delete() - } + try InputStreamBufferInput.newBufferInput(new FileInputStream(tmp)) + finally tmp.delete() } } } - private def createTempFile = { + private def createTempFile = val f = File.createTempFile("msgpackTest", "msgpack") f.deleteOnExit f - } - private def createTempFileWithInputStream = { + private def createTempFileWithInputStream = val f = createTempFile val out = new FileOutputStream(f) MessagePack.newDefaultPacker(out).packInt(42).close val in = new FileInputStream(f) (f, in) - } - private def createTempFileWithChannel = { + private def createTempFileWithChannel = val (f, in) = createTempFileWithInputStream val ch = in.getChannel (f, ch) - } - private def readInt(buf: MessageBufferInput): Int = { + private def readInt(buf: MessageBufferInput): Int = val unpacker = MessagePack.newDefaultUnpacker(buf) unpacker.unpackInt - } test("InputStreamBufferInput") { test("reset buffer") { @@ -186,42 +166,42 @@ class MessageBufferInputTest extends AirSpec { } test("unpack without blocking") { - val server = - ServerSocketChannel.open.bind(new InetSocketAddress("localhost", 0)) + val server = ServerSocketChannel.open.bind(new InetSocketAddress("localhost", 0)) val executorService = Executors.newCachedThreadPool - try { - executorService.execute(new Runnable { - override def run: Unit = { - val server_ch = server.accept - val packer = MessagePack.newDefaultPacker(server_ch) - packer.packString("0123456789") - packer.flush - // Keep the connection open - while (!executorService.isShutdown) { - TimeUnit.SECONDS.sleep(1) - } - packer.close - } - }) - - val future = executorService.submit(new Callable[String] { - override def call: String = { - val conn_ch = SocketChannel.open(new InetSocketAddress("localhost", server.socket.getLocalPort)) - val unpacker = MessagePack.newDefaultUnpacker(conn_ch) - val s = unpacker.unpackString - unpacker.close - s - } - }) + try + executorService.execute( + new Runnable: + override def run: Unit = + val server_ch = server.accept + val packer = MessagePack.newDefaultPacker(server_ch) + packer.packString("0123456789") + packer.flush + // Keep the connection open + while !executorService.isShutdown do + TimeUnit.SECONDS.sleep(1) + packer.close + ) + + val future = executorService.submit( + new Callable[String]: + override def call: String = + val conn_ch = SocketChannel.open( + new InetSocketAddress("localhost", server.socket.getLocalPort) + ) + val unpacker = MessagePack.newDefaultUnpacker(conn_ch) + val s = unpacker.unpackString + unpacker.close + s + ) future.get(5, TimeUnit.SECONDS) shouldBe "0123456789" - } finally { + finally executorService.shutdown - if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) { + if !executorService.awaitTermination(5, TimeUnit.SECONDS) then executorService.shutdownNow - } - } + end try } } -} + +end MessageBufferInputTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala index ea9cde57..5f6e9b7a 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferOutputTest.scala @@ -17,34 +17,30 @@ package org.msgpack.core.buffer import wvlet.airspec.AirSpec -import java.io._ +import java.io.* -class MessageBufferOutputTest extends AirSpec { +class MessageBufferOutputTest extends AirSpec: - private def createTempFile = { + private def createTempFile = val f = File.createTempFile("msgpackTest", "msgpack") f.deleteOnExit f - } - private def createTempFileWithOutputStream = { + private def createTempFileWithOutputStream = val f = createTempFile val out = new FileOutputStream(f) (f, out) - } - private def createTempFileWithChannel = { + private def createTempFileWithChannel = val (f, out) = createTempFileWithOutputStream val ch = out.getChannel (f, ch) - } - private def writeIntToBuf(buf: MessageBufferOutput) = { + private def writeIntToBuf(buf: MessageBufferOutput) = val mb0 = buf.next(8) mb0.putInt(0, 42) buf.writeBuffer(4) buf.close - } test("OutputStreamBufferOutput") { test("reset buffer") { @@ -73,4 +69,5 @@ class MessageBufferOutputTest extends AirSpec { f1.length.toInt > 0 shouldBe true } } -} + +end MessageBufferOutputTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala index 03e93b89..36940473 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/buffer/MessageBufferTest.scala @@ -21,9 +21,10 @@ import wvlet.airspec.AirSpec import java.nio.ByteBuffer import scala.util.Random -/** Created on 2014/05/01. +/** + * Created on 2014/05/01. */ -class MessageBufferTest extends AirSpec with Benchmark { +class MessageBufferTest extends AirSpec with Benchmark: private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] @@ -54,97 +55,87 @@ class MessageBufferTest extends AirSpec with Benchmark { val ub = MessageBuffer.allocate(M) val ud = - if (universal) MessageBuffer.wrap(ByteBuffer.allocate(M)) - else MessageBuffer.wrap(ByteBuffer.allocateDirect(M)) + if universal then + MessageBuffer.wrap(ByteBuffer.allocate(M)) + else + MessageBuffer.wrap(ByteBuffer.allocateDirect(M)) val hb = ByteBuffer.allocate(M) val db = ByteBuffer.allocateDirect(M) - def bench(f: Int => Unit): Unit = { + def bench(f: Int => Unit): Unit = var i = 0 - while (i < N) { + while i < N do f((i * 4) % M) i += 1 - } - } val r = new Random(0) val rs = new Array[Int](N) (0 until N).map(i => rs(i) = r.nextInt(N)) - def randomBench(f: Int => Unit): Unit = { + def randomBench(f: Int => Unit): Unit = var i = 0 - while (i < N) { + while i < N do f((rs(i) * 4) % M) i += 1 - } - } val rep = 3 info(f"Reading buffers (of size:${M}%,d) ${N}%,d x $rep times") time("sequential getInt", repeat = rep) { block("unsafe array") { var i = 0 - while (i < N) { + while i < N do ub.getInt((i * 4) % M) i += 1 - } } block("unsafe direct") { var i = 0 - while (i < N) { + while i < N do ud.getInt((i * 4) % M) i += 1 - } } block("allocate") { var i = 0 - while (i < N) { + while i < N do hb.getInt((i * 4) % M) i += 1 - } } block("allocateDirect") { var i = 0 - while (i < N) { + while i < N do db.getInt((i * 4) % M) i += 1 - } } } time("random getInt", repeat = rep) { block("unsafe array") { var i = 0 - while (i < N) { + while i < N do ub.getInt((rs(i) * 4) % M) i += 1 - } } block("unsafe direct") { var i = 0 - while (i < N) { + while i < N do ud.getInt((rs(i) * 4) % M) i += 1 - } } block("allocate") { var i = 0 - while (i < N) { + while i < N do hb.getInt((rs(i) * 4) % M) i += 1 - } } block("allocateDirect") { var i = 0 - while (i < N) { + while i < N do db.getInt((rs(i) * 4) % M) i += 1 - } } } } @@ -152,20 +143,21 @@ class MessageBufferTest extends AirSpec with Benchmark { private val builder = Seq.newBuilder[MessageBuffer] builder += MessageBuffer.allocate(10) builder += MessageBuffer.wrap(ByteBuffer.allocate(10)) - if (!universal) builder += MessageBuffer.wrap(ByteBuffer.allocateDirect(10)) + if !universal then + builder += MessageBuffer.wrap(ByteBuffer.allocateDirect(10)) + private val buffers = builder.result() test("convert to ByteBuffer") { - for (t <- buffers) { + for t <- buffers do val bb = t.sliceAsByteBuffer bb.position() shouldBe 0 bb.limit() shouldBe 10 bb.capacity shouldBe 10 - } } test("put ByteBuffer on itself") { - for (t <- buffers) { + for t <- buffers do val b = Array[Byte](0x02, 0x03) val srcArray = ByteBuffer.wrap(b) val srcHeap = ByteBuffer.allocate(b.length) @@ -173,7 +165,7 @@ class MessageBufferTest extends AirSpec with Benchmark { val srcOffHeap = ByteBuffer.allocateDirect(b.length) srcOffHeap.put(b).flip - for (src <- Seq(srcArray, srcHeap, srcOffHeap)) { + for src <- Seq(srcArray, srcHeap, srcOffHeap) do // Write header bytes val header = Array[Byte](0x00, 0x01) t.putBytes(0, header, 0, header.length) @@ -184,12 +176,10 @@ class MessageBufferTest extends AirSpec with Benchmark { t.getByte(1) shouldBe 0x01 t.getByte(2) shouldBe 0x02 t.getByte(3) shouldBe 0x03 - } - } } test("put MessageBuffer on itself") { - for (t <- buffers) { + for t <- buffers do val b = Array[Byte](0x02, 0x03) val srcArray = ByteBuffer.wrap(b) val srcHeap = ByteBuffer.allocate(b.length) @@ -198,9 +188,10 @@ class MessageBufferTest extends AirSpec with Benchmark { srcOffHeap.put(b).flip val builder = Seq.newBuilder[ByteBuffer] builder ++= Seq(srcArray, srcHeap) - if (!universal) builder += srcOffHeap + if !universal then + builder += srcOffHeap - for (src <- builder.result().map(d => MessageBuffer.wrap(d))) { + for src <- builder.result().map(d => MessageBuffer.wrap(d)) do // Write header bytes val header = Array[Byte](0x00, 0x01) t.putBytes(0, header, 0, header.length) @@ -211,23 +202,18 @@ class MessageBufferTest extends AirSpec with Benchmark { t.getByte(1) shouldBe 0x01 t.getByte(2) shouldBe 0x02 t.getByte(3) shouldBe 0x03 - } - } } test("copy sliced buffer") { - def prepareBytes: Array[Byte] = { - Array[Byte](0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07) - } + def prepareBytes: Array[Byte] = Array[Byte](0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07) - def prepareDirectBuffer: ByteBuffer = { + def prepareDirectBuffer: ByteBuffer = val directBuffer = ByteBuffer.allocateDirect(prepareBytes.length) directBuffer.put(prepareBytes) directBuffer.flip directBuffer - } - def checkSliceAndCopyTo(srcBuffer: MessageBuffer, dstBuffer: MessageBuffer) = { + def checkSliceAndCopyTo(srcBuffer: MessageBuffer, dstBuffer: MessageBuffer) = val sliced = srcBuffer.slice(2, 5) sliced.size() shouldBe 5 @@ -247,12 +233,17 @@ class MessageBufferTest extends AirSpec with Benchmark { dstBuffer.getByte(5) shouldBe 0x05 dstBuffer.getByte(6) shouldBe 0x06 dstBuffer.getByte(7) shouldBe 0x07 - } checkSliceAndCopyTo(MessageBuffer.wrap(prepareBytes), MessageBuffer.wrap(prepareBytes)) - checkSliceAndCopyTo(MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)), MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes))) - if (!universal) { - checkSliceAndCopyTo(MessageBuffer.wrap(prepareDirectBuffer), MessageBuffer.wrap(prepareDirectBuffer)) - } + checkSliceAndCopyTo( + MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)), + MessageBuffer.wrap(ByteBuffer.wrap(prepareBytes)) + ) + if !universal then + checkSliceAndCopyTo( + MessageBuffer.wrap(prepareDirectBuffer), + MessageBuffer.wrap(prepareDirectBuffer) + ) } -} + +end MessageBufferTest diff --git a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala index d0b0e08e..1a1a3a3c 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/example/MessagePackExampleTest.scala @@ -17,8 +17,9 @@ package org.msgpack.core.example import wvlet.airspec.AirSpec -/** */ -class MessagePackExampleTest extends AirSpec { +/** + */ +class MessagePackExampleTest extends AirSpec: test("example") { @@ -38,4 +39,3 @@ class MessagePackExampleTest extends AirSpec { MessagePackExample.configuration(); } } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala index fb340553..73e1edc5 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/RawStringValueImplTest.scala @@ -17,7 +17,7 @@ package org.msgpack.value import wvlet.airspec.AirSpec -class RawStringValueImplTest extends AirSpec { +class RawStringValueImplTest extends AirSpec: test("return the same hash code if they are equal") { val str = "a" @@ -29,4 +29,3 @@ class RawStringValueImplTest extends AirSpec { a2 shouldBe a1 a2.hashCode shouldBe a1.hashCode } -} diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala index 3568ba5b..623ca36d 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueFactoryTest.scala @@ -19,8 +19,9 @@ import org.scalacheck.Gen import wvlet.airspec.AirSpec import wvlet.airspec.spi.PropertyCheck -/** */ -class ValueFactoryTest extends AirSpec with PropertyCheck { +/** + */ +class ValueFactoryTest extends AirSpec with PropertyCheck: private def isValid( v: Value, @@ -37,7 +38,7 @@ class ValueFactoryTest extends AirSpec with PropertyCheck { isRaw: Boolean = false, isNumber: Boolean = false, isTimestamp: Boolean = false - ): Boolean = { + ): Boolean = v.isNilValue shouldBe isNil v.isBooleanValue shouldBe isBoolean v.isIntegerValue shouldBe isInteger @@ -51,7 +52,6 @@ class ValueFactoryTest extends AirSpec with PropertyCheck { v.isNumberValue shouldBe isNumber v.isTimestampValue shouldBe isTimestamp true - } test("ValueFactory") { test("nil") { @@ -66,24 +66,44 @@ class ValueFactoryTest extends AirSpec with PropertyCheck { test("int") { forAll { (v: Int) => - isValid(ValueFactory.newInteger(v), expected = ValueType.INTEGER, isInteger = true, isNumber = true) + isValid( + ValueFactory.newInteger(v), + expected = ValueType.INTEGER, + isInteger = true, + isNumber = true + ) } } test("float") { forAll { (v: Float) => - isValid(ValueFactory.newFloat(v), expected = ValueType.FLOAT, isFloat = true, isNumber = true) + isValid( + ValueFactory.newFloat(v), + expected = ValueType.FLOAT, + isFloat = true, + isNumber = true + ) } } test("string") { forAll { (v: String) => - isValid(ValueFactory.newString(v), expected = ValueType.STRING, isString = true, isRaw = true) + isValid( + ValueFactory.newString(v), + expected = ValueType.STRING, + isString = true, + isRaw = true + ) } } test("array") { forAll { (v: Array[Byte]) => - isValid(ValueFactory.newBinary(v), expected = ValueType.BINARY, isBinary = true, isRaw = true) + isValid( + ValueFactory.newBinary(v), + expected = ValueType.BINARY, + isBinary = true, + isRaw = true + ) } } @@ -97,13 +117,23 @@ class ValueFactoryTest extends AirSpec with PropertyCheck { test("ext") { forAll { (v: Array[Byte]) => - isValid(ValueFactory.newExtension(0, v), expected = ValueType.EXTENSION, isExtension = true, isRaw = false) + isValid( + ValueFactory.newExtension(0, v), + expected = ValueType.EXTENSION, + isExtension = true, + isRaw = false + ) } } test("timestamp") { forAll { (millis: Long) => - isValid(ValueFactory.newTimestamp(millis), expected = ValueType.EXTENSION, isExtension = true, isTimestamp = true) + isValid( + ValueFactory.newTimestamp(millis), + expected = ValueType.EXTENSION, + isExtension = true, + isTimestamp = true + ) } } @@ -111,8 +141,14 @@ class ValueFactoryTest extends AirSpec with PropertyCheck { val posLong = Gen.chooseNum[Long](-31557014167219200L, 31556889864403199L) val posInt = Gen.chooseNum(0, 1000000000 - 1) // NANOS_PER_SECOND forAll(posLong, posInt) { (sec: Long, nano: Int) => - isValid(ValueFactory.newTimestamp(sec, nano), expected = ValueType.EXTENSION, isExtension = true, isTimestamp = true) + isValid( + ValueFactory.newTimestamp(sec, nano), + expected = ValueType.EXTENSION, + isExtension = true, + isTimestamp = true + ) } } } -} + +end ValueFactoryTest diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala index 83cbde6b..76e2ed27 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTest.scala @@ -18,14 +18,17 @@ package org.msgpack.value import org.msgpack.core.MessagePackSpec.createMessagePackData import java.math.BigInteger -import org.msgpack.core._ +import org.msgpack.core.* import org.scalacheck.Prop.propBoolean import wvlet.airframe.json.JSON import wvlet.airspec.AirSpec import wvlet.airspec.spi.PropertyCheck -class ValueTest extends AirSpec with PropertyCheck { - private def checkSuccinctType(pack: MessagePacker => Unit, expectedAtMost: MessageFormat): Boolean = { +class ValueTest extends AirSpec with PropertyCheck: + private def checkSuccinctType( + pack: MessagePacker => Unit, + expectedAtMost: MessageFormat + ): Boolean = val b = createMessagePackData(pack) val v1 = MessagePack.newDefaultUnpacker(b).unpackValue() val mf = v1.asIntegerValue().mostSuccinctMessageFormat() @@ -39,7 +42,6 @@ class ValueTest extends AirSpec with PropertyCheck { mf2.ordinal() <= expectedAtMost.ordinal() shouldBe true true - } test("Value") { test("tell most succinct integer type") { @@ -61,14 +63,17 @@ class ValueTest extends AirSpec with PropertyCheck { forAll { (v: Long) => v > 0 ==> { // Create value between 2^63-1 < v <= 2^64-1 - checkSuccinctType(_.packBigInteger(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(v))), MessageFormat.UINT64) + checkSuccinctType( + _.packBigInteger(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(v))), + MessageFormat.UINT64 + ) } } } test("produce json strings") { - import ValueFactory._ + import ValueFactory.* newNil().toJson shouldBe "null" newNil().toString shouldBe "null" @@ -88,7 +93,8 @@ class ValueTest extends AirSpec with PropertyCheck { newArray(newInteger(0), newString("hello")).toJson shouldBe "[0,\"hello\"]" newArray(newInteger(0), newString("hello")).toString shouldBe "[0,\"hello\"]" - newArray(newArray(newString("Apple"), newFloat(0.2)), newNil()).toJson shouldBe """[["Apple",0.2],null]""" + newArray(newArray(newString("Apple"), newFloat(0.2)), newNil()).toJson shouldBe + """[["Apple",0.2],null]""" // Map value val m = newMapBuilder() @@ -112,7 +118,7 @@ class ValueTest extends AirSpec with PropertyCheck { } test("check appropriate range for integers") { - import ValueFactory._ + import ValueFactory.* import java.lang.Byte import java.lang.Short @@ -142,4 +148,5 @@ class ValueTest extends AirSpec with PropertyCheck { } } } -} + +end ValueTest diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala index fc81bdeb..7b992f28 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala @@ -15,70 +15,59 @@ // package org.msgpack.value -import org.msgpack.core.MessagePack.Code._ +import org.msgpack.core.MessagePack.Code.* import org.msgpack.core.{MessageFormat, MessageFormatException} import wvlet.airspec.AirSpec -/** Created on 2014/05/06. +/** + * Created on 2014/05/06. */ -class ValueTypeTest extends AirSpec { +class ValueTypeTest extends AirSpec: test("lookup ValueType from a byte value") { - def check(b: Byte, tpe: ValueType): Unit = { - MessageFormat.valueOf(b).getValueType shouldBe tpe - } + def check(b: Byte, tpe: ValueType): Unit = MessageFormat.valueOf(b).getValueType shouldBe tpe - for (i <- 0 until 0x7f) { + for i <- 0 until 0x7f do check(i.toByte, ValueType.INTEGER) - } - for (i <- 0x80 until 0x8f) { + for i <- 0x80 until 0x8f do check(i.toByte, ValueType.MAP) - } - for (i <- 0x90 until 0x9f) { + for i <- 0x90 until 0x9f do check(i.toByte, ValueType.ARRAY) - } check(NIL, ValueType.NIL) - try { + try MessageFormat.valueOf(NEVER_USED).getValueType fail("NEVER_USED type should not have ValueType") - } catch { + catch case e: MessageFormatException => // OK - } check(TRUE, ValueType.BOOLEAN) check(FALSE, ValueType.BOOLEAN) - for (t <- Seq(BIN8, BIN16, BIN32)) { + for t <- Seq(BIN8, BIN16, BIN32) do check(t, ValueType.BINARY) - } - for (t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32)) { + for t <- Seq(FIXEXT1, FIXEXT2, FIXEXT4, FIXEXT8, FIXEXT16, EXT8, EXT16, EXT32) do check(t, ValueType.EXTENSION) - } - for (t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64)) { + for t <- Seq(INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64) do check(t, ValueType.INTEGER) - } - for (t <- Seq(STR8, STR16, STR32)) { + for t <- Seq(STR8, STR16, STR32) do check(t, ValueType.STRING) - } - for (t <- Seq(FLOAT32, FLOAT64)) { + for t <- Seq(FLOAT32, FLOAT64) do check(t, ValueType.FLOAT) - } - for (t <- Seq(ARRAY16, ARRAY32)) { + for t <- Seq(ARRAY16, ARRAY32) do check(t, ValueType.ARRAY) - } - for (i <- 0xe0 until 0xff) { + for i <- 0xe0 until 0xff do check(i.toByte, ValueType.INTEGER) - } } -} + +end ValueTypeTest diff --git a/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala index f9a1c2a0..4eabdbd7 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala @@ -21,11 +21,12 @@ import wvlet.airspec.spi.PropertyCheck import java.time.Instant import java.util -import scala.jdk.CollectionConverters._ +import scala.jdk.CollectionConverters.* -/** */ -class VariableTest extends AirSpec with PropertyCheck { - private def check(pack: MessagePacker => Unit, checker: Variable => Unit): Unit = { +/** + */ +class VariableTest extends AirSpec with PropertyCheck: + private def check(pack: MessagePacker => Unit, checker: Variable => Unit): Unit = val packer = MessagePack.newDefaultBufferPacker() pack(packer) val msgpack = packer.toByteArray @@ -35,11 +36,11 @@ class VariableTest extends AirSpec with PropertyCheck { unpacker.unpackValue(v) checker(v) unpacker.close() - } - /** Test Value -> MsgPack -> Value + /** + * Test Value -> MsgPack -> Value */ - private def roundTrip(v: Value): Unit = { + private def roundTrip(v: Value): Unit = val packer = MessagePack.newDefaultBufferPacker() v.writeTo(packer) val msgpack = packer.toByteArray @@ -48,7 +49,6 @@ class VariableTest extends AirSpec with PropertyCheck { unpacker.close() v shouldBe v1 v.immutableValue() shouldBe v1 - } private def validateValue[V <: Value]( v: V, @@ -62,7 +62,7 @@ class VariableTest extends AirSpec with PropertyCheck { asMap: Boolean = false, asExtension: Boolean = false, asTimestamp: Boolean = false - ): V = { + ): V = v.isNilValue shouldBe asNil v.isBooleanValue shouldBe asBoolean v.isIntegerValue shouldBe asInteger @@ -76,203 +76,200 @@ class VariableTest extends AirSpec with PropertyCheck { v.isExtensionValue shouldBe asExtension | asTimestamp v.isTimestampValue shouldBe asTimestamp - if (asNil) { + if asNil then v.getValueType shouldBe ValueType.NIL roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asNilValue() } - } - if (asBoolean) { + if asBoolean then v.getValueType shouldBe ValueType.BOOLEAN roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asBooleanValue() } - } - if (asInteger) { + if asInteger then v.getValueType shouldBe ValueType.INTEGER roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asIntegerValue() } - } - if (asFloat) { + if asFloat then v.getValueType shouldBe ValueType.FLOAT roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asFloatValue() } - } - if (asBinary | asString) { + if asBinary | asString then v.asRawValue() roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asRawValue() } - } - if (asBinary) { + if asBinary then v.getValueType shouldBe ValueType.BINARY roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asBinaryValue() } - } - if (asString) { + if asString then v.getValueType shouldBe ValueType.STRING roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asStringValue() } - } - if (asArray) { + if asArray then v.getValueType shouldBe ValueType.ARRAY roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asArrayValue() } - } - if (asMap) { + if asMap then v.getValueType shouldBe ValueType.MAP roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asMapValue() } - } - if (asExtension) { + if asExtension then v.getValueType shouldBe ValueType.EXTENSION roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asExtensionValue() } - } - if (asTimestamp) { + if asTimestamp then v.getValueType shouldBe ValueType.EXTENSION roundTrip(v) - } else { + else intercept[MessageTypeCastException] { v.asTimestampValue() } - } v - } + + end validateValue test("Variable") { test("read nil") { check( _.packNil, - checker = { v => - val iv = validateValue(v.asNilValue(), asNil = true) - iv.toJson shouldBe "null" - } + checker = + v => + val iv = validateValue(v.asNilValue(), asNil = true) + iv.toJson shouldBe "null" ) } test("read integers") { - forAll { i: Int => - check( - _.packInt(i), - checker = { v => - val iv = validateValue(v.asIntegerValue(), asInteger = true) - iv.asInt() shouldBe i - iv.asLong() shouldBe i.toLong - } - ) + forAll { (i: Int) => + check( + _.packInt(i), + checker = + v => + val iv = validateValue(v.asIntegerValue(), asInteger = true) + iv.asInt() shouldBe i + iv.asLong() shouldBe i.toLong + ) } } test("read double") { - forAll { x: Double => - check( - _.packDouble(x), - checker = { v => - val iv = validateValue(v.asFloatValue(), asFloat = true) - // iv.toDouble shouldBe v - // iv.toFloat shouldBe x.toFloat - } - ) + forAll { (x: Double) => + check( + _.packDouble(x), + checker = + v => + val iv = validateValue(v.asFloatValue(), asFloat = true) + // iv.toDouble shouldBe v + // iv.toFloat shouldBe x.toFloat + ) } } test("read boolean") { - forAll { x: Boolean => - check( - _.packBoolean(x), - checker = { v => - val iv = validateValue(v.asBooleanValue(), asBoolean = true) - iv.getBoolean shouldBe x - } - ) + forAll { (x: Boolean) => + check( + _.packBoolean(x), + checker = + v => + val iv = validateValue(v.asBooleanValue(), asBoolean = true) + iv.getBoolean shouldBe x + ) } } test("read binary") { - forAll { x: Array[Byte] => + forAll { (x: Array[Byte]) => check( { packer => - packer.packBinaryHeader(x.length); packer.addPayload(x) + packer.packBinaryHeader(x.length); + packer.addPayload(x) }, - checker = { v => - val iv = validateValue(v.asBinaryValue(), asBinary = true) - util.Arrays.equals(iv.asByteArray(), x) - } + checker = + v => + val iv = validateValue(v.asBinaryValue(), asBinary = true) + util.Arrays.equals(iv.asByteArray(), x) ) } } test("read string") { - forAll { x: String => - check( - _.packString(x), - checker = { v => - val iv = validateValue(v.asStringValue(), asString = true) - iv.asString() shouldBe x - } - ) + forAll { (x: String) => + check( + _.packString(x), + checker = + v => + val iv = validateValue(v.asStringValue(), asString = true) + iv.asString() shouldBe x + ) } } test("read array") { - forAll { x: Seq[Int] => + forAll { (x: Seq[Int]) => check( { packer => packer.packArrayHeader(x.size) - x.foreach { packer.packInt(_) } + x.foreach { + packer.packInt(_) + } }, - checker = { v => - val iv = validateValue(v.asArrayValue(), asArray = true) - val lst = iv.list().asScala.map(_.asIntegerValue().toInt) - lst shouldBe x - } + checker = + v => + val iv = validateValue(v.asArrayValue(), asArray = true) + val lst = iv.list().asScala.map(_.asIntegerValue().toInt) + lst shouldBe x ) } } test("read map") { - forAll { x: Seq[Int] => + forAll { (x: Seq[Int]) => // Generate map with unique keys - val map = x.zipWithIndex.map { case (x, i) => (s"key-${i}", x) } + val map = x + .zipWithIndex + .map { case (x, i) => + (s"key-${i}", x) + } check( { packer => packer.packMapHeader(map.size) @@ -281,27 +278,32 @@ class VariableTest extends AirSpec with PropertyCheck { packer.packInt(x._2) } }, - checker = { v => - val iv = validateValue(v.asMapValue(), asMap = true) - val lst = iv.map().asScala.map(p => (p._1.asStringValue().asString(), p._2.asIntegerValue().asInt())).toSeq - lst.sortBy(_._1) shouldBe map.sortBy(_._1) - } + checker = + v => + val iv = validateValue(v.asMapValue(), asMap = true) + val lst = + iv.map() + .asScala + .map(p => (p._1.asStringValue().asString(), p._2.asIntegerValue().asInt())) + .toSeq + lst.sortBy(_._1) shouldBe map.sortBy(_._1) ) } } test("read timestamps") { - forAll { millis: Long => - val i = Instant.ofEpochMilli(millis) - check( - _.packTimestamp(i), - checker = { v => - val ts = validateValue(v.asTimestampValue(), asTimestamp = true) - ts.isTimestampValue shouldBe true - ts.toInstant shouldBe i - } - ) + forAll { (millis: Long) => + val i = Instant.ofEpochMilli(millis) + check( + _.packTimestamp(i), + checker = + v => + val ts = validateValue(v.asTimestampValue(), asTimestamp = true) + ts.isTimestampValue shouldBe true + ts.toInstant shouldBe i + ) } } } -} + +end VariableTest From 2bb48340b5159b96d14b8bb73fd293ce08ff89db Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 10:35:17 -0700 Subject: [PATCH 175/195] Upgrade Scala to 3.7.1 and use Scala 3 code format style (#899) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Upgrade Scala to 3.7.1 and update code format style - Upgrade Scala version from 2.13.12 to 3.7.1 in build.sbt - Update scalafmt.conf to use Scala 3 dialect and modern formatting rules - Fix Scala 3 compatibility issues in test files: - Update lambda syntax to use parentheses around parameters - Remove deprecated underscore suffix from function references - Apply Scala 3 formatting with scalafmt 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Update CLAUDE.md for Scala 3.7.1 and modern sbt syntax - Fix build command to use modern sbt syntax: Test / compile instead of test:compile - Update Scala version reference to 3.7.1 in testing structure - Update scalafmt configuration notes to reflect Scala 3 dialect and 100 char limit * Update CLAUDE.md to recommend latest Scala 3 version - Change specific version reference to 'always use the latest Scala 3 version' - This ensures the documentation remains current as new Scala 3 versions are released * Update README.md for modern sbt syntax and Scala 3 - Fix sbt command syntax: change test:compile to 'Test / compile' - Add note about Scala 3 dialect and latest version recommendation - Ensure developer documentation matches current project configuration * Update scalafmtAll command description - Change comment from 'Format Scala test code' to 'Format all Scala and sbt code' - More accurately reflects what scalafmtAll does (formats all Scala files, not just tests) - Apply change to both README.md and CLAUDE.md for consistency --------- Co-authored-by: Claude --- .scalafmt.conf | 2 +- CLAUDE.md | 8 +- README.md | 5 +- .../org/msgpack/core/MessagePackTest.scala | 6 +- .../org/msgpack/core/MessagePackerTest.scala | 2 +- .../msgpack/core/MessageUnpackerTest.scala | 10 +-- .../org/msgpack/value/VariableTest.scala | 80 +++++++++---------- 7 files changed, 57 insertions(+), 56 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index fcadd98d..e8563baf 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 3.9.4 +version = 3.9.8 project.layout = StandardConvention runner.dialect = scala3 maxColumn = 100 diff --git a/CLAUDE.md b/CLAUDE.md index e01643b5..2e72e982 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ MessagePack-Java is a binary serialization library that provides a fast and comp ### Build and Compile ```bash ./sbt compile # Compile source code -./sbt test:compile # Compile source and test code +./sbt "Test / compile" # Compile source and test code ./sbt package # Create JAR files ``` @@ -31,7 +31,7 @@ MessagePack-Java is a binary serialization library that provides a fast and comp ### Code Quality ```bash ./sbt jcheckStyle # Run checkstyle (Facebook Presto style) -./sbt scalafmtAll # Format Scala test code +./sbt scalafmtAll # Format all Scala and sbt code ``` ### Publishing @@ -66,7 +66,7 @@ The msgpack-jackson module provides: - Extension type support including timestamps ### Testing Structure -- **msgpack-core tests**: Written in Scala using AirSpec framework +- **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/` @@ -81,7 +81,7 @@ For JDK 17+ compatibility, these options are automatically added: ## Code Style Requirements - Java code follows Facebook Presto style (enforced by checkstyle) -- Scala test code uses Scalafmt with 180 character line limit +- Scala test code uses Scalafmt with Scala 3 dialect and 100 character line limit - Checkstyle runs automatically during compilation - No external dependencies allowed in msgpack-core diff --git a/README.md b/README.md index 34a3f277..54d1877a 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ msgpack-java uses [sbt](http://www.scala-sbt.org/) for building the projects. Fo Coding style * msgpack-java uses [the same coding style](https://github.com/airlift/codestyle) with Facebook Presto * [IntelliJ setting file](https://raw.githubusercontent.com/airlift/codestyle/master/IntelliJIdea14/Airlift.xml) + * Scala test code uses Scalafmt with Scala 3 dialect (always use the latest Scala 3 version) ### Basic sbt commands Enter the sbt console: @@ -76,14 +77,14 @@ $ ./sbt Here is a list of sbt commands for daily development: ``` > ~compile # Compile source codes -> ~test:compile # Compile both source and test codes +> ~"Test / compile" # Compile both source and test codes > ~test # Run tests upon source code change > ~testOnly *MessagePackTest # Run tests in the specified class > ~testOnly *MessagePackTest -- (pattern) # Run tests matching the pattern > project msgpack-core # Focus on a specific project > package # Create a jar file in the target folder of each project > jcheckStyle # Run check style -> scalafmtAll # Reformat code +> scalafmtAll # Format all Scala and sbt code ``` ### Publishing diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index 0a4328d8..b5541393 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -376,7 +376,7 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark: test("report errors when packing/unpacking malformed strings") { pending("We need to produce malformed utf-8 strings in Java 8") // Create 100 malformed UTF8 Strings - val r = new Random(0) + val r = new Random(0) val malformedStrings = Iterator .continually { val b = new Array[Byte](10) @@ -580,12 +580,12 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark: kvs .grouped(2) - .map((kvp: Array[Value]) => + .map { (kvp: Array[Value]) => val k = kvp(0) val v = kvp(1) (k.asStringValue().asString, v.asStringValue().asString) - ) + } .toMap } .toList diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala index c1b4b0a4..7ff5d82e 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackerTest.scala @@ -211,7 +211,7 @@ class MessagePackerTest extends AirSpec with Benchmark: } test("compute totalWrittenBytes") { - val out = new ByteArrayOutputStream + val out = new ByteArrayOutputStream val packerTotalWrittenBytes = withResource(MessagePack.newDefaultPacker(out)) { packer => packer diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala index ae25d284..adab4708 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala @@ -30,7 +30,7 @@ import scala.util.Random object MessageUnpackerTest: class SplitMessageBufferInput(array: Array[Array[Byte]]) extends MessageBufferInput: - var cursor = 0 + var cursor = 0 override def next(): MessageBuffer = if cursor < array.length then val a = array(cursor) @@ -45,7 +45,7 @@ import org.msgpack.core.MessageUnpackerTest.* class MessageUnpackerTest extends AirSpec with Benchmark: - private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] + private val universal = MessageBuffer.allocate(0).isInstanceOf[MessageBufferU] private def testData: Array[Byte] = val out = new ByteArrayOutputStream() val packer = MessagePack.newDefaultPacker(out) @@ -435,7 +435,7 @@ class MessageUnpackerTest extends AirSpec with Benchmark: val t = time("skip performance", repeat = N) { block("v6") { - val v6 = new org.msgpack.MessagePack() + val v6 = new org.msgpack.MessagePack() val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) var count = 0 @@ -567,7 +567,7 @@ class MessageUnpackerTest extends AirSpec with Benchmark: val t = time("unpack performance", repeat = N) { block("v6") { - val v6 = new org.msgpack.MessagePack() + val v6 = new org.msgpack.MessagePack() val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(data)) var count = 0 @@ -655,7 +655,7 @@ class MessageUnpackerTest extends AirSpec with Benchmark: time("unpackBinary", repeat = 100) { block("v6") { - val v6 = new org.msgpack.MessagePack() + val v6 = new org.msgpack.MessagePack() val unpacker = new org.msgpack.unpacker.MessagePackUnpacker(v6, new ByteArrayInputStream(b)) var i = 0 diff --git a/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala index 4eabdbd7..2f3cbf9c 100644 --- a/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/value/VariableTest.scala @@ -181,39 +181,39 @@ class VariableTest extends AirSpec with PropertyCheck: test("read integers") { forAll { (i: Int) => - check( - _.packInt(i), - checker = - v => - val iv = validateValue(v.asIntegerValue(), asInteger = true) - iv.asInt() shouldBe i - iv.asLong() shouldBe i.toLong - ) + check( + _.packInt(i), + checker = + v => + val iv = validateValue(v.asIntegerValue(), asInteger = true) + iv.asInt() shouldBe i + iv.asLong() shouldBe i.toLong + ) } } test("read double") { forAll { (x: Double) => - check( - _.packDouble(x), - checker = - v => - val iv = validateValue(v.asFloatValue(), asFloat = true) - // iv.toDouble shouldBe v - // iv.toFloat shouldBe x.toFloat - ) + check( + _.packDouble(x), + checker = + v => + val iv = validateValue(v.asFloatValue(), asFloat = true) + // iv.toDouble shouldBe v + // iv.toFloat shouldBe x.toFloat + ) } } test("read boolean") { forAll { (x: Boolean) => - check( - _.packBoolean(x), - checker = - v => - val iv = validateValue(v.asBooleanValue(), asBoolean = true) - iv.getBoolean shouldBe x - ) + check( + _.packBoolean(x), + checker = + v => + val iv = validateValue(v.asBooleanValue(), asBoolean = true) + iv.getBoolean shouldBe x + ) } } @@ -234,13 +234,13 @@ class VariableTest extends AirSpec with PropertyCheck: test("read string") { forAll { (x: String) => - check( - _.packString(x), - checker = - v => - val iv = validateValue(v.asStringValue(), asString = true) - iv.asString() shouldBe x - ) + check( + _.packString(x), + checker = + v => + val iv = validateValue(v.asStringValue(), asString = true) + iv.asString() shouldBe x + ) } } @@ -280,7 +280,7 @@ class VariableTest extends AirSpec with PropertyCheck: }, checker = v => - val iv = validateValue(v.asMapValue(), asMap = true) + val iv = validateValue(v.asMapValue(), asMap = true) val lst = iv.map() .asScala @@ -293,15 +293,15 @@ class VariableTest extends AirSpec with PropertyCheck: test("read timestamps") { forAll { (millis: Long) => - val i = Instant.ofEpochMilli(millis) - check( - _.packTimestamp(i), - checker = - v => - val ts = validateValue(v.asTimestampValue(), asTimestamp = true) - ts.isTimestampValue shouldBe true - ts.toInstant shouldBe i - ) + val i = Instant.ofEpochMilli(millis) + check( + _.packTimestamp(i), + checker = + v => + val ts = validateValue(v.asTimestampValue(), asTimestamp = true) + ts.isTimestampValue shouldBe true + ts.toInstant shouldBe i + ) } } } From fe697bc1b401d0ed2e5da77f6164f1c138647351 Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 10:40:59 -0700 Subject: [PATCH 176/195] Update README.md publishing instructions for Sonatype Central (#900) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove references to deprecated sbt-sonatype plugin - Update credentials setup to use new Sonatype Central format - Replace sonatypeBundleRelease with sonaRelease command - Add environment variable alternative for credentials - Update host from oss.sonatype.org to central.sonatype.com 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- README.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 54d1877a..f23af0b7 100644 --- a/README.md +++ b/README.md @@ -108,27 +108,38 @@ A new release note will be generated automatically at the [GitHub Releases](http #### Publishing to Sonatype from Local Machine -If you need to publish to Maven central using a local machine, you need to configure [sbt-sonatype](https://github.com/xerial/sbt-sonatype) plugin. First set Sonatype account information (user name and password) in the global sbt settings. To protect your password, never include this file in your project. +If you need to publish to Maven central using a local machine, you need to configure credentials for Sonatype Central. First set Sonatype account information (user name and password) in the global sbt settings. To protect your password, never include this file in your project. -___$HOME/.sbt/(sbt-version)/sonatype.sbt___ +___$HOME/.sbt/1.0/credentials.sbt___ ``` -credentials += Credentials("Sonatype Nexus Repository Manager", - "oss.sonatype.org", - "(Sonatype user name)", - "(Sonatype password)") +credentials += Credentials(Path.userHome / ".sbt" / "sonatype_central_credentials") +``` + +Then create a credentials file at `~/.sbt/sonatype_central_credentials`: + +``` +host=central.sonatype.com +user= +password= +``` + +Alternatively, you can use environment variables: +```bash +export SONATYPE_USERNAME= +export SONATYPE_PASSWORD= ``` You may also need to configure GPG. See the instruction in [sbt-pgp](https://github.com/sbt/sbt-pgp). -Then, run `publishedSigned` followed by `sonatypeBundleRelease`: +Then, run `publishSigned` followed by `sonaRelease`: ``` # [optional] When you need to perform the individual release steps manually, use the following commands: > publishSigned # Publish GPG signed artifacts to the Sonatype repository -> sonatypeBundleRelease # Publish to the Maven Central (It will be synched within less than 4 hours) +> sonaRelease # Publish to the Maven Central (It will be synched within less than 4 hours) ``` -If some sporadic error happens (e.g., Sonatype timeout), rerun `sonatypeBundleRelease` again. +If some sporadic error happens (e.g., Sonatype timeout), rerun `sonaRelease` again. ### Project Structure From 4e6458a23978c91c74ffa843e7692b5e75b40b3a Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 10:45:17 -0700 Subject: [PATCH 177/195] Skip CI tests for non-code changes using dorny/paths-filter (#901) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add dorny/paths-filter action to detect file changes - Skip code format and test jobs when only docs are changed - Improve CI efficiency by running tests only when needed 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- .github/workflows/CI.yml | 43 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 31f824e4..11c3501b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -2,27 +2,42 @@ name: CI on: pull_request: - paths: - - '**.scala' - - '**.java' - - '**.sbt' - - '.github/workflows/**.yml' - - 'project/build.properties' push: branches: - main - paths: - - '**.scala' - - '**.java' - - '**.sbt' - - '.github/workflows/**.yml' - - 'project/build.properties' - workflow_dispatch: + workflow_dispatch: jobs: + changes: + runs-on: ubuntu-latest + outputs: + code: ${{ steps.changes.outputs.code }} + docs: ${{ steps.changes.outputs.docs }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: changes + with: + filters: | + code: + - '**.scala' + - '**.java' + - '**.sbt' + - '.github/workflows/**.yml' + - 'project/build.properties' + - 'msgpack-core/**' + - 'msgpack-jackson/**' + docs: + - '**.md' + - '**.txt' + - 'LICENSE' + code_format: name: Code Format runs-on: ubuntu-latest + needs: changes + if: ${{ needs.changes.outputs.code == 'true' }} steps: - uses: actions/checkout@v4 - name: jcheckstyle @@ -31,6 +46,8 @@ jobs: test: name: Test JDK${{ matrix.java }} runs-on: ubuntu-latest + needs: changes + if: ${{ needs.changes.outputs.code == 'true' }} strategy: matrix: java: ['8', '11', '17', '21', '24'] From a08b9eb295c6fdfd203bb8346a3f4b955df3dfd1 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sat, 19 Jul 2025 19:58:41 +0200 Subject: [PATCH 178/195] Update jackson-databind to 2.18.4 (#886) * Update jackson-databind to 2.18.4 * Update build.sbt --------- Co-authored-by: Taro L. Saito --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3d6ba320..135145fd 100644 --- a/build.sbt +++ b/build.sbt @@ -133,7 +133,7 @@ lazy val msgpackJackson = "org.msgpack.jackson.dataformat" ), libraryDependencies ++= Seq( - "com.fasterxml.jackson.core" % "jackson-databind" % "2.18.2", + "com.fasterxml.jackson.core" % "jackson-databind" % "2.18.4", junitJupiter, junitVintage, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" From 3021550c18f65985db7ea2e0fd12339d0c75fd1e Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 11:02:02 -0700 Subject: [PATCH 179/195] Add scalafmtCheckAll to code format CI (#902) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures Scala code formatting is validated in CI alongside Java checkstyle. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- .github/workflows/CI.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 11c3501b..4c49c411 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -42,6 +42,8 @@ jobs: - uses: actions/checkout@v4 - name: jcheckstyle run: ./sbt jcheckStyle + - name: scalafmtCheckAll + run: ./sbt scalafmtCheckAll test: name: Test JDK${{ matrix.java }} From 799e2d188b13b07704d1708d4e10283fe6dfdc8f Mon Sep 17 00:00:00 2001 From: "Taro L. Saito" Date: Sat, 19 Jul 2025 12:40:06 -0700 Subject: [PATCH 180/195] Fix Jackson deprecation warnings in MessagePackFactory (#903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Jackson deprecation warnings in MessagePackFactory Replace deprecated _createContext(Object, boolean) calls with _createContext(ContentReference, boolean) to eliminate warnings when running tests with Jackson 2.18.4. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Fix Jackson deprecation warnings in MessagePackParserTest Replace deprecated JsonParser methods with their current equivalents: - getCurrentName() → currentName() - getTokenLocation() → currentTokenLocation() - getCurrentLocation() → currentLocation() 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Fix all remaining Jackson deprecation warnings - Replace deprecated ParserMinimalBase constructor with StreamReadConstraints - Add non-deprecated location methods (currentTokenLocation, currentLocation) - Update GeneratorBase constructor to use 4-parameter form with IOContext and JsonWriteContext - Add new createKeySerializer method signature for Jackson 2.18 - Keep deprecated methods for backward compatibility All tests pass and Jackson deprecation warnings are eliminated. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --------- Co-authored-by: Claude --- .../dataformat/MessagePackFactory.java | 5 ++- .../dataformat/MessagePackGenerator.java | 10 ++++- .../jackson/dataformat/MessagePackParser.java | 21 ++++++++-- .../MessagePackSerializerFactory.java | 9 +++++ .../dataformat/MessagePackParserTest.java | 38 +++++++++---------- 5 files changed, 57 insertions(+), 26 deletions(-) diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index dbd2a465..865c0cf4 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.io.ContentReference; import com.fasterxml.jackson.core.io.IOContext; import org.msgpack.core.MessagePack; import org.msgpack.core.annotations.VisibleForTesting; @@ -111,7 +112,7 @@ public JsonGenerator createGenerator(Writer w) public JsonParser createParser(byte[] data) throws IOException { - IOContext ioContext = _createContext(data, false); + IOContext ioContext = _createContext(ContentReference.rawReference(data), false); return _createParser(data, 0, data.length, ioContext); } @@ -119,7 +120,7 @@ public JsonParser createParser(byte[] data) public JsonParser createParser(InputStream in) throws IOException { - IOContext ioContext = _createContext(in, false); + IOContext ioContext = _createContext(ContentReference.rawReference(in), false); return _createParser(in, ioContext); } diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java index abb5089e..3dde5604 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackGenerator.java @@ -19,7 +19,11 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.SerializableString; import com.fasterxml.jackson.core.base.GeneratorBase; +import com.fasterxml.jackson.core.io.ContentReference; +import com.fasterxml.jackson.core.io.IOContext; import com.fasterxml.jackson.core.io.SerializedString; +import com.fasterxml.jackson.core.json.JsonWriteContext; +import com.fasterxml.jackson.core.util.BufferRecycler; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.annotations.Nullable; @@ -185,6 +189,7 @@ else if (value instanceof NodeArray) { } // This is an internal constructor for nested serialization. + @SuppressWarnings("deprecation") private MessagePackGenerator( int features, ObjectCodec codec, @@ -192,7 +197,7 @@ private MessagePackGenerator( MessagePack.PackerConfig packerConfig, boolean supportIntegerKeys) { - super(features, codec); + super(features, codec, new IOContext(new BufferRecycler(), ContentReference.rawReference(out), false), JsonWriteContext.createRootContext(null)); this.output = out; this.messagePacker = packerConfig.newPacker(out); this.packerConfig = packerConfig; @@ -200,6 +205,7 @@ private MessagePackGenerator( this.supportIntegerKeys = supportIntegerKeys; } + @SuppressWarnings("deprecation") public MessagePackGenerator( int features, ObjectCodec codec, @@ -209,7 +215,7 @@ public MessagePackGenerator( boolean supportIntegerKeys) throws IOException { - super(features, codec); + super(features, codec, new IOContext(new BufferRecycler(), ContentReference.rawReference(out), false), JsonWriteContext.createRootContext(null)); this.output = out; this.messagePacker = packerConfig.newPacker(getMessageBufferOutputForOutputStream(out, reuseResourceInGenerator)); this.packerConfig = packerConfig; diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index e59b7f57..72aeed20 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -106,7 +106,7 @@ private MessagePackParser(IOContext ctxt, boolean reuseResourceInParser) throws IOException { - super(features); + super(features, ctxt.streamReadConstraints()); this.codec = objectCodec; ioContext = ctxt; @@ -583,15 +583,29 @@ public JsonStreamContext getParsingContext() } @Override + public JsonLocation currentTokenLocation() + { + return new JsonLocation(ioContext.contentReference(), tokenPosition, -1, -1); + } + + @Override + public JsonLocation currentLocation() + { + return new JsonLocation(ioContext.contentReference(), currentPosition, -1, -1); + } + + @Override + @Deprecated public JsonLocation getTokenLocation() { - return new JsonLocation(ioContext.getSourceReference(), tokenPosition, -1, -1, (int) tokenPosition); + return currentTokenLocation(); } @Override + @Deprecated public JsonLocation getCurrentLocation() { - return new JsonLocation(ioContext.getSourceReference(), currentPosition, -1, -1, (int) currentPosition); + return currentLocation(); } @Override @@ -627,6 +641,7 @@ public boolean isCurrentFieldId() } @Override + @Deprecated public String getCurrentName() throws IOException { diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializerFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializerFactory.java index fa2148dc..4100ef4c 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializerFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackSerializerFactory.java @@ -16,8 +16,10 @@ package org.msgpack.jackson.dataformat; import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig; import com.fasterxml.jackson.databind.ser.BeanSerializerFactory; @@ -43,6 +45,13 @@ public MessagePackSerializerFactory(SerializerFactoryConfig config) } @Override + public JsonSerializer createKeySerializer(SerializerProvider prov, JavaType keyType, JsonSerializer defaultImpl) throws JsonMappingException + { + return new MessagePackKeySerializer(); + } + + @Override + @Deprecated public JsonSerializer createKeySerializer(SerializationConfig config, JavaType keyType, JsonSerializer defaultImpl) { return new MessagePackKeySerializer(); diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java index c0bab053..256c4332 100644 --- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java +++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java @@ -317,43 +317,43 @@ public void testMessagePackParserDirectly() JsonToken jsonToken = parser.nextToken(); assertEquals(JsonToken.START_OBJECT, jsonToken); - assertEquals(-1, parser.getTokenLocation().getLineNr()); - assertEquals(0, parser.getTokenLocation().getColumnNr()); - assertEquals(-1, parser.getCurrentLocation().getLineNr()); - assertEquals(1, parser.getCurrentLocation().getColumnNr()); + assertEquals(-1, parser.currentTokenLocation().getLineNr()); + assertEquals(0, parser.currentTokenLocation().getColumnNr()); + assertEquals(-1, parser.currentLocation().getLineNr()); + assertEquals(1, parser.currentLocation().getColumnNr()); jsonToken = parser.nextToken(); assertEquals(JsonToken.FIELD_NAME, jsonToken); - assertEquals("zero", parser.getCurrentName()); - assertEquals(1, parser.getTokenLocation().getColumnNr()); - assertEquals(6, parser.getCurrentLocation().getColumnNr()); + assertEquals("zero", parser.currentName()); + assertEquals(1, parser.currentTokenLocation().getColumnNr()); + assertEquals(6, parser.currentLocation().getColumnNr()); jsonToken = parser.nextToken(); assertEquals(JsonToken.VALUE_NUMBER_INT, jsonToken); assertEquals(0, parser.getIntValue()); - assertEquals(6, parser.getTokenLocation().getColumnNr()); - assertEquals(7, parser.getCurrentLocation().getColumnNr()); + assertEquals(6, parser.currentTokenLocation().getColumnNr()); + assertEquals(7, parser.currentLocation().getColumnNr()); jsonToken = parser.nextToken(); assertEquals(JsonToken.FIELD_NAME, jsonToken); - assertEquals("one", parser.getCurrentName()); - assertEquals(7, parser.getTokenLocation().getColumnNr()); - assertEquals(11, parser.getCurrentLocation().getColumnNr()); + assertEquals("one", parser.currentName()); + assertEquals(7, parser.currentTokenLocation().getColumnNr()); + assertEquals(11, parser.currentLocation().getColumnNr()); parser.overrideCurrentName("two"); - assertEquals("two", parser.getCurrentName()); + assertEquals("two", parser.currentName()); jsonToken = parser.nextToken(); assertEquals(JsonToken.VALUE_NUMBER_FLOAT, jsonToken); assertEquals(1.0f, parser.getIntValue(), 0.001f); - assertEquals(11, parser.getTokenLocation().getColumnNr()); - assertEquals(16, parser.getCurrentLocation().getColumnNr()); + assertEquals(11, parser.currentTokenLocation().getColumnNr()); + assertEquals(16, parser.currentLocation().getColumnNr()); jsonToken = parser.nextToken(); assertEquals(JsonToken.END_OBJECT, jsonToken); - assertEquals(-1, parser.getTokenLocation().getLineNr()); - assertEquals(16, parser.getTokenLocation().getColumnNr()); - assertEquals(-1, parser.getCurrentLocation().getLineNr()); - assertEquals(16, parser.getCurrentLocation().getColumnNr()); + assertEquals(-1, parser.currentTokenLocation().getLineNr()); + assertEquals(16, parser.currentTokenLocation().getColumnNr()); + assertEquals(-1, parser.currentLocation().getLineNr()); + assertEquals(16, parser.currentLocation().getColumnNr()); parser.close(); parser.close(); // Intentional From 34c1d590ad1cbebd234415de6f01460ee03aa5cb Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 25 Aug 2025 20:10:06 +0200 Subject: [PATCH 181/195] Update sbt, scripted-plugin to 1.11.4 (#910) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 138bc7a5..aced3065 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.11.3 +sbt.version=1.11.4 From d8d81aa32c3ac92849291c14bd1000b2fc6bb275 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:10:15 -0700 Subject: [PATCH 182/195] Bump actions/checkout from 4 to 5 (#909) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 6 +++--- .github/workflows/release.yml | 2 +- .github/workflows/snapshot.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4c49c411..a61fb3fa 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,7 +15,7 @@ jobs: docs: ${{ steps.changes.outputs.docs }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - uses: dorny/paths-filter@v3 id: changes with: @@ -39,7 +39,7 @@ jobs: needs: changes if: ${{ needs.changes.outputs.code == 'true' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: jcheckstyle run: ./sbt jcheckStyle - name: scalafmtCheckAll @@ -54,7 +54,7 @@ jobs: matrix: java: ['8', '11', '17', '21', '24'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-java@v4 with: distribution: 'zulu' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3dca7c2..6d1aa99f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: name: Release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 4cc85866..eac8cfbb 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -16,7 +16,7 @@ jobs: name: Publish snapshots runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version From 75482c5aec6bfafad7e17ce4e75c7abff682eec8 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 25 Aug 2025 20:10:50 +0200 Subject: [PATCH 183/195] Update airframe-json, airspec to 2025.1.16 (#912) --- build.sbt | 184 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 107 insertions(+), 77 deletions(-) diff --git a/build.sbt b/build.sbt index 135145fd..547e1ebe 100644 --- a/build.sbt +++ b/build.sbt @@ -1,11 +1,9 @@ Global / onChangedBuildSource := ReloadOnSourceChanges // For performance testing, ensure each test run one-by-one -Global / concurrentRestrictions := Seq( - Tags.limit(Tags.Test, 1) -) +Global / concurrentRestrictions := Seq(Tags.limit(Tags.Test, 1)) -val AIRFRAME_VERSION = "2025.1.14" +val AIRFRAME_VERSION = "2025.1.16" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true @@ -15,37 +13,65 @@ ThisBuild / dynverSeparator := "-" // Publishing metadata ThisBuild / homepage := Some(url("https://msgpack.org/")) ThisBuild / licenses := Seq("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")) -ThisBuild / scmInfo := Some( - ScmInfo( - url("https://github.com/msgpack/msgpack-java"), - "scm:git@github.com:msgpack/msgpack-java.git" +ThisBuild / scmInfo := + Some( + ScmInfo( + url("https://github.com/msgpack/msgpack-java"), + "scm:git@github.com:msgpack/msgpack-java.git" + ) ) -) -ThisBuild / developers := List( - Developer(id = "frsyuki", name = "Sadayuki Furuhashi", email = "frsyuki@users.sourceforge.jp", url = url("https://github.com/frsyuki")), - Developer(id = "muga", name = "Muga Nishizawa", email = "muga.nishizawa@gmail.com", url = url("https://github.com/muga")), - Developer(id = "oza", name = "Tsuyoshi Ozawa", email = "ozawa.tsuyoshi@gmail.com", url = url("https://github.com/oza")), - Developer(id = "komamitsu", name = "Mitsunori Komatsu", email = "komamitsu@gmail.com", url = url("https://github.com/komamitsu")), - Developer(id = "xerial", name = "Taro L. Saito", email = "leo@xerial.org", url = url("https://github.com/xerial")) -) +ThisBuild / developers := + List( + Developer( + id = "frsyuki", + name = "Sadayuki Furuhashi", + email = "frsyuki@users.sourceforge.jp", + url = url("https://github.com/frsyuki") + ), + Developer( + id = "muga", + name = "Muga Nishizawa", + email = "muga.nishizawa@gmail.com", + url = url("https://github.com/muga") + ), + Developer( + id = "oza", + name = "Tsuyoshi Ozawa", + email = "ozawa.tsuyoshi@gmail.com", + url = url("https://github.com/oza") + ), + Developer( + id = "komamitsu", + name = "Mitsunori Komatsu", + email = "komamitsu@gmail.com", + url = url("https://github.com/komamitsu") + ), + Developer( + id = "xerial", + name = "Taro L. Saito", + email = "leo@xerial.org", + url = url("https://github.com/xerial") + ) + ) -val buildSettings = Seq[Setting[_]]( - organization := "org.msgpack", - organizationName := "MessagePack", +val buildSettings = Seq[Setting[?]]( + organization := "org.msgpack", + organizationName := "MessagePack", organizationHomepage := Some(url("http://msgpack.org/")), - description := "MessagePack for Java", - scalaVersion := "3.7.1", - Test / logBuffered := false, + description := "MessagePack for Java", + scalaVersion := "3.7.1", + Test / logBuffered := false, // msgpack-java should be a pure-java library, so remove Scala specific configurations - autoScalaLibrary := false, - crossPaths := false, + autoScalaLibrary := false, + crossPaths := false, publishMavenStyle := true, // JVM options for building scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-feature"), Test / javaOptions ++= Seq("-ea"), javacOptions ++= Seq("-source", "1.8", "-target", "1.8"), - Compile / compile / javacOptions ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation"), + Compile / compile / javacOptions ++= + Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation"), // Use lenient validation mode when generating Javadoc (for Java8) doc / javacOptions := { val opts = Seq("-source", "1.8") @@ -58,17 +84,21 @@ val buildSettings = Seq[Setting[_]]( // Add sonatype repository settings publishTo := { val centralSnapshots = "https://central.sonatype.com/repository/maven-snapshots/" - if (isSnapshot.value) Some("central-snapshots" at centralSnapshots) - else localStaging.value + if (isSnapshot.value) + Some("central-snapshots" at centralSnapshots) + else + localStaging.value }, // Style check config: (sbt-jchekcstyle) jcheckStyleConfig := "facebook", // Run jcheckstyle both for main and test codes - Compile / compile := ((Compile / compile) dependsOn (Compile / jcheckStyle)).value, - Test / compile := ((Test / compile) dependsOn (Test / jcheckStyle)).value + Compile / compile := + ((Compile / compile) dependsOn (Compile / jcheckStyle)).value, + Test / compile := + ((Test / compile) dependsOn (Test / jcheckStyle)).value ) -val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.11.4" % "test" +val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.11.4" % "test" val junitVintage = "org.junit.vintage" % "junit-vintage-engine" % "5.11.4" % "test" // Project settings @@ -77,8 +107,8 @@ lazy val root = Project(id = "msgpack-java", base = file(".")) buildSettings, // Do not publish the root project publishArtifact := false, - publish := {}, - publishLocal := {} + publish := {}, + publishLocal := {} ) .aggregate(msgpackCore, msgpackJackson) @@ -86,58 +116,58 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) .enablePlugins(SbtOsgi) .settings( buildSettings, - description := "Core library of the MessagePack for Java", + description := "Core library of the MessagePack for Java", OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-core", - OsgiKeys.exportPackage := Seq( - // TODO enumerate used packages automatically - "org.msgpack.core", - "org.msgpack.core.annotations", - "org.msgpack.core.buffer", - "org.msgpack.value", - "org.msgpack.value.impl" - ), + OsgiKeys.exportPackage := + Seq( + // TODO enumerate used packages automatically + "org.msgpack.core", + "org.msgpack.core.annotations", + "org.msgpack.core.buffer", + "org.msgpack.value", + "org.msgpack.value.impl" + ), testFrameworks += new TestFramework("wvlet.airspec.Framework"), - Test / javaOptions ++= Seq( - // --add-opens is not available in JDK8 - "-XX:+IgnoreUnrecognizedVMOptions", - "--add-opens=java.base/java.nio=ALL-UNNAMED", - "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" - ), + Test / javaOptions ++= + Seq( + // --add-opens is not available in JDK8 + "-XX:+IgnoreUnrecognizedVMOptions", + "--add-opens=java.base/java.nio=ALL-UNNAMED", + "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" + ), Test / fork := true, - libraryDependencies ++= Seq( - // msgpack-core should have no external dependencies - junitJupiter, - junitVintage, - "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", - "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", - // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.18.1" % "test", - // For performance comparison with msgpack v6 - "org.msgpack" % "msgpack" % "0.6.12" % "test", - // For integration test with Akka - "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0" % "test" - ) + libraryDependencies ++= + Seq( + // msgpack-core should have no external dependencies + junitJupiter, + junitVintage, + "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", + "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", + // Add property testing support with forAll methods + "org.scalacheck" %% "scalacheck" % "1.18.1" % "test", + // For performance comparison with msgpack v6 + "org.msgpack" % "msgpack" % "0.6.12" % "test", + // For integration test with Akka + "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", + "org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0" % "test" + ) ) -lazy val msgpackJackson = - Project(id = "msgpack-jackson", base = file("msgpack-jackson")) - .enablePlugins(SbtOsgi) - .settings( - buildSettings, - name := "jackson-dataformat-msgpack", - description := "Jackson extension that adds support for MessagePack", - OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-jackson", - OsgiKeys.exportPackage := Seq( - "org.msgpack.jackson", - "org.msgpack.jackson.dataformat" - ), - libraryDependencies ++= Seq( +lazy val msgpackJackson = Project(id = "msgpack-jackson", base = file("msgpack-jackson")) + .enablePlugins(SbtOsgi) + .settings( + buildSettings, + name := "jackson-dataformat-msgpack", + description := "Jackson extension that adds support for MessagePack", + OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-jackson", + OsgiKeys.exportPackage := Seq("org.msgpack.jackson", "org.msgpack.jackson.dataformat"), + libraryDependencies ++= + Seq( "com.fasterxml.jackson.core" % "jackson-databind" % "2.18.4", junitJupiter, junitVintage, "org.apache.commons" % "commons-math3" % "3.6.1" % "test" ), - testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") - ) - .dependsOn(msgpackCore) + testOptions += Tests.Argument(TestFrameworks.JUnit, "-v") + ) + .dependsOn(msgpackCore) From 12062270a5ee2a0c754a11cef4b0a03e0f0078e9 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 25 Aug 2025 20:11:04 +0200 Subject: [PATCH 184/195] Update scalafmt-core to 3.9.9 (#907) * Update scalafmt-core to 3.9.9 * Reformat with scalafmt 3.9.9 Executed command: scalafmt --non-interactive * Add 'Reformat with scalafmt 3.9.9' to .git-blame-ignore-revs --- .git-blame-ignore-revs | 2 ++ .scalafmt.conf | 2 +- project/plugins.sbt | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..285ed6f4 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Scala Steward: Reformat with scalafmt 3.9.9 +424ec59eb4865feb383ca53b4278dfb8b9b6c36c diff --git a/.scalafmt.conf b/.scalafmt.conf index e8563baf..a4b995aa 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 3.9.8 +version = 3.9.9 project.layout = StandardConvention runner.dialect = scala3 maxColumn = 100 diff --git a/project/plugins.sbt b/project/plugins.sbt index 5bc49937..18f414ea 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,10 +1,10 @@ -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") // TODO: Fixes jacoco error: // java.lang.NoClassDefFoundError: Could not initialize class org.jacoco.core.internal.flow.ClassProbesAdapter //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") -addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") +addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5") -addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.1") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5") +addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.1") scalacOptions ++= Seq("-deprecation", "-feature") From e93fb75eed2d8ca6e41993d4dad3f9c68d33be29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 Aug 2025 18:24:48 -0700 Subject: [PATCH 185/195] Bump actions/setup-java from 4 to 5 (#914) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/snapshot.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a61fb3fa..091ca0de 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -55,7 +55,7 @@ jobs: java: ['8', '11', '17', '21', '24'] steps: - uses: actions/checkout@v5 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version: ${{ matrix.java }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d1aa99f..16adf80f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: # Fetch all tags so that sbt-dynver can find the previous release version - run: git fetch --tags -f # Install OpenJDK 8 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: # We need to use JDK8 for Android compatibility https://github.com/msgpack/msgpack-java/issues/516 java-version: 8 diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index eac8cfbb..749e6175 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -21,7 +21,7 @@ jobs: fetch-depth: 10000 # Fetch all tags so that sbt-dynver can find the previous release version - run: git fetch --tags - - uses: actions/setup-java@v4 + - uses: actions/setup-java@v5 with: java-version: 11 distribution: adopt From be6f0160119eb1214449e7b8470c162df39193dc Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Sun, 31 Aug 2025 03:24:57 +0200 Subject: [PATCH 186/195] Update sbt, scripted-plugin to 1.11.5 (#913) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index aced3065..d05ee025 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.11.4 +sbt.version=1.11.5 From cab44596bf6ebe3b74198897cc77e5e7ed91bccb Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 1 Sep 2025 23:16:30 +0200 Subject: [PATCH 187/195] Update junit-jupiter to 5.13.4 (#905) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 547e1ebe..143ef7e1 100644 --- a/build.sbt +++ b/build.sbt @@ -98,7 +98,7 @@ val buildSettings = Seq[Setting[?]]( ((Test / compile) dependsOn (Test / jcheckStyle)).value ) -val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.11.4" % "test" +val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.13.4" % "test" val junitVintage = "org.junit.vintage" % "junit-vintage-engine" % "5.11.4" % "test" // Project settings From 17dc837745ef3be60aa3f37b44230ce92fffd5e4 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:18:08 +0200 Subject: [PATCH 188/195] Update sbt, scripted-plugin to 1.11.6 (#918) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index d05ee025..73840fdd 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.11.5 +sbt.version=1.11.6 From 06cf66d77ba85ef4ad76e7a65da4b6d6b2672bbd Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:18:17 +0200 Subject: [PATCH 189/195] Update airframe-json, airspec to 2025.1.18 (#920) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 143ef7e1..5e89ef1e 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ Global / onChangedBuildSource := ReloadOnSourceChanges // For performance testing, ensure each test run one-by-one Global / concurrentRestrictions := Seq(Tags.limit(Tags.Test, 1)) -val AIRFRAME_VERSION = "2025.1.16" +val AIRFRAME_VERSION = "2025.1.18" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From 918a396fcde16987abc8a26edb126248c868c9aa Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:18:36 +0200 Subject: [PATCH 190/195] Update scalacheck to 1.19.0 (#919) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5e89ef1e..3f8c9813 100644 --- a/build.sbt +++ b/build.sbt @@ -144,7 +144,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test", "org.wvlet.airframe" %% "airspec" % AIRFRAME_VERSION % "test", // Add property testing support with forAll methods - "org.scalacheck" %% "scalacheck" % "1.18.1" % "test", + "org.scalacheck" %% "scalacheck" % "1.19.0" % "test", // For performance comparison with msgpack v6 "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka From a7a54ea6ed5710391f6f4222189690b0cc630103 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:47:13 +0100 Subject: [PATCH 191/195] Update sbt-scalafmt to 2.5.6 (#932) --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 18f414ea..a7594c7a 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") //addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") addSbtPlugin("org.xerial.sbt" % "sbt-jcheckstyle" % "0.2.1") addSbtPlugin("com.github.sbt" % "sbt-osgi" % "0.10.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.6") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.1") scalacOptions ++= Seq("-deprecation", "-feature") From 78e5b7e2cb3d50e86e276e771e5fc9f794f8240f Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:47:24 +0100 Subject: [PATCH 192/195] Update airframe-json, airspec to 2025.1.21 (#929) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3f8c9813..6e3d753d 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ Global / onChangedBuildSource := ReloadOnSourceChanges // For performance testing, ensure each test run one-by-one Global / concurrentRestrictions := Seq(Tags.limit(Tags.Test, 1)) -val AIRFRAME_VERSION = "2025.1.18" +val AIRFRAME_VERSION = "2025.1.21" // Use dynamic snapshot version strings for non tagged versions ThisBuild / dynverSonatypeSnapshots := true From bfa9fd4674a3f7e92922debbf1cc04c3670243c9 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:48:12 +0100 Subject: [PATCH 193/195] Update scala-collection-compat to 2.14.0 (#926) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6e3d753d..d70268a0 100644 --- a/build.sbt +++ b/build.sbt @@ -149,7 +149,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core")) "org.msgpack" % "msgpack" % "0.6.12" % "test", // For integration test with Akka "com.typesafe.akka" %% "akka-actor" % "2.6.20" % "test", - "org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0" % "test" + "org.scala-lang.modules" %% "scala-collection-compat" % "2.14.0" % "test" ) ) From f6427b4aa757aba58fd6f9788a3db0b789342e52 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:48:23 +0100 Subject: [PATCH 194/195] Update sbt, scripted-plugin to 1.11.7 (#925) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 73840fdd..b1b10405 100755 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ -sbt.version=1.11.6 +sbt.version=1.11.7 From 81a9f0d80c81a24229a2641075a9e802c0843ec2 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:49:33 +0100 Subject: [PATCH 195/195] Update junit-jupiter to 5.14.1 (#930) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index d70268a0..f8600c56 100644 --- a/build.sbt +++ b/build.sbt @@ -98,7 +98,7 @@ val buildSettings = Seq[Setting[?]]( ((Test / compile) dependsOn (Test / jcheckStyle)).value ) -val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.13.4" % "test" +val junitJupiter = "org.junit.jupiter" % "junit-jupiter" % "5.14.1" % "test" val junitVintage = "org.junit.vintage" % "junit-vintage-engine" % "5.11.4" % "test" // Project settings