This guide aims to "Connect the Dots" for Jackson 2.x to 3.x migration, helping developers by outlining the process. It is not a comprehensive guide, or check list.
Guide mostly references documentation in other repos and provides a high-level summary with appropriate links.
⚠️ Jackson 3.0 is not an LTS (Long-Term Support) version.
It is considered a transitional release.
Jackson 3.1 is your recommended target for long-term stability.
Jackson LTS model is as follows:
| Version | LTS | Notes |
|---|---|---|
| 3.0.x | ❌ | Transitional release — migrate to 3.1 |
| 3.1.x | ✅ | First LTS in the 3.x line (~2 year support window) |
| 2.18.x | ✅ | LTS (~2 year support window) |
| 2.21.x | ✅ | LTS (~2 year support window) |
See JSTEP-13 for the full LTS policy discussion.
- Baseline JDK raised to Java 17, from Java 8 in Jackson 2.x
- New Maven group-id and Java package:
tools.jackson(2.x usedcom.fasterxml.jackson)- See JSTEP-1 for details
- Exception:
jackson-annotations: 2.x version still used with 3.x, so no group-id/Java package change- See this discussion for rationale
- Jackson 3.0 uses
jackson-annotations2.20 - "Exception to Exception": annotations within
jackson-databindlike@JsonSerializeand@JsonDeserializeDO move to the new Java package (tools.jackson.databind.annotation). Same for format-specific annotation like XML (jackson-dataformat-xml) ones.
- All
@Deprecated(as of 2.20) methods, fields and classes are removed from 3.0- Javadocs in Jackson
2.20updated to indicate replacements where available (incomplete: PRs welcome for more!)
- Javadocs in Jackson
- Renaming of Core Entities (classes), methods, fields
- See JSTEP-6 for rationale, references to notable renamings
- JSTEP-8 covers refactoring/renaming of format-specific Read/Write features (like
JsonParser.FeatureintoJsonReadFeatureandStreamReadFeaure) - Javadocs in Jackson
2.20updated to indicate new names where available (incomplete: PRs welcome for more!)
- Changes to Default Configuration Settings (esp. various XxxFeatures)
- See JSTEP-2 for rationale, the set of changes made
- Immutability of
ObjectMapper,JsonFactoryObjectMapperandJsonFactory(and their sub-types) are fully immutable in 3.x: instances to be constructed using the builder pattern
- Use of format-aligned
ObjectMappermandatory:new YAMLMapper(),new XmlMapper()- Old
new ObjectMapper(new YAMLFactory())no longer allowed
- Old
- Unchecked exceptions: all Jackson exceptions are now
RuntimeExceptions (unchecked)- JSTEP-4 explains rationale, changes
- Base exception (
JsonProcessingExceptionin 2.x, renamed asJacksonException) now extendsRuntimeExceptionand NOTIOException(like 2.x did)
- Embedding and Removal of "Java 8 modules"
- All 3 "Java 8 modules", that were separate in Jackson 2.x, are now built-in to
jackson-databind(no need to register separately)jackson-module-parameter-names: auto-detection of constructor parameter namesjackson-datatype-jdk8: support forjava.util.Optionaland other optional types (OptionalDouble, ...)jackson-datatype-jsr310: supportjava.timetypes (added in 3.0.0-rc3)
- All 3 "Java 8 modules", that were separate in Jackson 2.x, are now built-in to
- Deprecation of
jackson-module-jsonSchemamodule- As per JSTEP-9, some 2.x modules were Deprecated and no 3.0.0 version was produced (no 3.x branch with converted code base)
- JSON Schema module is considered Obsolete, no plans to migrate
- Jackson Hibernate datatype was added in 3.0.2.
- As per JSTEP-9, some 2.x modules were Deprecated and no 3.0.0 version was produced (no 3.x branch with converted code base)
For the full list of all issues resolved for 3.0, see Jackson 3.0 Release Notes.
- Jackson-future-ideas Github repo contains the majority of planning and discussion for Jackson 3 preparation. It includes:
- JSTEPs (Jackson STrategic Enhancement Proposals)
- Sources for most major changes
- Github Discussions section in the same repo as JSTEP
- see first (but not last) discussion here as example
- JSTEPs (Jackson STrategic Enhancement Proposals)
- OpenRewrite recipe for Jackson 2 -> 3 migration which can be found here
- Blog posts about regarding Jackson 3 release from our own @cowtowncoder here
- Jackson 3 support in Spring here
While the functional migration covers API and behavior changes, a couple of default settings in 3.x can have modest performance impact compared to 2.x. If you are sensitive to throughput/latency, consider the following:
-
Trailing-token checks
-
In Jackson 3.x,
DeserializationFeature.FAIL_ON_TRAILING_TOKENSis enabled by default (it was off by default in 2.x). This adds a small amount of overhead because the parser validates there is no extra content after a successful value parse. -
If your inputs are trusted/controlled and you want to match 2.x behavior, you can disable it:
JsonMapper mapper = JsonMapper.builder() .disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS) .build(); // Or on read call: MyValue v = mapper.readerFor(MyValue.class) .without(DeserializationFeature.FAIL_ON_TRAILING_TOKENS) .readValue(source);
-
Recommendation: keep it enabled for security/correctness unless profiling shows a measurable regression on your workload.
-
-
Buffer recycling settings
Buffer recycling is used for byte[] and char[] buffers used by Streaming parsers and generators (JsonParser, JsonGenerator). There are multiple recycler pool (RecyclerPool) implementations optimized for different use cases: Jackson 2.x and 3.x have different default pool choices.
-
Jackson 3.0 defaults to a deque-based
RecyclerPool, which can add overhead in some common cases versus the 2.x default (JsonRecyclerPools.threadLocalPool()). -
If your workload benefited from the 2.x behavior, set the pool explicitly when building your
TokenStreamFactory(e.g.,JsonFactory), and then pass that factory to your mapper:JsonFactory factory = JsonFactory.builder() .recyclerPool(JsonRecyclerPools.threadLocalPool()) .build(); JsonMapper mapper = JsonMapper.builder(factory) .build();
-
Note: choose the pool that matches your deployment model (single-thread hot loops vs. highly concurrent). Test both options under production-like load.
-
Note: it is even possible that for some cases, not recycling may have least overhead:
JsonFactory factory = JsonFactory.builder() .recyclerPool(JsonRecyclerPools.nonRecyclingPool()) .build();
We will expand this section as more performance-affecting defaults are identified.
References
- Default for trailing-tokens in 3.0 discussion: jackson-databind#3406
- Recycler pool defaults & alternatives: jackson-core#1117, default change notes jackson-core#1266, how to override in 2.17.x/3.x jackson-core#1293
- Background on moving away from ThreadLocal pools (virtual threads): jackson-core#919
This section aims to guide users through actual conversation from Jackson 2 to 3. Starting with "High-level conversion overflow" section, followed by "Detailed Conversion Guidelines"
Starting from the high-level change list, we can see the need for following changes:
- Java baseline: JDK 17
- Depends on your application :)
- Maven group id, Java package change
- Need to update build files (
pom.xml,build.gradle) to use new group id (com.fasterxml.jackson.core->tools.jackson.coreand so on) - Need to change import statements due to the change in the Java package (
com.fasterxml.jackson->tools.jackson-- EXCEPT not forjackson-annotations)
- Need to update build files (
@Deprecatedmethod, field, class removal:- Need to replace with non-Deprecated alternatives, as per
2.20Javadocs updated to indicate replacement where possible - See a later section for a set of common cases
- Need to replace with non-Deprecated alternatives, as per
- Renaming of Core Entities (classes), methods, fields
- Need to change references to use the new name (including
importstatements):2.20Javadocs updated to indicate replacement where possible - JSTEP-6 includes a list (likely incomplete) of renamed things as well
- Streaming API Read/Write
Features like formerJsonParser.FeatureandJsonGenerator.Featurewere renamed as per JSTEP-8JsonParser.Featuresplit into generalStreamReadFeatures and JSON-specificJsonReadFeaturesJsonGenerator.Featuresplit into generalStreamWriteFeatures and JSON-specificJsonWriteFeatures- Same was done for other format backends as well: Avro, CBOR, CSV, Ion, Smile, XML and YAML
- Need to change references to use the new name (including
- Changes to Default Configuration Settings
- MAY need to override some defaults (where existing 2.x behavior preferred) -- but most changes are to settings developers prefer so unlikely to need to change all
JsonMapper.builderWithJackson2Defaults()may be used to use some of legacy configuration settings (cannot change all defaults but can help migration)
- JSTEP-2 lists all default changes
- MAY need to override some defaults (where existing 2.x behavior preferred) -- but most changes are to settings developers prefer so unlikely to need to change all
- Immutability of
ObjectMapper,JsonFactoryObjectMapper/JsonMapper: convert direct configuration withBuilderalternatives:JsonMapper.builder().enable(...).build()JsonFactory/TokenStreamFactory: convert direct configuration withBuilderalternatives:JsonFactory.builder().enable(...).build()
- Use of format-aligned
ObjectMappermandatory- Format-specific sub-types already exist for all formats in 2.20
- In 3.0, constructing plain
ObjectMapperwith format-specificTokenStreamFactoryno longer allowed
- Unchecked exceptions
- May require changes to handling since catching Jackson exceptions is now optional
- No need to declare
throwsclause for Jackson calls - Base exceptions renamed; specifically:
JsonProcessingException->JacksonExceptionJsonMappingException->DatabindException
- Other exception renamings:
JsonEOFException->UnexpectedEndOfInputException
- Embedding and Removal of "Java 8 modules"
- Simply remove Maven/Gradle dependencies, module registrations
- Deprecation of
jackson-module-jsonSchemamodule- For
jackson-module-jsonSchemause alternate tools
- For
No additional suggestions.
Changes to import statements should be quite mechanical:
- Replace
com.fasterxml.jackson.withtools.jackson.everywhere- EXCEPT NOT for
com.fasterxml.jackson.annotation
- EXCEPT NOT for
Similarly change to Maven Group id in the build files (pom.xml, build.gradle) should be mechanical:
- Replace
com.fasterxml.jacksonwithtools.jacksonfor dependencies- BUT NOT for
com.fasterxml.jackson.annotation
- BUT NOT for
But beyond this, if you are not yet using jackson-bom for enforcing compatible set of versions, we would highly encourage starting to do so.
This could additionally help avoid most of complexity of jackson-annotations dependency since it is possible to rely on annotations package as transitive dependency. For Maven you can just do:
<project>
<!-- ... -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>tools.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>3.0.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<!-- ... -->
<dependencies>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- jackson-core and jackson-annotations transitive dependencies -->
</dependencies>
<project>and for Gradle you can use something like:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
implementation platform("tools.jackson:jackson-bom:3.0.0")
// Now declare Jackson modules WITHOUT versions
implementation "tools.jackson.core:jackson-databind"
}It is necessary to convert @Deprecated methods/fields/classes with the documented alternative where ones exist.
Jackson 2.20 Javadocs include replacement in many cases.
Here are some notes on the most commonly encountered cases.
JsonFactorygetCodec(),setCodec(): removed from 3.0 while not deprecated (since use ok in 2.x)- No replacement since codec-style object (
ObjectMapperor similar) no longer associated with streaming factory -- only with generators, parsers
JsonGeneratorgetCodec(): replaced withobjectWriteContext()to provide same (or better) functionality
JsonParsercanWriteBinaryNatively(),canWriteFormattedNumbers()replaced withStreamWriteCapability.CAN_WRITE_BINARY_NATIVELY/StreamWriteCapability.CAN_WRITE_FORMATTED_NUMBERS(respectively)getCodec(): replaced withobjectReadContext()to provide same (or better) functionality
ObjectMappercopy(): removed from 3.0 while not deprecated (since use ok in 2.x)- No replacement as making exact copies no longer necessary or useful: creating differently configured instances needs to use new Build pattern
- See "ObjectMapper: copying an existing mapper instance" for details
None reported yet
com.fasterxml.jackson.databind.MappingJsonFactoryis removed -- while not Deprecated in 2.x (where it is used), implementation is neither needed nor possible to support as-is.com.fasterxml.jackson.core.ObjectCodec(ofjackson-core) -- which exposed subset ofObjectMapperfunctionality to streaming API was removed- Replaced with 2 separate interfaces:
tools.jackson.core.ObjectReadContext,tools.jackson.core.ObjectWriteContext ObjectReadContextimplemented byjackson-databindclassDeserializationContextObjectWriteContextimplemented byjackson-databindclassSerializationContext(known asSerializerProviderin 2.x)- See jackson-core#413 for details
- Replaced with 2 separate interfaces:
tools.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidatoris no longer public. Please useBasicPolymorphicTypeValidator.builder()to construct and configure your type validator. See "ObjectMapper: automatic inclusion of type information configuration".
Jackson 1.x and 2.x contained functionality for auto-detecting format of arbitrary content to decode: functionality was part of jackson-core -- Java classes under com.fasterxml.jackson.core.format (like DataFormatDetector) -- (and implemented by jackson-dataformat-xxx components for non-JSON formats).
But due to complexity of implementation, problems with API handling, and lack of usage, this functionality was dropped from 3.0. No replacement exists
Methods ObjectMapper.canDeserialize(), ObjectMapper.canSerialize() removed since they cannot be implemented in a useful way.
See databind#1917 for details.
Similar to deprecations, it is necessary to change old references to use new names (including import statements): 2.20 Javadocs were updated in some cases to indicate replacement (if available).
Further JSTEP-6 includes a list of renamed things as well -- possibly incomplete list, but useful.
From that, here are ones you are most likely to encounter.
Regular classes:
JsonFactorysplit- API extracted as
TokenStreamFactory - Implementation moved under
tools.jackson.core.json(note the added "json" segment)
- API extracted as
JsonStreamContext->TokenStreamContextJsonLocation->TokenStreamLocation
Exception types:
JsonProcessingException->JacksonException(ultimate base exception)JsonParseException-> `StreamReadExceptionJsonEOFException->UnexpectedEndOfInputExceptionJsonGenerationException->StreamWriteException
Methods:
JsonGenerator:- replace references in method names to "field" with "property"
getCodec()->objectWriteContext()getCurrentValue()->currentValue()setCurrentValue()->assignCurrentValue()writeObject()->writePOJO()
JsonParser:- replace references in method names to "field" with "property"
- replace "xxxTextYyy" methods (like
getText(),getTextCharacters()) with "xxxStringYyy" methods (likegetString(),getStringCharacters()) getCodec()->objectReadContext()getCurrentLocation()->currentLocation()getTokenLocation()->currentTokenLocation()getCurrentName()-> 'currentName()' ('currentName()' is available since Jackson 2.17)getCurrentValue()->currentValue()setCurrentValue()->assignCurrentValue()
Fields:
JsonToken.FIELD_NAME->JsonToken.PROPERTY_NAME
Streaming API Read/Write Features like former JsonParser.Feature and JsonGenerator.Feature were renamed as per JSTEP-8.
JsonParser.Featuresplit into generalStreamReadFeatures and JSON-specificJsonReadFeaturesJsonGenerator.Featuresplit into generalStreamWriteFeatures and JSON-specificJsonWriteFeatures
Same was done for format backends as well:
- Avro:
AvroParser.Feature->AvroReadFeature;AvroGenerator.Feature->AvroWriteFeature - CBOR:
CBORGenerator.Feature->CBORWriteFeature - CSV:
CsvParser.Feature->CsvReadFeature;CsvGenerator.Feature->CsvWriteFeature - Ion:
IonParser.Feature->IonReadFeature;IonGenerator.Feature->IonWriteFeature - Smile:
SmileParser.Feature->SmileReadFeature;SmileGenerator.Feature->SmileWriteFeature - XML:
FromXmlParser.Feature->XmlReadFeature;ToXmlGenerator.Feature->XmlWriteFeature - YAML:
YAMLParser.Feature->YAMLReadFeature;YAMLGenerator.Feature->YAMLWriteFeature
Regular classes:
BeanDeserializerModifier->ValueDeserializerModifierBeanSerializerModifier->ValueSerializerModifierContainerSerializer->StdContainerSerializerContextualDeserializer-> REMOVED -- now methodcreateContextualpart ofValueDeserializerContextualSerializer-> REMOVED -- now methodcreateContextualpart ofValueSerializerJsonDeserializer->ValueDeserializerJsonSerializer->ValueSerializerJsonSerializable->JacksonSerializableModule->JacksonModule(to resolve naming overlap with JDKModule)ResolvableDeserializer-> REMOVED -- now methodresolve()part ofValueDeserializerResolvableSerializer-> REMOVED -- now methodresolve()part ofValueSerializerSerializerProvider->SerializationContextTextNode->StringNode
Exception types:
JsonMappingException->DatabindException
"Feature" enums
DateTimeFeaturecreated: some existingDeserializationFeature/SerializationFeatures movedDeserializationFeatureADJUST_DATES_TO_CONTEXT_TIME_ZONEREAD_DATE_TIMESTAMPS_AS_NANOSECONDS
SerializationFeatureWRITE_DATES_AS_TIMESTAMPS(default changed tofalsein 3.0)WRITE_DATE_KEYS_AS_TIMESTAMPSWRITE_DATE_TIMESTAMPS_AS_NANOSECONDSWRITE_DATES_WITH_ZONE_IDWRITE_DATES_WITH_CONTEXT_TIME_ZONEWRITE_DURATIONS_AS_TIMESTAMPS
- Some existing
DeserializationFeature/SerializationFeatures moved toEnumFeature(added in 2.14)DeserializationFeatureFAIL_ON_NUMBERS_FOR_ENUMSREAD_ENUMS_USING_TO_STRING(default changed totruein 3.0)READ_UNKNOWN_ENUM_VALUES_AS_NULLREAD_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE
SerializationFeatureWRITE_ENUMS_USING_TO_STRING(default changed totruein 3.0)WRITE_ENUMS_USING_INDEXWRITE_ENUM_KEYS_USING_INDEX
Methods:
- Many of
JsonNodemethods renamed: see JSTEP-3 for details ObjectMapper.getRegisteredModuleIds()->ObjectMapper.registeredModules()- note: return value changed; see databind#5272 for details.
JSTEP-2 lists all changes. In general, these changes do not necessarily cause problems or require changes, however, if you do observe runtime problems (or new unit test failures), it is good to consider the possibility that some default config setting changes could be the cause. But not all changes are equally likely to cause compatibility problems: here are ones that are considered the most likely to cause problems or observed behavioral changes:
MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS(disabled in 3.0): this non-intuitive feature may have masked actual problems with immutable classes, wherein Jackson forcibly overwrote values offinalfields (which is possible via reflection!), but the developer assumed a constructor was being used.- "Is it a Bug or Feature?" -- disabled since newer JVMs are less likely to allow the feature to work.
MapperFeature.AUTO_DETECT_CREATORS(and 4 relatedAUTO_DETECT_xxxvariants) were removed: see "Configuring ObjectMappers" section for replacement (JsonMapper.builder().changeDefaultVisibility(*MapperFeature.DEFAULT_VIEW_INCLUSION(disabled in 3.0): simple configuration change, but significant impact for@JsonView` usageMapperFeature.SORT_PROPERTIES_ALPHABETICALLY(enabled in 3.0): likely to change the default ordering of property serialization for POJOs (where@JsonPropertyOrderis not used)- Highly visible and may break brittle unit tests (ones that assume specific ordering)
MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER(removed in 3.0, disabled in 2.x): Effective behavior in 3.0 is the same as if this was enabled. Only applies ifMapperFeature.SORT_CREATOR_PROPERTIES_FIRSTis enabled (enabled by default in 2.x & 3.0). Likely to change the ordering of property serialization for POJOs (where alphabetical property ordering is used).MapperFeature.USE_GETTERS_AS_SETTERS(disabled in 3.0): another highly non-intuitive feature; but one that may have masked actual problems (no setter or constructor for passingCollection/Mapvalued properties)- Originally included for JAXB compatibility ...)`)
MapperFeature.USE_STD_BEAN_NAMING: removed; no longer used or needed -- 3.0 behavior same as 2.x with Feature enabled.
DeserializationFeature.FAIL_ON_TRAILING_TOKENS(enabled in 3.0, disabled in 2.x): enables validation that no extra content follows a parsed value; improves safety but introduces modest overhead. Disable if inputs are trusted and performance is critical.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES(disabled in 3.0): May mask real issues with name mismatchDeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES(enabled in 3.0): May start failing@JsonCreatorusage where missing values for primitive (likeint) valued properties can start failing.
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS(disabled in 3.0, enabled in 2.x): Highly visible change to serialization; may break unit tests. (It is moved to DateTimeFeature)
Since both ObjectMapper and JsonFactory (TokenStreamFactory) -- along with their subtypes -- are fully immutable in 3.0, neither has direct configurability: no simple setters, or methods to configure handlers.
Instead, builder-based configuration is needed:
A simple example of constructing JSON-handling ObjectMapper:
final JsonMapper mapper = JsonMapper.builder() // format-specific builders
.addModule(new JodaModule()) // to use Joda date/time types
.enable(JsonWriteFeature.ESCAPE_NON_ASCII) // configure streaming JSON-escaping
.build();Note, too, that given a mapper instance, you CAN create a Builder with its settings to create a re-configured instance:
JsonMapper mapper2 = mapper.rebuild()
.enable(SerializationFeature.INDENT_OUTPUT)
.build();Beside configuring simple Features via Builder instead of direct ObjectMapper calls, some changes are bit more involved
Instead of
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
mapper.setTimeZone(TimeZone.getDefault());
use
ObjectMapper mapper = JsonMapper.builder()
.defaultDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"))
.defaultTimeZone(TimeZone.getDefault())
.build();
Note that the default time zone is UTC, NOT default TimeZone of JVM.
Instead of
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
use
ObjectMapper mapper = JsonMapper.builder()
.changeDefaultPropertyInclusion(incl -> incl.withValueInclusion(JsonInclude.Include.NON_NULL))
.changeDefaultPropertyInclusion(incl -> incl.withContentInclusion(JsonInclude.Include.NON_NULL))
.build();
Instead of
mapper.disable(MapperFeature.AUTO_DETECT_FIELDS);
use
ObjectMapper mapper = JsonMapper.builder()
.changeDefaultVisibility(vc ->
vc.withFieldVisibility(JsonAutoDetect.Visibility.NONE))
.build();
To configure specific type information, use .activateDefaultTypingAsProperty(). This did not change, however, the way this is configured did:
Instead of for example
mapper.activateDefaultTypingAsProperty(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS,
"@class");
use
ObjectMapper mapper = JsonMapper.builder()
.activateDefaultTypingAsProperty(typeValidator, DefaultTyping.NON_CONCRETE_AND_ARRAYS, "@class")
.build();
where typeValidator is built using the builder present in BasicPolymorphicTypeValidator:
var typeValidator = BasicPolymorphicTypeValidator.builder()
.allowIfSubType("my.package.base.name.")
.allowIfSubType("java.util.concurrent.")
.allowIfSubTypeIsArray()
// ...
.build();
Note that the enum DefaultTyping also moved outside of the ObjectMapper to tools.jackson.databind.
ObjectMapper.copy method has been removed. You are encouraged to create mappers by reusing a Mapper.Builder instance.
You can modify Mapper.Builder instances but ObjectMapper instances are immutable in Jackson 3 so it is not as useful to
copy mappers any more. ObjectMapper.rebuild() is one way to get a builder instance if you don't have a cached builder instance to work with.
One quick workaround if you still want to copy a mapper is to call ObjectMapper.rebuild().build() to create a new mapper instance.
In Jackson 2.x, you could configure default view at the ObjectMapper level:
objectMapper.setConfig(objectMapper.getSerializationConfig().withView(Views.Public.class));
objectMapper.setConfig(objectMapper.getDeserializationConfig().withView(Views.Public.class));Since ObjectMapper is immutable in 3.x and setConfig is removed, this no longer works.
Jackson 3.1 (#5575): Use MapperBuilder.defaultSerializationView() and defaultDeserializationView():
ObjectMapper mapper = JsonMapper.builder()
.defaultSerializationView(Views.Public.class)
.defaultDeserializationView(Views.Public.class)
.build();For per-request views, use ObjectReader.withView() / ObjectWriter.withView() as before.
Similar to ObjectMapper, streaming parser/generator factories -- subtypes of TokenStreamFactory like JsonFactory -- are also built using Builders:
JsonFactory f = JsonFactory.builder()
.disable(StreamWriteFeature.AUTO_CLOSE_TARGET)
.build();and may also be re-configured like so:
JsonFactory f2 = f.rebuild()
.enable(StreamWriteFeature.STRICT_DUPLICATE_DETECTION)
.build();To align with 2.x performance characteristics, you may explicitly configure the recycler pool on the factory builder:
JsonFactory f = JsonFactory.builder()
.recyclerPool(JsonRecyclerPools.threadLocalPool())
.build();
JsonMapper mapper = JsonMapper.builder(f).build();If your workload is highly concurrent, benchmark the default deque-based pool versus threadLocalPool() and choose based on observed throughput/latency and memory behavior.
Finally, to pass customized TokenStreamFactory for ObjectMapper, you will need to pass instance to builder() like so:
JsonFactory f = JsonFactory.builder()
// configure
.build();
ObjectMapper mapper = JsonMapper.builder(f)
// configure
.build();Although use of
new ObjectMapper()
is still allowed, the use of one of
new JsonMapper()
JsonMapper.builder().build()
is recommend. And all construction of generic ObjectMapper:
new ObjectMapper(new YAMLFactory()); // and similar
MUST be converted to format-specific ObjectMapper subtypes:
new YAMLMapper(new YAMLFactory());
new YAMLMapper(); // same as above
new YAMLMapper(YAMLFactory().builder()
// configure
.build());
In addition, it may make sense to start passing typed mapper instances along: JsonMapper instead of ObjectMapper (unless format-agnostic handling needs to be supported).
No additional suggestions.
Configuration of Java 8 Date/Time handling in 3.x is done using new DateTimeFeature enumeration, like so:
ObjectMapper MAPPER = JsonMapper.builder()
.enable(DateTimeFeature.WRITE_DATES_WITH_ZONE_ID)
.build();instead of either module-specific JavaTimeFeature or renamed DeserializationFeature / SerializationFeature
No additional suggestions.