Kotlinx.serialization: java.lang.NoSuchMethodError when classes are in different modules

Created on 11 Oct 2019  路  32Comments  路  Source: Kotlin/kotlinx.serialization

Runtime Crash

java.lang.NoSuchMethodError: No direct method (ILkotlinx/serialization/SerializationConstructorMarker;)V in class Lcom/xxxx/common/core/Model; or its super classes (declaration of 'com.xxxx.common.core.Model' appears in /data/app/com.xxxx.demo-PV-n86-hzEl-eyc8UqbACQ==/base.apk!classes7.dex)
10-11 15:30:10.048 E/AndroidRuntime(25760): at com.xxxx.reg.data.User.(Unknown Source:9)
10-11 15:30:10.048 E/AndroidRuntime(25760): at com.xxxx.reg.data.User$$serializer.deserialize(Unknown Source:624)
10-11 15:30:10.048 E/AndroidRuntime(25760): at com.xxxx.reg.data.User$$serializer.deserialize(User.kt:17)
10-11 15:30:10.048 E/AndroidRuntime(25760): at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:33)

To Reproduce

@Serializable
abstract class Model(
var uniqueId: String = "",
}

@Serializable
data class User(
var userName: String = "",
var dateOfBirth: String = "",
) : Model()

Library A - Model
Library B - User

I am getting the above crash.

BUT if I move the Model from Library A to Library B NO issues.
[Just an FYI]
if the variable uniqueId from Model is removed no issue
if @Serializable is removed from Model no issues

Expected behavior
Not crash or throw fatal error.

Environment

  • Kotlin version: [e.g. 1.3.50]
  • Library version: [e.g. 0.13.0]

Updated Post with More comments and Link to Code - https://github.com/Kotlin/kotlinx.serialization/issues/576#issuecomment-637581639

bug compiler-plugin multi-project setup

Most helpful comment

Kotlin 1.3.61 and Kotlin Serialization 0.14.0 is working for me, but with Kotlin 1.3.70:

Caused by: java.lang.NoSuchMethodError: No direct method <init>(Ljava/lang/String;Lkotlinx/serialization/internal/GeneratedSerializer;I)V in class Lkotlinx/serialization/internal/SerialClassDescImpl; or its super classes (declaration of 'kotlinx.serialization.internal.SerialClassDescImpl' appears in /data/app/com.javiersc.gitGut-9pedF-cZ8kBfR8wDIz6hJg==/base.apk)
        at com.javiersc.gitGut.models.UserDTO$$serializer.<clinit>(UserDTO.kt:7)
        at com.javiersc.gitGut.models.UserDTO$Companion.serializer(Unknown Source:0)

All 32 comments

any update on this or verfied this as a known issue or has been fixed?

a class extended from either same library or a different library should yield same results.

Sorry, seems like this issue slipped out of my sight. Can confirm this bug on 1.3.60 with mutli-module (library/app) setup

@sandwwraith

Yes, this is still an issue.

We are using

Kotlin - 1.3.61
Kotlin Serialization - 0.14.0

Kotlin 1.3.61 and Kotlin Serialization 0.14.0 is working for me, but with Kotlin 1.3.70:

Caused by: java.lang.NoSuchMethodError: No direct method <init>(Ljava/lang/String;Lkotlinx/serialization/internal/GeneratedSerializer;I)V in class Lkotlinx/serialization/internal/SerialClassDescImpl; or its super classes (declaration of 'kotlinx.serialization.internal.SerialClassDescImpl' appears in /data/app/com.javiersc.gitGut-9pedF-cZ8kBfR8wDIz6hJg==/base.apk)
        at com.javiersc.gitGut.models.UserDTO$$serializer.<clinit>(UserDTO.kt:7)
        at com.javiersc.gitGut.models.UserDTO$Companion.serializer(Unknown Source:0)

I can confirm kotlin 1.3.70 is not compatible with serialization 0.14.0 as well.

I tried the last eap 0.20.0 and it is working

