Releases: Kotlin/kotlinx.serialization
1.5.1
This release contains an important Native targets overhaul, as well as numerous enhancements and bugfixes.
Kotlin 1.8.21 is used by default.
New set of Native targets
The official Kotlin target support policy has recently been published describing new target policy: each target belongs to a certain tier, and different tiers have different stability guarantees. The official recommendation for library authors is to support targets up to Tier 3, and kotlinx.serialization now follows it. It means that in this release, there are a lot of new targets added from this tier, such as androidNativeX86
or watchosDeviceArm64
. Note that since they belong to Tier 3, they're not auto-tested on CI.
kotlinx.serialization also ships some deprecated Kotlin/Native targets that do not belong to any tier (e.g. iosArm32
, mingwX86
).
We'll continue to release them, but we do not provide support for them, nor do we plan to add new targets from the deprecated list.
Improvements in Json elements
There are two new function sets that should make creating raw Json elements easier.
First one contains overloads for JsonPrimitive
constructor-like function that accept unsigned types: JsonPrimitive(1u)
.
Second one adds new addAll
functions to JsonArrayBuilder
to be used with collections of numbers, booleans or strings: buildJsonArray { addAll(listOf(1, 2, 3)) }
.
Both were contributed to us by aSemy.
Other enhancements
- Potential source-breaking change: Rename json-okio
target
variables tosink
(#2226) - Function to retrieve KSerializer by KClass and type arguments serializers (#2291)
- Added FormatLanguage annotation to Json methods (#2234)
- Properties Format: Support sealed/polymorphic classes as class properties (#2255)
Bugfixes
- KeyValueSerializer: Fix missing call to endStructure() (#2272)
- ObjectSerializer: Respect sequential decoding (#2273)
- Fix value class encoding in various corner cases (#2242)
- Fix incorrect json decoding iterator's .hasNext() behavior on array-wrapped inputs (#2268)
- Fix memory leak caused by invalid KTypeWrapper's equals method (#2274)
- Fixed NoSuchMethodError when parsing a JSON stream on Java 8 (#2219)
- Fix MissingFieldException duplication (#2213)
1.5.0
This release contains all features and bugfixes from 1.5.0-RC plus some experimental features and bugfixes on its own (see below).
Kotlin 1.8.10 is used as a default.
HoconEncoder and HoconDecoder interfaces and HOCON-specific serializers
These interfaces work in a way similar to JsonEncoder
and JsonDecoder
: they allow intercepting (de)serialization process,
making writing if custom HOCON-specific serializers easier. New ConfigMemorySizeSerializer
and JavaDurationSerializer
already make use of them.
See more details in the PR.
Big thanks to Alexander Mikhailov for contributing this!
Ability to read buffered huge strings in custom Json deserializers
New interface ChunkedDecoder
allows you to read huge strings that may not fit in memory by chunks.
Currently, this interface is only implemented by Json decoder that works with strings and streams,
but we may expand it later, if there's a demand for it.
See more details in the PR authored by Alexey Sviridov.
Bugfixes
1.5.0-RC
This is a release candidate for the next version with many new features to try.
It uses Kotlin 1.8.0 by default.
Json naming strategies
A long-awaited feature (#33) is available in this release.
A new interface, JsonNamingStrategy
and Json configuration property namingStrategy
allow
defining a transformation that is applied to all properties' names serialized by a Json instance.
There's also a predefined implementation for the most common use case: Json { namingStrategy = JsonNamingStrategy.SnakeCase }
.
Check out the PR for more details and documentation.
Json unquoted literals
kotlinx-serialization-json has an API for manipulating raw Json values: functions and classes JsonObject
, JsonPrimitive
, etc.
In this release, there is a new addition to this API: JsonUnquotedLiteral
constructor function.
It allows to produce a string that is not quoted in the Json output. This function has a lot of valuable
applications: from writing unsigned or large numbers to embedding whole Json documents without the need for re-parsing.
For an example, read the Encoding literal Json content docs.
This huge feature was contributed to us by aSemy: #2041.
Stabilization of serializer(java.lang.Type) function family
Functions serializer
, serializerOrNull
and extensions SerializersModule.serializer
, SerializersModule.serializerOrNull
have JVM-only overloads that accept java.lang.Type
. These overloads are crucial for interoperability: with them, third-party Java frameworks
like Spring, which usually rely on Java's reflection and type tokens, can retrieve KSerializer
instance and use kotlinx.serialization properly.
We've removed @ExperimentalSerializationApi
from these functions, and starting from 1.5.0-RC they're considered stable with all backward compatibility guarantees.
This change should improve third-party support for kotlinx.serialization in various frameworks.
See the PR for details.
Deprecations in module builders for polymorphism
Some time ago, in 1.3.2, new functions SerializersModuleBuilder.polymorphicDefaultSerializer/polymorphicDefaultDeserializer
and PolymorphicModuleBuilder.defaultDeserializer
were introduced
— better names allow an easier understanding of which serializers affect what part of the process.
In 1.5.0-RC, we finish the migration path: these functions are no longer experimental.
And old functions, namely SerializersModuleCollector.polymorphicDefault
and PolymorphicModuleBuilder.default
, are now deprecated.
See the PR for details.
Bundled Proguard rules
The kotlinx-serialization-core-jvm
JAR file now includes consumer Proguard rules,
so manual Proguard configuration is no longer necessary for most of the setups.
See updated Android setup section and corresponding PRs: #2092, #2123.
Support for kotlin.Duration in HOCON format
HOCON specifies its own formatting for duration values. Starting with this release,
kotlinx-serialization-hocon is able to serialize and deserialize kotlin.Duration
using proper representation instead of the default one. Big thanks to Alexander Mikhailov
and his PRs: #2080, #2073.
Functional and performance improvements
- Make DeserializationStrategy covariant at declaration-site (#1897) (thanks to Lukellmann)
- Added support for the
kotlin.Nothing
class as built-in (#1991, #2150) - Further improve stream decoding performance (#2101)
- Introduce CharArray pooling for InputStream decoding (#2100)
- Consolidate exception messages and improve them (#2068)
Bugfixes
- Add stable hashCode()/equals() calculation to PrimitiveSerialDescriptor (#2136) (thanks to Vasily Vasilkov)
- Added a factory that creates an enum serializer with annotations on the class (#2125)
- Correctly handle situation where different serializers can be provided for the same KClass in SealedClassSerializer (#2113)
- Fixed serializers caching for parametrized types from different class loaders (#2070)
1.4.1
This patch release contains several bug fixes and improvements.
Kotlin 1.7.20 is used by default.
Improvements
- Add @MustBeDocumented to certain annotations (#2059)
- Deprecate .isNullable in SerialDescriptor builder (#2040)
- Unsigned primitives and unsigned arrays serializers can be retrieved as built-ins (#1992)
- Serializers are now cached inside reflective lookup, leading to faster serializer retrieval (#2015)
- Compiler plugin can create enum serializers using static factories for better speed (#1851) (Kotlin 1.7.20 required)
- Provide a foundation for compiler plugin intrinsics available in Kotlin 1.8.0 (#2031)
Bugfixes
- Support polymorphism in Properties format (#2052) (thanks to Rodrigo Vedovato)
- Added support of UTF-16 surrogate pairs to okio streams (#2033)
- Fix dependency on core module from HOCON module (#2020) (thanks to Osip Fatkullin)
1.4.0
1.4.0-RC
This is a candidate for the next big release with many new exciting features to try.
It uses Kotlin 1.7.10 by default.
Integration with Okio's BufferedSource and BufferedSink
Okio library by Square is a popular solution for fast and efficient IO operations on JVM, K/N and K/JS.
In this version, we have added functions that parse/write JSON directly to Okio's input/output classes, saving you the overhead of copying data to String
beforehand.
These functions are called Json.decodeFromBufferedSource
and Json.encodeToBufferedSink
, respectively.
There's also decodeBufferedSourceToSequence
that behaves similarly to decodeToSequence
from Java streams integration, so you can lazily decode multiple objects the same way as before.
Note that these functions are located in a separate new artifact, so users who don't need them wouldn't find themselves dependent on Okio.
To include this artifact in your project, use the same group id org.jetbrains.kotlinx
and artifact id kotlinx-serialization-json-okio
.
To find out more about this integration, check new functions' documentation and corresponding pull requests:
#1901 and #1982.
Inline classes and unsigned numbers do not require experimental annotations anymore
Inline classes and unsigned number types have been promoted to a Stable feature in Kotlin 1.5,
and now we are promoting support for them in kotlinx.serialization to Stable status, too.
To be precise, we've removed all @ExperimentalSerializationApi
annotations from functions related to inline classes encoding and decoding,
namely SerialDescriptor.isInline
, Encoder.encodeInline
, and some others. We've also updated related documentation article.
Additionally, all @ExperimentalUnsignedTypes
annotations were removed completely,
so you can freely use types such as UInt
and their respective serializers as a stable feature
without opt-in requirement.
Part of SerializationException's hierarchy is public now
When kotlinx.serialization 1.0 was released, all subclasses of SerializationException
were made internal,
since they didn't provide helpful information besides the standard message.
Since then, we've received a lot of feature requests with compelling use-cases for exposing some of these internal types to the public.
In this release, we are starting to fulfilling these requests by making MissingFieldException
public.
One can use it in the catch
clause to better understand the reasons of failure — for example, to return 400 instead of 500 from an HTTP server — and then use its fields
property to communicate the message better.
See the details in the corresponding PR.
In future releases, we'll continue work in this direction, and we aim to provide more useful public exception types & properties.
In the meantime, we've revamped KDoc for some methods regarding the exceptions — all of them now properly declare which exception types are allowed to be thrown.
For example, KSerializer.deserialize
is documented to throw IllegalStateException
to indicate problems unrelated to serialization, such as data validation in classes' constructors.
@MetaSerializable annotation
This release introduces a new @MetaSerializable
annotation that adds @Serializable
behavior to user-defined annotations — i.e., those annotations would also instruct the compiler plugin to generate a serializer for class. In addition, all annotations marked with @MetaSerializable
are saved in the generated @SerialDescriptor
as if they are annotated with @SerialInfo
.
This annotation will be particularly useful for various format authors who require adding some metadata to the serializable class — this can now be done using a single annotation instead of two, and without the risk of forgetting @Serializable
. Check out details & examples in the KDoc and corresponding PR.
Note: Kotlin 1.7.0 or higher is required for this feature to work.
Moving documentation from GitHub pages to kotlinlang.org
As a part of a coordinated effort to unify kotlinx libraries users' experience, Dokka-generated documentation pages (KDoc) were moved from https://kotlin.github.io/kotlinx.serialization/ to https://kotlinlang.org/api/kotlinx.serialization/. No action from you is required — there are proper redirects at the former address, so there is no need to worry about links in your blogpost getting obsolete or broken.
Note that this move does not affect guides written in Markdown in the docs
folder. We aim to move them later, enriching text with runnable examples as in the Kotlin language guides.
Other improvements
- Allow Kotlin's null literal in JSON DSL (#1907) (thanks to Lukellmann)
- Stabilize EmptySerializersModule (#1921)
- Boost performance of polymorphic deserialization in optimistic scenario (#1919)
- Added serializer for the
kotlin.time.Duration
class (plugin support comes in Kotlin 1.7.20) (#1960) - Support tagged not null marks in TaggedEncoder/Decoder (#1954) (thanks to EdwarDDay)
Bugfixes
- Support quoting unsigned integers when used as map keys (#1969)
- Fix protocol buffer enum schema generation (#1967) (thanks to mogud)
- Support diamond inheritance of sealed interfaces in SealedClassSerializer (#1958)
- Support retrieving serializer for sealed interface (#1968)
- Fix misleading token description in JSON errors (#1941) (thanks to TheMrMilchmann)
1.3.3
This release contains support for Protocol Buffers packed fields, as well as several bugfixes.
It uses Kotlin 1.6.21 by default.
Protobuf packed fields
It is now possible to encode and decode Kotlin classes to/from Protobuf messages with packed repeated fields.
To mark the field as packed, use @ProtoPacked
annotation on it.
Note it affects only List
and primitive collection such as IntArray
types.
With this feature, it is now possible to decode Proto3 messages, where all repeated fields are packed by default.
Protobuf schema generator also supports new @ProtoPacked
annotation.
Many thanks to Paul de Vrieze for his valuable contribution!
Other improvements & small features
- Incorporate JsonPath into exception messages (#1841)
- Mark block in corresponding encodeStructure/decodeStructure extensions as crossinline to reduce amount of bytecode (#1917)
- Support serialization of compile-time
Collection<E>
properties that are not lists at the runtime (#1821) - Best-effort kotlin reflect avoidance in serializer(Type) (#1819)
Bugfixes
1.3.2
This release contains several features and bugfixes for core API as well as for HOCON format.
It uses Kotlin 1.6.10 by default.
Serializing objects to HOCON
It's now possible to encode Kotlin objects to Config
values with new Hocon.encodeToConfig
function.
This feature may help edit existing configs inside Kotlin program or generate new ones.
Big thanks to Osip Fatkullin for implementing this.
Polymorphic default serializers
As of now, polymorphicDefault
clause inside SerializersModule { }
builder specifies a
fallback serializer to be used only during deserialization process. A new function has been introduced to allow setting
fallback serializer for serialization: polymorphicDefaultSerializer
.
This function should ease serializing vast hierarchies of third-party or Java classes.
Note that there are two new experimental functions, polymorphicDefaultSerializer
and polymorphicDefaultDeserializer
.
To avoid naming confusion, we are going to deprecate polymorphicDefault
in favor of polymorphicDefaultDeserializer
in the next minor release (1.4.0).
Credit for the PR goes to our contributor Joseph Burton.
Other improvements
- HOCON: parse strings into integers and booleans if possible (#1795) (thanks to tobiaslieber)
- Add an encodeCollection extensions (#1749) (thanks to Nicklas Ansman Giertz)
Bugfixes
1.3.1
This release mainly contains bugfixes for 1.3.0 and provides new experimental Json.decodeToSequence
function.
Improvements
- Provide decodeToSequence to read multiple objects from stream lazily (#1691)
Bugfixes
- Correctly handle buffer boundaries while decoding escape sequences from json stream (#1706)
- Properly skip unknown keys for objects and structures with zero properties (#1720)
- Fix merging for maplikeSerializer when the map is not empty (by using the actual size * 2). (#1712) (thanks to pdvrieze)
- Fix lookup of primitive array serializers by Java type token (#1708)
1.3.0
This release contains all of the cool new features from 1.3.0-RC as well as minor improvements.
It uses Kotlin 1.5.31 by default.
Bugfixes and improvements
- Promote JsonConfiguration and its usages to stable (#1690)
- Remove opt-in annotations from SerialFormat, StringFormat, BinaryFormat (#1688)
- Correctly throw SerializationException instead of IOOBE for some cases with EOF in streams (#1677)
- CBOR: ignore tags when reading (#1614) (thanks to David Robertson)