JSTEP 2 - FasterXML/jackson-future-ideas GitHub Wiki

(Back to JSTEP page)


Jackson 3 default settings, behavior changes

Author

Tatu Saloranta (@cowtowncoder)

Version history

  • 2025-05-12: Update wrt CBOR read/write feature defaults - @cowtowncoder
  • 2025-05-05: Update wrt DeserializationFeature.FAIL_ON_UNEXPECTED_VIEW_PROPERTIES revert - @cowtowncoder
  • 2025-05-03: Update wrt MonthSerializer and MonthDeserializer behavior change - @JooHyukKim
  • 2025-04-08: Added DateTimeFeature.ONE_BASED_MONTHS - @cowtowncoder
  • 2025-04-06: Added MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS - @cowtowncoder
  • 2025-02-05: Updates wrt XmlWriteFeature default changes - @cowtowncoder
  • 2025-02-01: Update wrt SerializationFeature.WRITE_DATES_AS_TIMESTAMPS default change - @cowtowncoder
  • 2025-01-31: Update wrt SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS default change - @cowtowncoder
  • 2025-01-29: Update wrt DeserializationFeature.FAIL_ON_TRAILING_TOKENS default change - @cowtowncoder
  • 2025-01-19: Add Kotlin module proposed change links - @cowtowncoder
  • 2024-07-21: DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES default changed - @cowtowncoder
  • 2024-06-06: DeserializationFeature.READ_ENUMS_USING_TO_STRING, SerializationFeature.WRITE_ENUMS_USING_TO_STRING defaults changed - @cowtowncoder
  • 2024-05-31: MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS default changed - @cowtowncoder
  • 2019-02-10: create first version from earlier notes - @cowtowncoder

Status

Mostly complete for 3.0.0-rc4 (2025-05-10) but will remain technically open until 3.0.0 release

Overview

During Jackson 2.x development, certain default settings have proven either problematic by development team, or non-intuitive/non-optimal by users: latter indicated both by filed issues and comments on mailing list discussions. Since default settings and behavior are important part of the public API, changes have had to wait until major version change in most cases.

This document details proposed/planned as well as implemented changes.

Changes to jackson-core defaults

JsonReadFeature

No changes

