jackson 2.16 support (#564)
* jackson 2.15 support * Update JacksonObjectMapperProvider.scala Update JacksonObjectMapperProvider.scala Update JacksonObjectMapperProvider.scala Update JacksonObjectMapperProvider.scala * jackson 2.15.3 * jackson 2.16 * Update reference.conf * add max-document-length * Update .scala-steward.conf * Update reference.conf * 2.16.1 * Create JacksonFactorySpec.scala * Update JacksonFactorySpec.scala * add blank line
This commit is contained in:
parent
f361cb2f59
commit
3f97d9fe04
5 changed files with 151 additions and 32 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
updates.pin = [
|
||||||
|
{ groupId = "com.fasterxml.jackson.core", version = "2.16." }
|
||||||
|
]
|
||||||
|
|
||||||
updates.ignore = [
|
updates.ignore = [
|
||||||
{ groupId = "org.scalameta", artifactId = "scalafmt-core" }
|
{ groupId = "org.scalameta", artifactId = "scalafmt-core" }
|
||||||
{ groupId = "org.scalameta", artifactId = "sbt-scalafmt" }
|
{ groupId = "org.scalameta", artifactId = "sbt-scalafmt" }
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ object Dependencies {
|
||||||
val protobufJavaVersion = "3.20.3"
|
val protobufJavaVersion = "3.20.3"
|
||||||
val logbackVersion = "1.3.14"
|
val logbackVersion = "1.3.14"
|
||||||
|
|
||||||
val jacksonCoreVersion = "2.14.3"
|
val jacksonCoreVersion = "2.16.1"
|
||||||
val jacksonDatabindVersion = jacksonCoreVersion
|
val jacksonDatabindVersion = jacksonCoreVersion
|
||||||
|
|
||||||
val scala212Version = "2.12.18"
|
val scala212Version = "2.12.18"
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,27 @@ pekko.serialization.jackson {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#//#stream-read-constraints
|
||||||
|
pekko.serialization.jackson {
|
||||||
|
read {
|
||||||
|
# see https://www.javadoc.io/static/com.fasterxml.jackson.core/jackson-core/2.16.1/com/fasterxml/jackson/core/StreamReadConstraints.html
|
||||||
|
# these defaults are the same as the defaults in `StreamReadConstraints`
|
||||||
|
max-nesting-depth = 1000
|
||||||
|
max-number-length = 1000
|
||||||
|
max-string-length = 20000000
|
||||||
|
max-name-length = 50000
|
||||||
|
# max-document-length of -1 means unlimited
|
||||||
|
max-document-length = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
write {
|
||||||
|
# see https://www.javadoc.io/static/com.fasterxml.jackson.core/jackson-core/2.16.1/com/fasterxml/jackson/core/StreamWriteConstraints.html
|
||||||
|
# these defaults are the same as the defaults in `StreamWriteConstraints`
|
||||||
|
max-nesting-depth = 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#//#stream-read-constraints
|
||||||
|
|
||||||
#//#features
|
#//#features
|
||||||
pekko.serialization.jackson {
|
pekko.serialization.jackson {
|
||||||
# Configuration of the ObjectMapper serialization features.
|
# Configuration of the ObjectMapper serialization features.
|
||||||
|
|
|
||||||
|
|
@ -17,40 +17,42 @@ import java.util.Optional
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import scala.annotation.nowarn
|
import scala.annotation.nowarn
|
||||||
import scala.collection.immutable
|
import scala.collection.immutable
|
||||||
import scala.util.Failure
|
import scala.util.{ Failure, Success }
|
||||||
import scala.util.Success
|
import com.fasterxml.jackson.annotation.{ JsonAutoDetect, JsonCreator, PropertyAccessor }
|
||||||
|
import com.fasterxml.jackson.core.{
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect
|
JsonFactory,
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator
|
JsonFactoryBuilder,
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor
|
JsonGenerator,
|
||||||
import com.fasterxml.jackson.core.JsonFactory
|
JsonParser,
|
||||||
import com.fasterxml.jackson.core.JsonFactoryBuilder
|
StreamReadConstraints,
|
||||||
import com.fasterxml.jackson.core.JsonGenerator
|
StreamReadFeature,
|
||||||
import com.fasterxml.jackson.core.JsonParser
|
StreamWriteConstraints,
|
||||||
import com.fasterxml.jackson.core.StreamReadFeature
|
StreamWriteFeature
|
||||||
import com.fasterxml.jackson.core.StreamWriteFeature
|
}
|
||||||
import com.fasterxml.jackson.core.json.JsonReadFeature
|
import com.fasterxml.jackson.core.json.{ JsonReadFeature, JsonWriteFeature }
|
||||||
import com.fasterxml.jackson.core.json.JsonWriteFeature
|
import com.fasterxml.jackson.databind.{
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
DeserializationFeature,
|
||||||
import com.fasterxml.jackson.databind.MapperFeature
|
MapperFeature,
|
||||||
import com.fasterxml.jackson.databind.Module
|
Module,
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
ObjectMapper,
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature
|
SerializationFeature
|
||||||
|
}
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule
|
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import org.apache.pekko
|
import org.apache.pekko
|
||||||
import pekko.actor.ActorSystem
|
import pekko.actor.{
|
||||||
import pekko.actor.ClassicActorSystemProvider
|
ActorSystem,
|
||||||
import pekko.actor.DynamicAccess
|
ClassicActorSystemProvider,
|
||||||
import pekko.actor.ExtendedActorSystem
|
DynamicAccess,
|
||||||
import pekko.actor.Extension
|
ExtendedActorSystem,
|
||||||
import pekko.actor.ExtensionId
|
Extension,
|
||||||
import pekko.actor.ExtensionIdProvider
|
ExtensionId,
|
||||||
|
ExtensionIdProvider
|
||||||
|
}
|
||||||
import pekko.actor.setup.Setup
|
import pekko.actor.setup.Setup
|
||||||
import pekko.annotation.InternalStableApi
|
import pekko.annotation.InternalStableApi
|
||||||
import pekko.event.Logging
|
import pekko.event.{ Logging, LoggingAdapter }
|
||||||
import pekko.event.LoggingAdapter
|
|
||||||
import pekko.util.unused
|
import pekko.util.unused
|
||||||
import pekko.util.OptionConverters._
|
import pekko.util.OptionConverters._
|
||||||
|
|
||||||
|
|
@ -68,7 +70,7 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
||||||
*/
|
*/
|
||||||
def configForBinding(bindingName: String, systemConfig: Config): Config = {
|
def configForBinding(bindingName: String, systemConfig: Config): Config = {
|
||||||
val basePath = "pekko.serialization.jackson"
|
val basePath = "pekko.serialization.jackson"
|
||||||
val baseConf = systemConfig.getConfig("pekko.serialization.jackson")
|
val baseConf = systemConfig.getConfig(basePath)
|
||||||
if (systemConfig.hasPath(s"$basePath.$bindingName"))
|
if (systemConfig.hasPath(s"$basePath.$bindingName"))
|
||||||
systemConfig.getConfig(s"$basePath.$bindingName").withFallback(baseConf)
|
systemConfig.getConfig(s"$basePath.$bindingName").withFallback(baseConf)
|
||||||
else
|
else
|
||||||
|
|
@ -81,15 +83,31 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
||||||
config: Config,
|
config: Config,
|
||||||
baseJsonFactory: Option[JsonFactory]): JsonFactory = {
|
baseJsonFactory: Option[JsonFactory]): JsonFactory = {
|
||||||
|
|
||||||
|
val streamReadConstraints = StreamReadConstraints.builder()
|
||||||
|
.maxNestingDepth(config.getInt("read.max-nesting-depth"))
|
||||||
|
.maxNumberLength(config.getInt("read.max-number-length"))
|
||||||
|
.maxStringLength(config.getInt("read.max-string-length"))
|
||||||
|
.maxNameLength(config.getInt("read.max-name-length"))
|
||||||
|
.maxDocumentLength(config.getLong("read.max-document-length"))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val streamWriteConstraints = StreamWriteConstraints.builder()
|
||||||
|
.maxNestingDepth(config.getInt("write.max-nesting-depth"))
|
||||||
|
.build()
|
||||||
|
|
||||||
val jsonFactory: JsonFactory = baseJsonFactory match {
|
val jsonFactory: JsonFactory = baseJsonFactory match {
|
||||||
case Some(factory) =>
|
case Some(factory) =>
|
||||||
// Issue #28918 not possible to use new JsonFactoryBuilder(jsonFactory) here.
|
// Issue #28918 not possible to use new JsonFactoryBuilder(jsonFactory) here.
|
||||||
// It doesn't preserve the formatParserFeatures and formatGeneratorFeatures in
|
// It doesn't preserve the formatParserFeatures and formatGeneratorFeatures in
|
||||||
// CBORFactor. Therefore we use JsonFactory and configure the features with mappedFeature
|
// CBORFactor. Therefore we use JsonFactory and configure the features with mappedFeature
|
||||||
// instead of using JsonFactoryBuilder (new in Jackson 2.10.0).
|
// instead of using JsonFactoryBuilder (new in Jackson 2.10.0).
|
||||||
factory
|
factory.setStreamReadConstraints(streamReadConstraints)
|
||||||
|
factory.setStreamWriteConstraints(streamWriteConstraints)
|
||||||
case None =>
|
case None =>
|
||||||
new JsonFactoryBuilder().build()
|
new JsonFactoryBuilder()
|
||||||
|
.streamReadConstraints(streamReadConstraints)
|
||||||
|
.streamWriteConstraints(streamWriteConstraints)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
val configuredStreamReadFeatures =
|
val configuredStreamReadFeatures =
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You 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.apache.pekko.serialization.jackson
|
||||||
|
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
import org.scalatest.BeforeAndAfterAll
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.wordspec.AnyWordSpecLike
|
||||||
|
import org.apache.pekko
|
||||||
|
import pekko.actor.{ ActorSystem, ExtendedActorSystem }
|
||||||
|
import pekko.testkit.TestKit
|
||||||
|
|
||||||
|
class JacksonFactorySpec extends TestKit(ActorSystem("JacksonFactorySpec"))
|
||||||
|
with AnyWordSpecLike with Matchers with BeforeAndAfterAll {
|
||||||
|
|
||||||
|
private val defaultConfig = ConfigFactory.defaultReference()
|
||||||
|
private val dynamicAccess = system.asInstanceOf[ExtendedActorSystem].dynamicAccess
|
||||||
|
private val objectMapperFactory = new JacksonObjectMapperFactory
|
||||||
|
|
||||||
|
override def afterAll(): Unit = {
|
||||||
|
super.afterAll()
|
||||||
|
system.terminate()
|
||||||
|
}
|
||||||
|
|
||||||
|
"Jackson Factory config" must {
|
||||||
|
"support StreamReadConstraints" in {
|
||||||
|
val bindingName = "testJackson"
|
||||||
|
val maxNumLen = 987
|
||||||
|
val maxStringLen = 1234567
|
||||||
|
val maxDocLen = 123456789L
|
||||||
|
val maxNestingDepth = 5
|
||||||
|
val config = ConfigFactory.parseString(
|
||||||
|
s"""pekko.serialization.jackson.read.max-number-length=$maxNumLen
|
||||||
|
|pekko.serialization.jackson.read.max-string-length=$maxStringLen
|
||||||
|
|pekko.serialization.jackson.read.max-document-length=$maxDocLen
|
||||||
|
|pekko.serialization.jackson.read.max-nesting-depth=$maxNestingDepth
|
||||||
|
|""".stripMargin)
|
||||||
|
.withFallback(defaultConfig)
|
||||||
|
val jacksonConfig = JacksonObjectMapperProvider.configForBinding(bindingName, config)
|
||||||
|
val mapper = JacksonObjectMapperProvider.createObjectMapper(
|
||||||
|
bindingName, None, objectMapperFactory, jacksonConfig, dynamicAccess, None)
|
||||||
|
val streamReadConstraints = mapper.getFactory.streamReadConstraints()
|
||||||
|
streamReadConstraints.getMaxNumberLength shouldEqual maxNumLen
|
||||||
|
streamReadConstraints.getMaxStringLength shouldEqual maxStringLen
|
||||||
|
streamReadConstraints.getMaxDocumentLength shouldEqual maxDocLen
|
||||||
|
streamReadConstraints.getMaxNestingDepth shouldEqual maxNestingDepth
|
||||||
|
}
|
||||||
|
"support StreamWriteConstraints" in {
|
||||||
|
val bindingName = "testJackson"
|
||||||
|
val maxNestingDepth = 54321
|
||||||
|
val config = ConfigFactory.parseString(
|
||||||
|
s"pekko.serialization.jackson.write.max-nesting-depth=$maxNestingDepth")
|
||||||
|
.withFallback(defaultConfig)
|
||||||
|
val jacksonConfig = JacksonObjectMapperProvider.configForBinding(bindingName, config)
|
||||||
|
val mapper = JacksonObjectMapperProvider.createObjectMapper(
|
||||||
|
bindingName, None, objectMapperFactory, jacksonConfig, dynamicAccess, None)
|
||||||
|
val streamWriteConstraints = mapper.getFactory.streamWriteConstraints()
|
||||||
|
streamWriteConstraints.getMaxNestingDepth shouldEqual maxNestingDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue