Top Description Inners Fields Constructors Methods
com.fasterxml.jackson.module.androidrecord

public Class AndroidRecordModule

extends SimpleModule
Class Inheritance
Imports
java.lang.reflect.*, java.util.*, java.util.stream.Collectors, .Stream, com.fasterxml.jackson.core.Version, com.fasterxml.jackson.databind.AnnotationIntrospector, .JavaType, .PropertyName, com.fasterxml.jackson.databind.cfg.MapperConfig, com.fasterxml.jackson.databind.introspect.*, com.fasterxml.jackson.databind.module.SimpleModule

Module that allows (de)serialization of records using the canonical constructor and accessors on Android, where java records are supported through desugaring, and Jackson's built-in support for records doesn't work, since the desugared classes have a non-standard super class, and record component-related reflection methods are missing.

See Android Developers Blog article

Note

this module is a no-op when no Android-desugared records are being (de)serialized, so it is safe to use in code shared between Android and non-Android platforms.

Note

the canonical record constructor is identified through matching of parameter names and types with fields. Therefore, this module doesn't allow a deserialized desugared record to have a custom constructor with the same set of parameter names and types as the canonical one. For the same reason, this module requires that desugared canonical record constructor parameter names be stored in class files. Apparently, with Android SDK 34 tooling, that is the case by default. If that ever changes, it may require an explicit setting in build files.

Author
Eran Leshem

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv static class
pack-priv static class
private static class

Field Summary

Modifier and TypeField and Description
private static final long
Inherited from com.fasterxml.jackson.databind.module.SimpleModule:
_abstractTypes_deserializerModifier_deserializers_hasExplicitName_keyDeserializers_keySerializers_mixins_name_namingStrategy_serializerModifier_serializers_subtypes_valueInstantiators_version

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
pack-priv static Class<?>
arrayTypeCompat(Class<?> componentType)

pack-priv static Type
pack-priv static Stream<Field>
pack-priv static boolean
public void
setupModule(Module.SetupContext context)

Overrides com.fasterxml.jackson.databind.module.SimpleModule.setupModule.

Standard implementation handles registration of all configured customizations: it is important that sub-classes call this implementation (usually before additional custom logic) if they choose to override it; otherwise customizations will not be registered.

Inherited from com.fasterxml.jackson.databind.module.SimpleModule:
_checkNotNulladdAbstractTypeMappingaddDeserializeraddKeyDeserializeraddKeySerializeraddSerializeraddSerializeraddValueInstantiatorgetModuleNamegetTypeIdregisterSubtypesregisterSubtypesregisterSubtypessetAbstractTypessetDeserializerModifiersetDeserializerssetKeyDeserializerssetKeySerializerssetMixInAnnotationsetNamingStrategysetSerializerModifiersetSerializerssetValueInstantiatorsversion

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Hides com.fasterxml.jackson.databind.module.SimpleModule.serialVersionUID.

Constructor Detail

AndroidRecordModuleback to summary
public AndroidRecordModule()

Method Detail

arrayTypeCompatback to summary
pack-priv static Class<?> arrayTypeCompat(Class<?> componentType)
fixAndroidGenericTypeback to summary
pack-priv static Type fixAndroidGenericType(Type type)
getDesugaredRecordComponentsback to summary
pack-priv static Stream<Field> getDesugaredRecordComponents(Class<?> raw)
isDesugaredRecordClassback to summary
pack-priv static boolean isDesugaredRecordClass(Class<?> raw)
setupModuleback to summary
public void setupModule(Module.SetupContext context)

Overrides com.fasterxml.jackson.databind.module.SimpleModule.setupModule.

Doc from com.fasterxml.jackson.databind.module.SimpleModule.setupModule.

Standard implementation handles registration of all configured customizations: it is important that sub-classes call this implementation (usually before additional custom logic) if they choose to override it; otherwise customizations will not be registered.

Annotations
@Override
com.fasterxml.jackson.module.androidrecord back to summary

pack-priv Class AndroidRecordModule.AndroidRecordAnnotationIntrospector

extends AnnotationIntrospector
Class Inheritance

Field Summary

Modifier and TypeField and Description
private static final long

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public PotentialCreator
findDefaultCreator(MapperConfig<?>
Configuration settings in effect (for deserialization)
config
,
AnnotatedClass
Class being instantiated; defines Creators passed
valueClass
,
List<PotentialCreator>
Constructors value class declares
declaredConstructors
,
List<PotentialCreator>
Factory methods value class declares
declaredFactories
)

Overrides com.fasterxml.jackson.databind.AnnotationIntrospector.findDefaultCreator.