Yes, unfortunately, there's a breaking change in 1.3.70 plugin. We'll release compatible version of serialization in the following next few hours. Meanwhile, you can try eap builds from bintray: https://bintray.com/kotlin/kotlinx/kotlinx.serialization.runtime (e.g. 0.20.0-1.3.70-eap-274-2)

Hmm, even the latest 0.20.0 is still failing for me with "no direct method " error using Kotlin 1.3.70

Original issue, which is a bug, not an incompatibility with Kotlin, is still present. @JavierSegoviaCordoba's issue was #736

Updated the versions to

Kotlin - 1.3.70
Kotlin Serialization - 0.20.0

Confirming that Issue is still there.

@sandwwraith This issue is not the same as @JavierSegoviaCordoba is mentioning fixed.
This issue is rather an issue in the Serialization annotation processor which doesn't allow inheritance of the Serialization property when working in an multi module project and serialization property are failing to be serialized at runtime. As you can see it throws an java.lang.NoSuchMethod error as it cannot process
However while working in an non multi module project this issue of inheritance is not there. If it was an Kotlin issue it would have given in an non multi module project as well if I am not wrong

@sandwwraith Also I am not sure but I believe the fix would need @Inherit added in the @Serialzable annotation so that this can be inherited across modules

@Krondo The issue mentioned in #763 is not the same.

I had the same issue, any workaround on this ?

I might have a workaround..

kotlin: 1.3.70, kotlinx-serialization: 0.20.0

I was running my newly created project on IntelliJ ever since i got "java.lang.NoSuchMethodError". I figure out, kotlinx plugin is not get activated when I run my test classes in IDE. I need to run mvn clean compile and here we go;

[INFO] --- kotlin-maven-plugin:1.3.70:compile (compile) @ healthcheck ---
[INFO] Applied plugin: 'kotlinx-serialization'

so the serializer() function will be generated and exception will be gone right after you see the lines above. Hope it's solves your problem as well.

===

Edit: i'm still suffering when i move my data class to test module

This bug seems to happen only in JVM targets, I'm able to serialize/deserialize with no issues on my JS target but on my JVM target that bug happens.

In my case, I'm having this exception:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at kotlinx.serialization.SerializationKt.constructSerializerForGivenTypeArgs(Serialization.kt:40)
    at kotlinx.serialization.SerializationKt.compiledSerializerImpl(Serialization.kt:13)
    at kotlinx.serialization.PlatformUtilsKt.serializerOrNull(PlatformUtils.kt:34)
    at kotlinx.serialization.PlatformUtilsKt.serializer(PlatformUtils.kt:20)
    at kotlinx.serialization.modules.SerialModuleExtensionsKt.getContextualOrDefault(SerialModuleExtensions.kt:26)
    at net.perfectdreams.loritta.website.routes.api.v1.loritta.TestKt.main(Test.kt:23)
    at net.perfectdreams.loritta.website.routes.api.v1.loritta.TestKt.main(Test.kt)
Caused by: java.lang.NoSuchMethodError: kotlinx.serialization.internal.SerialClassDescImpl.<init>(Ljava/lang/String;Lkotlinx/serialization/internal/GeneratedSerializer;)V
    at net.perfectdreams.loritta.datawrapper.Background$$serializer.<clinit>(Background.kt:7)
    at net.perfectdreams.loritta.datawrapper.Background$Companion.serializer(Background.kt)
    ... 11 more

Edit: Changing kotlinx.serialization and Kotlin libs to 1.3.70 fixed my issue: https://stackoverflow.com/questions/61259946/receiving-noclassdeffounderror-when-invoking-generated-serializer-method/61259947#61259947

kotlin: 1.3.70, kotlinx-serialization: 0.20.0

Fixed my issue

I see how ppl are commenting that the issues are fixed in latest kotlin and kotlin serilzation plugin. Let me remind you guys to please understand the issue before commenting it's fixed and stop misleading everyone.

And NO THIS ISSUE is not fixed in kotlin: 1.3.70, kotlinx-serialization: 0.20.0

