CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-typesafe-akka--akka-serialization-jackson

Jackson-based JSON and CBOR serialization capabilities for the Akka toolkit, enabling efficient serialization and deserialization of Akka messages and persistent events.

Pending
Overview
Eval results
Files

configuration.mddocs/

Advanced Configuration

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.

Configuration Structure

Base Configuration Path

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
  }
}

Binding-Specific Configuration

# 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
  }
}

Jackson Feature Configuration

Serialization Features

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
  }
}

Deserialization Features

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
  }
}

Mapper Features

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
  }
}

JSON Parser Features

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
  }
}

JSON Generator Features

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
  }
}

Stream Features

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
  }
}

Visibility Configuration

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
  }
}

Compression Configuration

Compression Algorithms

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 Performance

// 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 ratios

Security Configuration

Class Filtering

akka.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 = []
}

Type Manifest Configuration

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"
}

Module Configuration

Jackson Modules

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"
  ]
}

Conditional Module Loading

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 found

Migration Configuration

Migration Class Mapping

akka.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"
  }
}

Debug and Monitoring

Debug Logging

akka.serialization.jackson {
  # Enable detailed serialization logging (requires akka.loglevel = DEBUG)
  verbose-debug-logging = on
}

# Also set Akka log level
akka.loglevel = DEBUG

Debug output includes:

  • Serialization/deserialization time in microseconds
  • Payload sizes (compressed and uncompressed)
  • Class names being serialized
  • Migration version information

Performance Monitoring

// 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
  }
}

Configuration Examples

High-Performance Configuration

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
  }
}

Strict Compatibility Configuration

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
  }
}

Development Configuration

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
  }
}

Best Practices

Configuration Management

  1. Use binding-specific settings - Different serializers may need different configurations
  2. Test configuration changes - Feature changes can break compatibility
  3. Document custom settings - Explain why non-default values are used
  4. Version configurations - Track configuration changes with code versions

Security Considerations

  1. Restrict allowed classes - Only allow known safe classes for deserialization
  2. Disable dangerous features - Turn off features that might enable attacks
  3. Monitor deserialization - Log and alert on unexpected class types
  4. Regular security updates - Keep Jackson versions current

Performance Tuning

  1. Profile before optimizing - Measure actual performance impact
  2. Test compression effectiveness - Different data may benefit from different algorithms
  3. Monitor memory usage - Some features increase memory overhead
  4. Benchmark realistic payloads - Use production-like data for testing

Install with Tessl CLI

npx tessl i tessl/maven-com-typesafe-akka--akka-serialization-jackson

docs

akka-types.md

configuration.md

index.md

migration.md

object-mapper.md

tile.json