3

Using kotlin plugin 1.3.10 in Android Studio, when I try to stringify a simple class' object to JSON, it wont compile:

This declaration is experimental and its usage must be marked with '@kotlinx.serialization.ImplicitReflectionSerializer' or '@UseExperimental(kotlinx.serialization.ImplicitReflectionSerializer::class)'

@Serializable data class Data(val a: Int, val b: Int)
val data = Data(1, 2)
val x = JSON.stringify(data)

However, giving a serialiser works:

val x = JSON.stringify(Data.serializer(), data)

I can't see anybody else having this problem, any idea what the problem is? I've set up using serialisation in gradle.build.

I import with:

import kotlinx.serialization.*
import kotlinx.serialization.json.JSON
Tor Langballe
  • 54
  • 2
  • 8

1 Answers1

4

The overload of StringFormat.stringify which doesn't take in a serializer (SerializationStrategy) is still experimental. If you view its definition (e.g. ctrl+click on it in the IDE) you'll see it looks as follows:

@ImplicitReflectionSerializer
inline fun <reified T : Any> StringFormat.stringify(obj: T): String = stringify(context.getOrDefault(T::class), obj)

Where that ImplicitReflectionSerializer annotation is itself declared in that same file (SerialImplicits.kt):

@Experimental
annotation class ImplicitReflectionSerializer

So because it's still experimental, you need to do exactly as the warning says, i.e. tell the compiler to allow the use of experimental features, by adding an annotation such as @UseExperimental... where you're using it.

Note that the quick example shown on the kotlinx.serialization GitHub repo's main readme shows that you need to pass in a serializer when calling stringify.

Yoni Gibbs
  • 6,518
  • 2
  • 24
  • 37
  • Ah, OK. All the examples using it didn't mention it. However, when I annotate the function that uses it with @UseExperimental... , then functions that call that need to be annotated as well, all the way up to the top level I think. Is there a way to avoid this? – Tor Langballe Dec 07 '18 at 10:59
  • I'm not sure that's true. I just tried there and when I annotate `Class1.method1()` with `@UseExperimental` I can call it from `Class2.method2()` without annotating that second class/method with `@UseExperimental`. Are you getting different results? – Yoni Gibbs Dec 07 '18 at 11:18
  • In fact this is explicitly stated in the [documentation](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-use-experimental/index.html): "If a declaration is annotated with UseExperimental, its usages are **not** required to opt-in to that experimental API." – Yoni Gibbs Dec 07 '18 at 11:19
  • Thanks, just using. I was using '@kotlinx.serialization.ImplicitReflectionSerializer' '@UseExperimental(kotlinx.serialization.ImplicitReflectionSerializer::class)' – Tor Langballe Dec 07 '18 at 12:03