Changing the Kotlin version forces clean building, which fixes the issue sometimes (when it's caused by incremental compilation in one module).

@sandwwraith

Issue is NOT fixed.
Tested:
Kotlin 1.3.72
kotlinx-serialization: 0.20.0

I have pushed test code outlined in original post https://github.com/Kotlin/kotlinx.serialization/issues/576#issue-506005603 in this repo below.

https://github.com/lallam/broke.git

(A) if you compile above code and run AS-IS, app crashes at line 32 during deserialization in MainActivity [it is a very simple code]

(B) to illustrate the multi project/module inheritance and deserialization issue.

in libraryb, i have created a duplicate class ModelX (Same as Model from LibraryA) , and inherited the User class

User - if you uncomment line 8 and comment line 9. problem goes away.

serialize/deserialize should work regardless of, if Parent class is in
(A) Different library or (B) Same library.

At the moment.
(A) - Doesn't work
(B) - Works.

I'm new to android. @lallam, can you (or anyone) ELI5 how to set kotlinx-serialization?

My build script is:

buildscript {
    ext.kotlin_version = '1.3.70'
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

build.gradle:app is dependencies:



dependencies {
    ...
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
}

and my variable values are
serialization_version set to 0.20.0
kotlin_version set to 1.3.70


UPDATE: I guess it's no mystery on how to set kotlinx-serialization, but I am still getting the error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: gtink.deere.com.hammlink, PID: 5067
            java.lang.NoSuchFieldError: No field Companion of type Lkotlinx/serialization/json/Json$Companion; in class Lkotlinx/serialization/json/Json; or its superclasses (declaration of 'kotlinx.serialization.json.Json' appears in /data/app/~~RUbPhu7SrnGhEv-E3WOq3A==/PROJ.FOLDERS.com.***-NvjPkuiwQNXcO5VogochCg==/base.apk!classes3.dex)

Kotlin 1.3.72
kotlinx-serialization: 0.20.0
java.lang.NoSuchMethodError: No direct method (ILkotlinx/serialization/SerializationConstructorMarker;)V

still occurs

Is there any progress on this one? This issue drives the library completly useless...

Reference: https://github.com/Kotlin/kotlinx.serialization/issues/576#issue-506005603
https://github.com/Kotlin/kotlinx.serialization/issues/576#issuecomment-637581639

this has become a critical issue for us. we are currently using a VERY crude method to over come this temporarily.

Library A - Model

Library B - Model extends LibraryA.Model
- User extends LibraryB.Model

Library C - Model extends LibraryA.Model
- Device extends LibraryC.Model

Model classes in LibraryB and LibraryC are identical to LibraryA.Model and override the members.
We are hoping that once the issue is fixed, we could DELETE these duplicate classes and extend User and Device classes directly from LibraryA.Model.

or other alternative is to abandon kotlin serialization altogether and refactor it to a different Library. fingers crossed.

thanks @sandwwraith we will test and confirm.

Hello, this is happening to me with Kotlin 1.4 and org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.0.0-RC which is included in Retrofit kotlinx serialization converter dependency (I could not use org.jetbrains.kotlinx:kotlinx-serialization-runtime-jvm:1.0-M1-1.4.0-rc since it creates dependency conflict).

@IgnacioGarcia198 Do you have a sample project with reproducer?

@sandwwraith I posted a project in my GitHub repository in order to reproduce it. Here is the link.
https://github.com/IgnacioGarcia198/BikeSharing-Android
If you try the test SerializationTest.kt, you will see it is working, but when you run the app the problem is with Retrofit. Please if you notice something I am doing wrong tell me ;)

Any update on this issue or example workaround? I'm experiencing this also in 1.4.10

maybe it has something to do with proguard obfuscation?

@IgnacioGarcia198 don't use the serializer factory of retrofit instead accept the Retrofit response as Response Body objects and the write your own serializing extension api and convert the response body received to the required module using the modules serializer using kotlin serialization.

Was this page helpful?
0 / 5 - 0 ratings