Jackson-based JSON and CBOR serialization capabilities for the Akka toolkit, enabling efficient serialization and deserialization of Akka messages and persistent events.
—
Akka Serialization Jackson provides comprehensive configuration options for fine-tuning serialization behavior, performance, security, and compatibility. The configuration system supports both global settings and binding-specific overrides.
All configuration is under the akka.serialization.jackson section:
akka.serialization.jackson {
# Global configuration options
verbose-debug-logging = off
type-in-manifest = on
# Binding-specific configuration
my-binding {
# Override global settings for this binding
}
}# Configuration hierarchy:
# 1. akka.serialization.jackson.<binding-name> (most specific)
# 2. akka.serialization.jackson (fallback)
akka.serialization.jackson {
# Global defaults
compression.algorithm = off
jackson-json {
# JSON-specific settings
compression.algorithm = gzip
compression.compress-larger-than = 32 KiB
}
jackson-cbor {
# CBOR-specific settings
compression.algorithm = lz4
compression.compress-larger-than = 1 KiB
}
}Control Jackson's SerializationFeature settings:
akka.serialization.jackson {
serialization-features {
# Date/time format
WRITE_DATES_AS_TIMESTAMPS = off # Use ISO-8601 format
WRITE_DURATIONS_AS_TIMESTAMPS = off # Use ISO-8601 duration format
# Object handling
FAIL_ON_EMPTY_BEANS = off # Allow empty objects
INDENT_OUTPUT = off # Compact JSON output
# Number formatting
WRITE_BIGDECIMAL_AS_PLAIN = off # Scientific notation allowed
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS = off # String representation for char[]
# Collection handling
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED = off # Always use array format
}
}Control Jackson's DeserializationFeature settings:
akka.serialization.jackson {
deserialization-features {
# Property handling
FAIL_ON_UNKNOWN_PROPERTIES = off # Ignore unknown JSON properties
FAIL_ON_NULL_FOR_PRIMITIVES = off # Allow null for primitives
FAIL_ON_NUMBERS_FOR_ENUMS = off # Allow numeric enum values
# Collection handling
ACCEPT_EMPTY_STRING_AS_NULL_OBJECT = off # Treat "" as null
ACCEPT_SINGLE_VALUE_AS_ARRAY = off # Single values as one-element arrays
# Type handling
FAIL_ON_INVALID_SUBTYPE = on # Strict subtype validation
UNWRAP_SINGLE_VALUE_ARRAYS = off # Keep array format
}
}Control Jackson's MapperFeature settings:
akka.serialization.jackson {
mapper-features {
# Property ordering
SORT_PROPERTIES_ALPHABETICALLY = off # Preserve declaration order
# Duplicate handling
ALLOW_FINAL_FIELDS_AS_MUTATORS = off # Respect final field immutability
# Visibility
AUTO_DETECT_CREATORS = on # Auto-detect constructors
AUTO_DETECT_FIELDS = on # Auto-detect field access
AUTO_DETECT_GETTERS = on # Auto-detect getter methods
# Type handling
USE_ANNOTATIONS = on # Process Jackson annotations
USE_GETTERS_AS_SETTERS = on # Use getters for collection mutation
}
}Control Jackson's JsonParser.Feature settings:
akka.serialization.jackson {
json-parser-features {
# Comment support
ALLOW_COMMENTS = off # Disallow // and /* */ comments
# Quote handling
ALLOW_SINGLE_QUOTES = off # Require double quotes
ALLOW_UNQUOTED_FIELD_NAMES = off # Require quoted field names
# Value handling
ALLOW_NUMERIC_LEADING_ZEROS = off # Strict numeric format
ALLOW_NON_NUMERIC_NUMBERS = off # Disallow NaN, Infinity
# Control characters
ALLOW_UNESCAPED_CONTROL_CHARS = off # Require escaped control chars
}
}Control Jackson's JsonGenerator.Feature settings:
akka.serialization.jackson {
json-generator-features {
# Quote handling
QUOTE_FIELD_NAMES = on # Always quote field names
QUOTE_NON_NUMERIC_NUMBERS = on # Quote NaN, Infinity
# Number formatting
WRITE_NUMBERS_AS_STRINGS = off # Use numeric representation
# Character handling
ESCAPE_NON_ASCII = off # Allow UTF-8 characters
}
}Control JsonFactory stream features:
akka.serialization.jackson {
# Stream read features
stream-read-features {
STRICT_DUPLICATE_DETECTION = off # Allow duplicate keys
USE_FAST_DOUBLE_PARSER = on # Optimized double parsing
}
# Stream write features
stream-write-features {
WRITE_BIGDECIMAL_AS_PLAIN = off # Use scientific notation
USE_FAST_DOUBLE_WRITER = on # Optimized double writing
}
# JSON-specific read features
json-read-features {
ALLOW_JAVA_COMMENTS = off # Disallow Java-style comments
ALLOW_YAML_COMMENTS = off # Disallow YAML-style comments
ALLOW_SINGLE_QUOTES = off # Require double quotes
ALLOW_UNQUOTED_FIELD_NAMES = off # Require quoted field names
ALLOW_TRAILING_COMMA = off # Disallow trailing commas
}
# JSON-specific write features
json-write-features {
QUOTE_FIELD_NAMES = on # Always quote field names
WRITE_NAN_AS_STRINGS = on # Write NaN as "NaN"
ESCAPE_NON_ASCII = off # Allow UTF-8 output
}
}Control property visibility for serialization:
akka.serialization.jackson {
visibility {
# Field visibility (default: ANY - all fields including private)
FIELD = ANY # PUBLIC_ONLY, PROTECTED_AND_PUBLIC, etc.
# Other accessors default to Jackson's default behavior (not explicitly set)
# GETTER = default # Getter method visibility
# SETTER = default # Setter method visibility
# CREATOR = default # Constructor visibility
# IS_GETTER = default # Is-getter method visibility
}
}akka.serialization.jackson {
compression {
# Available algorithms: off, gzip, lz4
algorithm = off
# Compress only if payload is larger than this size
compress-larger-than = 0 KiB
}
# Binding-specific compression
jackson-json {
compression {
algorithm = gzip # Default for JSON (good for text)
compress-larger-than = 32 KiB # Default threshold for JSON
}
}
jackson-cbor {
compression {
algorithm = off # Default is off for CBOR
compress-larger-than = 0 KiB # Default threshold
}
}
}// Compression effectiveness by algorithm:
// gzip: High compression ratio, moderate CPU usage
// lz4: Lower compression ratio, very fast CPU usage
// off: No compression, minimal CPU usage
// Size thresholds:
// < 1 KiB: Usually not worth compressing
// 1-32 KiB: LZ4 often optimal
// > 32 KiB: GZIP may provide better ratiosakka.serialization.jackson {
# Additional allowed class prefixes (beyond serialization-bindings)
allowed-class-prefix = [
"com.example.safe", # Allow com.example.safe.* classes
"org.mycompany.dto" # Allow org.mycompany.dto.* classes
]
# Deprecated - use allowed-class-prefix instead
whitelist-class-prefix = []
}akka.serialization.jackson {
# Include type information in serialization manifest
type-in-manifest = on # Default: include type info
# Override deserialization type (when type-in-manifest = off)
deserialization-type = "" # Empty = auto-detect from bindings
# Example: Force all data to deserialize as specific type
# deserialization-type = "com.example.BaseMessage"
}akka.serialization.jackson {
jackson-modules = [
# Core Akka modules
"akka.serialization.jackson.AkkaJacksonModule",
"akka.serialization.jackson.AkkaTypedJacksonModule", # If akka-actor-typed available
"akka.serialization.jackson.AkkaStreamJacksonModule", # If akka-streams available
# Standard Jackson modules
"com.fasterxml.jackson.module.paramnames.ParameterNamesModule",
"com.fasterxml.jackson.datatype.jdk8.Jdk8Module",
"com.fasterxml.jackson.datatype.jsr310.JavaTimeModule",
"com.fasterxml.jackson.module.scala.DefaultScalaModule",
# Custom modules
"com.example.MyCustomJacksonModule"
]
}Modules are automatically filtered based on classpath availability:
// Automatic filtering:
// - AkkaTypedJacksonModule: Only if akka.actor.typed.ActorRef is available
// - AkkaStreamJacksonModule: Only if akka.stream.Graph is available
// - Other modules: Always loaded if class is foundakka.serialization.jackson {
migrations {
# Map class names to migration implementations
"com.example.User" = "com.example.migrations.UserMigration"
"com.example.Order" = "com.example.migrations.OrderMigration"
# Support old class names
"com.example.legacy.OldUser" = "com.example.migrations.UserMigration"
}
}akka.serialization.jackson {
# Enable detailed serialization logging (requires akka.loglevel = DEBUG)
verbose-debug-logging = on
}
# Also set Akka log level
akka.loglevel = DEBUGDebug output includes:
// Enable JMX monitoring for ObjectMapper metrics
import com.fasterxml.jackson.databind.ObjectMapper
// Custom ObjectMapper factory with metrics
class MonitoredObjectMapperFactory extends JacksonObjectMapperFactory {
override def newObjectMapper(bindingName: String, jsonFactory: JsonFactory): ObjectMapper = {
val mapper = super.newObjectMapper(bindingName, jsonFactory)
// Add metrics collection
registerMetrics(bindingName, mapper)
mapper
}
}akka.serialization.jackson {
# Optimize for speed
verbose-debug-logging = off
serialization-features {
INDENT_OUTPUT = off # Compact output
WRITE_DATES_AS_TIMESTAMPS = on # Faster than ISO format
}
mapper-features {
SORT_PROPERTIES_ALPHABETICALLY = off # Preserve order = faster
}
compression {
algorithm = lz4 # Fastest compression
compress-larger-than = 1 KiB
}
}akka.serialization.jackson {
# Optimize for compatibility
serialization-features {
WRITE_DATES_AS_TIMESTAMPS = off # ISO-8601 format
FAIL_ON_EMPTY_BEANS = on # Strict validation
}
deserialization-features {
FAIL_ON_UNKNOWN_PROPERTIES = on # Strict property validation
FAIL_ON_INVALID_SUBTYPE = on # Strict type validation
}
json-parser-features {
ALLOW_COMMENTS = off # Strict JSON format
ALLOW_SINGLE_QUOTES = off # Standard JSON only
}
}akka.serialization.jackson {
# Optimize for debugging
verbose-debug-logging = on
serialization-features {
INDENT_OUTPUT = on # Pretty-print JSON
}
deserialization-features {
FAIL_ON_UNKNOWN_PROPERTIES = off # Lenient parsing
}
compression {
algorithm = off # No compression for debugging
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-typesafe-akka--akka-serialization-jackson