jackson 2.18 with max-token-count support (#1556)

* jackson 2.18.1 with max-token-count support

* Update Dependencies.scala

* remove lock-free buffer-recycler

* add non-recycling pool

* Update Dependencies.scala
This commit is contained in:
PJ Fanning 2024-12-28 14:01:10 +01:00 committed by GitHub
parent 2cd8313bf5
commit aea4e836e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 15 additions and 9 deletions

View file

@ -1,5 +1,6 @@
updates.pin = [ updates.pin = [
{ groupId = "com.fasterxml.jackson.core", version = "2.17." } # Jackson upgrades can be complicated to coordinate across modules - it is better to upgrade manually
{ groupId = "com.fasterxml.jackson.core", version = "2.18." }
# Pin logback to v1.3.x because v1.4.x needs JDK11 # Pin logback to v1.3.x because v1.4.x needs JDK11
{ groupId = "ch.qos.logback", version="1.3." } { groupId = "ch.qos.logback", version="1.3." }
# Pin sbt-paradox to v0.9.x because 0.10.x needs JDK 11 # Pin sbt-paradox to v0.9.x because 0.10.x needs JDK 11

View file

@ -38,7 +38,7 @@ object Dependencies {
val nettyVersion = "4.1.116.Final" val nettyVersion = "4.1.116.Final"
val logbackVersion = "1.3.14" val logbackVersion = "1.3.14"
val jacksonCoreVersion = "2.17.3" val jacksonCoreVersion = "2.18.2"
val jacksonDatabindVersion = jacksonCoreVersion val jacksonDatabindVersion = jacksonCoreVersion
val scala212Version = "2.12.20" val scala212Version = "2.12.20"
@ -106,7 +106,8 @@ object Dependencies {
val jacksonDatabind = "com.fasterxml.jackson.core" % "jackson-databind" % jacksonDatabindVersion val jacksonDatabind = "com.fasterxml.jackson.core" % "jackson-databind" % jacksonDatabindVersion
val jacksonJdk8 = "com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % jacksonCoreVersion val jacksonJdk8 = "com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % jacksonCoreVersion
val jacksonJsr310 = "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % jacksonCoreVersion val jacksonJsr310 = "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % jacksonCoreVersion
val jacksonScala = "com.fasterxml.jackson.module" %% "jackson-module-scala" % jacksonCoreVersion val jacksonScala = ("com.fasterxml.jackson.module" %% "jackson-module-scala" % jacksonCoreVersion)
.excludeAll(ExclusionRule(organization = "org.scala-lang"))
val jacksonParameterNames = "com.fasterxml.jackson.module" % "jackson-module-parameter-names" % jacksonCoreVersion val jacksonParameterNames = "com.fasterxml.jackson.module" % "jackson-module-parameter-names" % jacksonCoreVersion
val jacksonCbor = "com.fasterxml.jackson.dataformat" % "jackson-dataformat-cbor" % jacksonCoreVersion val jacksonCbor = "com.fasterxml.jackson.dataformat" % "jackson-dataformat-cbor" % jacksonCoreVersion
val lz4Java = "org.lz4" % "lz4-java" % "1.8.0" val lz4Java = "org.lz4" % "lz4-java" % "1.8.0"

View file

@ -36,11 +36,10 @@ pekko.serialization.jackson {
} }
# Controls the Buffer Recycler Pool implementation used by Jackson. # Controls the Buffer Recycler Pool implementation used by Jackson.
# https://javadoc.io/static/com.fasterxml.jackson.core/jackson-core/2.17.1/com/fasterxml/jackson/core/util/JsonRecyclerPools.html # https://javadoc.io/static/com.fasterxml.jackson.core/jackson-core/2.18.1/com/fasterxml/jackson/core/util/JsonRecyclerPools.html
# The default is "thread-local" which is the same as the default in Jackson 2.16. # The default is "thread-local" which is the same as the default in Jackson 2.18.
buffer-recycler { buffer-recycler {
# the supported values are "thread-local", "lock-free", "shared-lock-free", "concurrent-deque", # the supported values are "thread-local", "concurrent-deque", "shared-concurrent-deque", "bounded", "non-recycling"
# "shared-concurrent-deque", "bounded"
pool-instance = "thread-local" pool-instance = "thread-local"
# the maximum size of bounded recycler pools - must be >=1 or an IllegalArgumentException will occur # the maximum size of bounded recycler pools - must be >=1 or an IllegalArgumentException will occur
# only applies to pool-instance type "bounded" # only applies to pool-instance type "bounded"
@ -59,6 +58,8 @@ pekko.serialization.jackson {
max-name-length = 50000 max-name-length = 50000
# max-document-length of -1 means unlimited # max-document-length of -1 means unlimited
max-document-length = -1 max-document-length = -1
# max-token-count of -1 means unlimited
max-token-count = -1
} }
write { write {

View file

@ -90,6 +90,7 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
.maxStringLength(config.getInt("read.max-string-length")) .maxStringLength(config.getInt("read.max-string-length"))
.maxNameLength(config.getInt("read.max-name-length")) .maxNameLength(config.getInt("read.max-name-length"))
.maxDocumentLength(config.getLong("read.max-document-length")) .maxDocumentLength(config.getLong("read.max-document-length"))
.maxTokenCount(config.getLong("read.max-token-count"))
.build() .build()
val streamWriteConstraints = StreamWriteConstraints.builder() val streamWriteConstraints = StreamWriteConstraints.builder()
@ -159,11 +160,10 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
private def getBufferRecyclerPool(cfg: Config): RecyclerPool[BufferRecycler] = { private def getBufferRecyclerPool(cfg: Config): RecyclerPool[BufferRecycler] = {
cfg.getString("buffer-recycler.pool-instance") match { cfg.getString("buffer-recycler.pool-instance") match {
case "thread-local" => JsonRecyclerPools.threadLocalPool() case "thread-local" => JsonRecyclerPools.threadLocalPool()
case "lock-free" => JsonRecyclerPools.newLockFreePool()
case "shared-lock-free" => JsonRecyclerPools.sharedLockFreePool()
case "concurrent-deque" => JsonRecyclerPools.newConcurrentDequePool() case "concurrent-deque" => JsonRecyclerPools.newConcurrentDequePool()
case "shared-concurrent-deque" => JsonRecyclerPools.sharedConcurrentDequePool() case "shared-concurrent-deque" => JsonRecyclerPools.sharedConcurrentDequePool()
case "bounded" => JsonRecyclerPools.newBoundedPool(cfg.getInt("buffer-recycler.bounded-pool-size")) case "bounded" => JsonRecyclerPools.newBoundedPool(cfg.getInt("buffer-recycler.bounded-pool-size"))
case "non-recycling" => JsonRecyclerPools.nonRecyclingPool()
case other => throw new IllegalArgumentException(s"Unknown recycler-pool: $other") case other => throw new IllegalArgumentException(s"Unknown recycler-pool: $other")
} }
} }

View file

@ -45,11 +45,13 @@ class JacksonFactorySpec extends TestKit(ActorSystem("JacksonFactorySpec"))
val maxStringLen = 1234567 val maxStringLen = 1234567
val maxDocLen = 123456789L val maxDocLen = 123456789L
val maxNestingDepth = 5 val maxNestingDepth = 5
val maxTokenCount = 9876543210L
val config = ConfigFactory.parseString( val config = ConfigFactory.parseString(
s"""pekko.serialization.jackson.read.max-number-length=$maxNumLen s"""pekko.serialization.jackson.read.max-number-length=$maxNumLen
|pekko.serialization.jackson.read.max-string-length=$maxStringLen |pekko.serialization.jackson.read.max-string-length=$maxStringLen
|pekko.serialization.jackson.read.max-document-length=$maxDocLen |pekko.serialization.jackson.read.max-document-length=$maxDocLen
|pekko.serialization.jackson.read.max-nesting-depth=$maxNestingDepth |pekko.serialization.jackson.read.max-nesting-depth=$maxNestingDepth
|pekko.serialization.jackson.read.max-token-count=$maxTokenCount
|""".stripMargin) |""".stripMargin)
.withFallback(defaultConfig) .withFallback(defaultConfig)
val jacksonConfig = JacksonObjectMapperProvider.configForBinding(bindingName, config) val jacksonConfig = JacksonObjectMapperProvider.configForBinding(bindingName, config)
@ -60,6 +62,7 @@ class JacksonFactorySpec extends TestKit(ActorSystem("JacksonFactorySpec"))
streamReadConstraints.getMaxStringLength shouldEqual maxStringLen streamReadConstraints.getMaxStringLength shouldEqual maxStringLen
streamReadConstraints.getMaxDocumentLength shouldEqual maxDocLen streamReadConstraints.getMaxDocumentLength shouldEqual maxDocLen
streamReadConstraints.getMaxNestingDepth shouldEqual maxNestingDepth streamReadConstraints.getMaxNestingDepth shouldEqual maxNestingDepth
streamReadConstraints.getMaxTokenCount shouldEqual maxTokenCount
} }
"support StreamWriteConstraints" in { "support StreamWriteConstraints" in {