Method called to check if introspector can find a Creator it considers the "Primary Creator": Creator to use as the primary one, when no Creator has explicit annotation (findCreatorAnnotation returns null).

public Version
version()

Implements abstract com.fasterxml.jackson.databind.AnnotationIntrospector.version.

Implements com.fasterxml.jackson.core.Versioned.version.

Method called to detect version of the component that implements this interface; returned version should never be null, but may return specific "not available" instance (see Version for details).

Inherited from com.fasterxml.jackson.databind.AnnotationIntrospector:
_findAnnotation_hasAnnotation_hasOneOfallIntrospectorsallIntrospectorsfindAndAddVirtualPropertiesfindAutoDetectVisibilityfindClassDescriptionfindContentDeserializerfindContentSerializerfindCreatorAnnotationfindCreatorBindingfindDefaultEnumValuefindDefaultEnumValuefindDeserializationContentConverterfindDeserializationConverterfindDeserializerfindEnumAliasesfindEnumAliasesfindEnumNamingStrategyfindEnumValuefindEnumValuesfindEnumValuesfindFilterIdfindFormatfindIgnoreUnknownPropertiesfindImplicitPropertyNamefindInjectableValuefindInjectableValueIdfindKeyDeserializerfindKeySerializerfindMergeInfofindNameForDeserializationfindNameForSerializationfindNamingStrategyfindNullSerializerfindObjectIdInfofindObjectReferenceInfofindPOJOBuilderfindPOJOBuilderConfigfindPolymorphicTypeInfofindPropertiesToIgnorefindPropertyAccessfindPropertyAliasesfindPropertyContentTypeResolverfindPropertyDefaultValuefindPropertyDescriptionfindPropertyIgnoralByNamefindPropertyIgnoralsfindPropertyInclusionfindPropertyInclusionByNamefindPropertyIndexfindPropertyTypeResolverfindReferenceTypefindRenameByFieldfindRootNamefindSerializationContentConverterfindSerializationConverterfindSerializationPropertyOrderfindSerializationSortAlphabeticallyfindSerializationTypingfindSerializerfindSetterInfofindSubtypesfindTypeNamefindTypeResolverfindUnwrappingNameTransformerfindValueInstantiatorfindViewsfindWrapperNamehasAnyGetterhasAnyGetterAnnotationhasAnySetterhasAnySetterAnnotationhasAsKeyhasAsValuehasAsValueAnnotationhasCreatorAnnotationhasIgnoreMarkerhasRequiredMarkerisAnnotationBundleisIgnorableTypeisTypeIdnopInstancepairrefineDeserializationTyperefineSerializationTyperesolveSetterConflict

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Constructor Detail

AndroidRecordAnnotationIntrospectorback to summary
pack-priv AndroidRecordAnnotationIntrospector()

Method Detail

findDefaultCreatorback to summary
public PotentialCreator findDefaultCreator(MapperConfig<?> config, AnnotatedClass valueClass, List<PotentialCreator> declaredConstructors, List<PotentialCreator> declaredFactories)

Overrides com.fasterxml.jackson.databind.AnnotationIntrospector.findDefaultCreator.

Doc from com.fasterxml.jackson.databind.AnnotationIntrospector.findDefaultCreator.

Method called to check if introspector can find a Creator it considers the "Primary Creator": Creator to use as the primary one, when no Creator has explicit annotation (findCreatorAnnotation returns null). Examples of default creators include the canonical constructor defined by Java Records; "Data" classes by frameworks like Lombok and JVM languages like Kotlin and Scala (case classes) also have similar concepts. If introspector can determine that one of given PotentialCreators should be considered the primary, it should return it; if not, should return null. Note that core databind functionality may call this method even in the presence of explicitly annotated creators; and may or may not use Creator returned depending on other criteria.

Note

when returning chosen Creator, it may be necessary to mark its "mode" with PotentialCreator#overrideMode (especially for "delegating" creators).

Note

method is NOT called for Java Record types; selection of the canonical constructor as the Primary creator is handled directly by POJOPropertiesCollector

Note

naming of this method is unfortunately inconsistent in that "default Creator" has other meanings than "primary Creator" -- in other places Jackson code refers to no-arguments Constructors as "default Creators". So this method ought to have been named findPrimaryCreator().

Parameters
config:MapperConfig<?>

Configuration settings in effect (for deserialization)

valueClass:AnnotatedClass

Class being instantiated; defines Creators passed

declaredConstructors:List<PotentialCreator>

Constructors value class declares

declaredFactories:List<PotentialCreator>

Factory methods value class declares

Returns:PotentialCreator

