Gson TypeAdapterFactory
implementation for Java
Record classes (Java 16 feature). This project
was inspired by the discussion on Gson issue #1794.
ℹ️ Gson has since version 2.10 built-in support for Record classes. Usage of this separate type adapter factory is therefore not necessary anymore, unless you want to use the extended customization options this factory provides.
@SerializedName
on Record components@JsonAdapter
on Record components- Generic Record classes
(type resolution differs slightly from Gson's implementation, hopefully making it easier to use)
Currently this library is not published to Maven Central. You can either build the project locally or you can use JitPack as Maven repository serving this library.
When using JitPack it is recommended to put the jitpack.io repository last in the list of declared repositories for better performance and to avoid pulling undesired dependencies from it. When using Gradle as build tool you should also use repository content filtering:
repositories {
mavenCentral()
exclusiveContent {
forRepository {
maven {
url = uri("https://jitpack.io")
}
}
filter {
// Only use JitPack for the `gson-record-type-adapter-factory` library
includeModule("com.github.Marcono1234", "gson-record-type-adapter-factory")
}
}
}
This type adapter factory can either be used by registering it with a GsonBuilder
:
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(RecordTypeAdapterFactory.DEFAULT)
.create();
Or it can be referenced using a @JsonAdapter
annotation placed on a Record class:
@JsonAdapter(RecordTypeAdapterFactory.class)
record MyRecord(int i) { }
A customized type adapter factory can be created using RecordTypeAdapterFactory.builder()
.
See CHANGELOG.md
.
This project uses Gradle for building; just run:
./gradlew build
It is built against Java 17, but there is no need to manually install the correct JDK; Gradle's toolchain feature automatically downloads the needed JDK. Some IDEs do not support toolchains yet, so you might have to configure them manually.
This project uses the axion-release-plugin to create releases.
It is configured to automatically perform additional tasks, such as updating the changelog by
replacing the placeholder [Unreleased ???] - ???
with the version number and date.
A new release can be created with:
./gradlew release
This will automatically increment the version number. It is also possible to adjust how the version number is incremented or to force a version number.
Use -Prelease.dryRun
to perform a dry run.
- Using a type adapter factory as value for
@JsonAdapter
on a Record component and callingGson.getDelegateAdapter
inside the factory does not work correctly.
The underlying issue is a known bug in the implementation ofGson.getDelegateAdapter
. Hopefully that can be fixed in a way which also allows this type adapter factory to work correctly. - Record type adapter factory is not detected as being reflection-based by Gson's
TypeAdapterRuntimeTypeWrapper
.
Gson's internal classTypeAdapterRuntimeTypeWrapper
is used by the built-in reflection type adapter to decide whether for a given value of a field the runtime type adapter or the compile-time type adapter should be used. The intention is to prefer custom type adapters over reflection-based type adapters. So for example when a custom type adapter for classBase
exists and for its subclassSub
only the reflection-based adapter exists, thenBase
's adapter should be preferred. However, Gson does not recognize this Record type adapter factory as being reflection-based, so it will always prefer it over any adapter for the base class.
This issue can only occur when two or more type adapters for Record classes have been registered, so most use cases will be unaffected by this. - Gson field exclusion logic is not supported.
The standard Gson exclusion annotations@Expose
,@Since
and@Until
are not supported on record components and the relatedGsonBuilder
methods will have no effect because Gson does not expose this exclusion logic as public API. Using these annotations on components will cause an exception.
Similarly,ExclusionStrategy.shouldSkipField
implementations have no effect on the serialization and deserialization of Record components. - Reflection access filters are not considered.
Gson'sReflectionAccessFilter
is not considered to determine whether this Record type adapter may serialize or deserialize a Record class or make its canonical constructor or accessor methods accessible.
This project uses the MIT license; all contributions are implicitly under that license.