JsonWriteFeature

  • JsonWriteFeature.ESCAPE_FORWARD_SLASHES now defaults to true (see core#1200)

StreamReadConstraints

  • DEFAULT_MAX_DEPTH to 500 (from 1,000) (see core#1233)

StreamWriteConstraints

  • DEFAULT_MAX_DEPTH to 500 (from 1,000) (see core#1233)

StreamReadFeature

  • USE_FAST_DOUBLE_PARSER: enabled by default in 3.0 (see core#1231)
  • USE_FAST_BIG_NUMBER_PARSER: enabled by default in 3.0 (see core#1231)

StreamWriteFeature

  • USE_FAST_DOUBLE_WRITER: enabled by default in 3.0 (see core#1231)

Changes to jackson-databind defaults

MapperFeature

First, following deprecated features have been removed from 3.0:

  • USE_STD_BEAN_NAMING: should always be enabled, no need for old slightly differing algorithm
  • AUTO_DETECT_xxx: old limited settings superceded by more granular settings -- frees up 5 features

And defaults to following features have been changed:

  • ALLOW_FINAL_FIELDS_AS_MUTATORS: default to false -- while enabling may be useful sometimes, it confuses users in general and is unlikely to even work with future JDKs/JVMs
  • DEFAULT_VIEW_INCLUSION: default to false: has been requested by users and change initially approved
  • USE_GETTERS_AS_SETTERS: default to false -- earlier default was based on JAXB but is quite confusing for users
  • SORT_PROPERTIES_ALPHABETICALLY: default to true (false really doesn't make much sense since it is unstable, and arbitrary based on JVM/JDK)

Changes, potential:

  • OVERRIDE_PUBLIC_ACCESS_MODIFIERS: default to false since benefits of enabling seem small if not non-existent with 3.0

DeserializationFeature

Changes completed:

  • FAIL_ON_UNKNOWN_PROPERTIES: default to false (TOP REQUEST by users) databind#493
  • READ_ENUMS_USING_TO_STRING: default to true (instead of false that relies on name()) databind#4566
    • NOTE: this was further renamed/moved as EnumFeature.READ_ENUMS_USING_TO_STRING (via databind#5079)
  • FAIL_ON_NULL_FOR_PRIMITIVES: default to true (databind#4858)
    • Setting to false would allowing coercion from JSON null into Java int, long and so on. For some users, and especially on "low null" languages like Kotlin, such coercion is rarely expected.
  • FAIL_ON_TRAILING_TOKENS: default to true (databind#3406)

Changes planned but not made (or were reverted):

SerializationFeature

Changes completed:

  • WRITE_ENUMS_USING_TO_STRING: default to true (to keep symmetry between its DeserializationFeature.READ_ENUMS_USING_TO_STRING counterpart) databind#4567
    • NOTE: this was further renamed/moved as EnumFeature.WRITE_ENUMS_USING_TO_STRING (via databind#5080)
  • FAIL_ON_EMPTY_BEANS: default to false databind#3070
  • FAIL_ON_ORDER_MAP_BY_INCOMPARABLE_KEY : was added in 2.19. Changed default in 3.0 via databind#4781
  • WRITE_DURATIONS_AS_TIMESTAMPS: change default to false to serialize as ISO-8601 String -- databind#4846
    • Note: renamed/moved as DateTimeFeature.WRITE_DURATIONS_AS_TIMESTAMPS
  • Writing date/time values as ISO-8601 Strings instead of (Java style) timestamps
    • WRITE_DATES_AS_TIMESTAMPS: change default to false to serialize as ISO-8601 String -- databind#4845
      • Note: renamed/moved as DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS
    • WRITE_DATE_KEYS_AS_TIMESTAMPS: RETAIN default of false -- no change
      • Note: renamed/moved as DateTimeFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS

DateTimeFeature

Changes completed:

Changes to other format backend defaults

Changes to CBOR defaults

  • CBORReadFeature:
    • CBORReadFeature.DECODE_USING_STANDARD_NEGATIVE_BIGINT_ENCODING: change default to true CBOR#582
    • CBORReadFeature.READ_UNDEFINED_AS_EMBEDDED_OBJECT: change default to true CBOR#591
    • CBORReadFeature.READ_SIMPLE_VALUE_AS_EMBEDDED_OBJECT: change default to true CBOR#591
  • CBORWriteFeature:
    • CBORWriteFeature.ENCODE_USING_STANDARD_NEGATIVE_BIGINT_ENCODING: change default to true CBOR#582

Changes to XML defaults

  • XmlWriteFeature
    • XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE: Change default to true XML#725
    • XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL: Change default to true XML#727
    • XmlWriteFeature.AUTO_DETECT_XSI_TYPE: Change default to true XML#728
    • XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS: Change default to true XML#729

Changes to Date/Time defaults

NOTE: see above for databind DateTimeFeature changes.

Changes to defaults proposed:

  • Disable lenient setting (that is: default to "strict")
  • Check defaults of date/time handling

Changes to jackson-module-kotlin defaults

Kotlin module has a few proposed/accept changes.

Misc other default setting, behavior changes

JsonNode handling

  • DecimalNode creation via JsonNodeFactory: default to NOT truncating trailing zeroes (minimal trimming), because JsonNode should by default expose content as close to way it came.

MonthSerializer and MonthDeserializer behavior change (databind#5127)

  • In 2.x, java.time.Month was handled as plain Enum and was applied with Enum-related handling such as EnumFeature.WRITE_ENUMS_USING_INDEX or EnumFeature.WRITE_ENUMS_USING_TO_STRING.
  • Starting 3.x, along with java-time merging to databind module, it's now handled like regular date/time classes, defaulting to number as value.