Default Creator to possibly use for valueClass, if one can be determined; null if not.

Annotations
@Override
versionback to summary
public Version version()

Implements abstract com.fasterxml.jackson.databind.AnnotationIntrospector.version.

Implements com.fasterxml.jackson.core.Versioned.version.

Doc from com.fasterxml.jackson.core.Versioned.version.

Method called to detect version of the component that implements this interface; returned version should never be null, but may return specific "not available" instance (see Version for details).

Returns:Version

Version of the component

Annotations
@Override
com.fasterxml.jackson.module.androidrecord back to summary

pack-priv Class AndroidRecordModule.AndroidRecordClassIntrospector

extends BasicClassIntrospector
Class Inheritance

Field Summary

Modifier and TypeField and Description
private static final long
Inherited from com.fasterxml.jackson.databind.introspect.BasicClassIntrospector:
BOOLEAN_DESCINT_DESCLONG_DESCOBJECT_DESCSTRING_DESC

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
protected POJOPropertiesCollector
Inherited from com.fasterxml.jackson.databind.introspect.BasicClassIntrospector:
_findStdJdkCollectionDesc_findStdTypeDesc_isStdJDKCollection_resolveAnnotatedClass_resolveAnnotatedWithoutSuperTypescollectPropertiescollectPropertiesWithBuildercollectPropertiesWithBuilderconstructPropertyCollectorconstructPropertyCollectorcopyforClassAnnotationsforCreationforDeserializationforDeserializationWithBuilderforDeserializationWithBuilderforDirectClassAnnotationsforSerialization

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Hides com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.serialVersionUID.

Constructor Detail

AndroidRecordClassIntrospectorback to summary
pack-priv AndroidRecordClassIntrospector()

Method Detail

collectPropertiesback to summary
protected POJOPropertiesCollector collectProperties(MapperConfig<?> config, JavaType type, ClassIntrospector.MixInResolver r, boolean forSerialization)

Overrides com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties.

Annotations
@Override
com.fasterxml.jackson.module.androidrecord back to summary

private final Class AndroidRecordModule.AndroidRecordNaming

extends DefaultAccessorNamingStrategy
Class Inheritance

Field Summary

Modifier and TypeField and Description
private final Set<String>
_componentNames

Names of actual Record components from definition; auto-detected.

Inherited from com.fasterxml.jackson.databind.introspect.DefaultAccessorNamingStrategy:
_baseNameValidator_config_forClass_getterPrefix_isGetterPrefix_isGettersNonBoolean_mutatorPrefix_stdBeanNaming

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public String
findNameForRegularGetter(AnnotatedMethod
Method to check
am
,
String
Name to check (usually same as AnnotatedMethod#getName()
name
)

Overrides com.fasterxml.jackson.databind.introspect.DefaultAccessorNamingStrategy.findNameForRegularGetter.

Method called to find whether given method would be considered a "regular" getter method in context of type introspected, and if so, what is the logical property it is associated with (which in turn suggest external name for property)

Note that signature acceptability has already been checked (no arguments, does have a return value) by caller.

Inherited from com.fasterxml.jackson.databind.introspect.DefaultAccessorNamingStrategy:
_isCglibGetCallbacks_isGroovyMetaClassGetterfindNameForIsGetterfindNameForMutatorlegacyManglePropertyNamemodifyFieldNamestdManglePropertyName

Field Detail

_componentNamesback to summary
private final Set<String> _componentNames

Names of actual Record components from definition; auto-detected.

Constructor Detail

AndroidRecordNamingback to summary
pack-priv AndroidRecordNaming(MapperConfig<?> config, AnnotatedClass forClass)

Method Detail

findNameForRegularGetterback to summary
public String findNameForRegularGetter(AnnotatedMethod am, String name)

Overrides com.fasterxml.jackson.databind.introspect.DefaultAccessorNamingStrategy.findNameForRegularGetter.

Doc from com.fasterxml.jackson.databind.introspect.AccessorNamingStrategy.findNameForRegularGetter.

Method called to find whether given method would be considered a "regular" getter method in context of type introspected, and if so, what is the logical property it is associated with (which in turn suggest external name for property)

Note that signature acceptability has already been checked (no arguments, does have a return value) by caller.

Note that this method MAY be called for potential "is-getter" methods too (before findNameForIsGetter)

Note that visibility checks are applied separately; strategy does not need to be concerned with that aspect.

Parameters
am:AnnotatedMethod

Method to check

name:String

Name to check (usually same as AnnotatedMethod#getName()

Returns:String

Implied property name for getter method, if match; null to indicate that the name does not conform to expected naming convention

Annotations
@Override