Another conjugate question: What is the process if...
# serialization
y
Another conjugate question: What is the process if I want to apply
@Serializable (with = customJavaSerializer.class)
annotation on a Java class? (I want to have both the class itself and the custom serializer defined in Java, but use them in Kotlin) I have tried define a Java class
Hello
, and then define a custom serializer
HelloSerializer
in Java. What is the field name or method name (like the
Impl
in the previous annotation example) should I give, so that the complier plugin can get access to my custom java serializer with
@Serializable
? Thank you very much.
e
probably you need a
static Companion INSTANCE;
and a
serializer()
method inside
Companion
, but this whole approach looks quite ill-advised to me. what is preventing you from defining the class in Kotlin?
y
The thing is we have a Java SDK first (all the annotations and classes are defined in Java), and then we add a Kotlin extension lib for it. Now, I want to provide Kotlin serialization for Kotlin SDK users, there seems no way I can make these Java class
@Serializable
unless 1) I use
@Contextual
, 2) Or I find out a way to apply
@Serializable
to the Java classes. Do you have any suggestions?
e
if you are adding references to serialization in your Java SDK, then it'll depend on Kotlin regardless
y
Following your suggestion, I am adding the
static Companion Instance
and
serializer()
in my
Hello.class
:
Copy code
@Serializable(with = HelloSerializer.class)
public final class Hello {
    public static final Hello.Companion INSTANCE = new Hello.Companion((DefaultConstructorMarker)null);

    public static final class Companion {
        private Companion() {
        }

        public Companion(DefaultConstructorMarker $constructor_marker) {
            this();
        }

        @NotNull
        public final KSerializer serializer() {
            return new HelloSerializer();
        }
    }


}
And this is my custom serializer:
Copy code
public final class HelloSerializer implements KSerializer<Hello> {

    @Override
    public Hello deserialize(@NonNull Decoder decoder) {
        return new Hello();
    }

    @NonNull
    @Override
    public SerialDescriptor getDescriptor() {
        return SerialDescriptorsKt.PrimitiveSerialDescriptor("Hello", (PrimitiveKind) PrimitiveKind.STRING.INSTANCE);
    }

    @Override
    public void serialize(@NonNull Encoder encoder, Hello hello) {
        encoder.encodeString("hello");
When I try to get `Hello`’s serializer from Kotlin, I got
NoSuchElementException
e
sorry
INSTANCE
is wrong, it's
Companion
- but I don't think this is a good idea anyway, it's possible future compiler plugin versions will require valid Kotlin metadata as well which you can't supply
y
We are trying to let our Java SDK only depend on the official
kotlin-serialization-core
library, but independent from our Kotlin extension library.
e
it'll depend on kotlin-stdlib transitively, and between that and writing Kotlin in your Java SDK directly there is no observable difference to Java consumers
y
I have changed
INSTANCE
to
Companion
, but still the same `NoSuchElementException`🤣.
e
🤷 I dunno then
if you really want to keep any reference to Kotlin out of the Java SDK, I think you will have to provide a SerializersModule in your Kotlin SDK to register all the contextual serializers
y
Thank you very much for your help, one caveat is that in our Java SDK, we are using compileOnly dependency, so Java user will not pay the size cost. One more thing to confirm, as you mentioned:
Copy code
I don't think it can be guaranteed that you  haven't missed anything that it might additionally depend on in the future
Is this plugin supposed to be backward compatible?
e
if it's compileOnly, then annotations are ok, but referencing
KSerializer
will fail when the class loads. you can't do that
y
Haha~~~
e
it's only expected to be backwards compatible to its own output
y
Thank you very much for your help~~