Kotlin / kotlinx.serialization

Kotlin multiplatform / multi-format serialization
Apache License 2.0
5.36k stars 619 forks source link

Android, Gradle, Serialization plugin is incompatible with Kotlin Android plugin 1.9.20 #2508

Closed lifestreamy closed 9 months ago

lifestreamy commented 10 months ago

When choosing either

the

@Serializable annotation on this simple class

@Serializable
data class SomeDataClass(val a: Int)

is highlighted with a warning: "kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project."

To Reproduce

In other words, in the top-level build.gradle file, This setup leads to the error:

plugins {
    id("com.android.application") version "8.2.0-rc01" apply false
    id("org.jetbrains.kotlin.android") version "1.9.20" apply false
    id("com.google.devtools.ksp") version "1.9.20-1.0.14" apply false
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.10" apply false
}

, and this setup leads to the error:

plugins {
    id("com.android.application") version "8.2.0-rc01" apply false
    id("org.jetbrains.kotlin.android") version "1.9.10" apply false
    id("com.google.devtools.ksp") version "1.9.20-1.0.14" apply false
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.20" apply false
}

, and this setup leads to the error:

plugins {
    id("com.android.application") version "8.2.0-rc01" apply false
    id("org.jetbrains.kotlin.android") version "1.9.20" apply false
    id("com.google.devtools.ksp") version "1.9.20-1.0.14" apply false
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.20" apply false
}

And this setup works as expected (at least there is no warning)

plugins {
    id("com.android.application") version "8.2.0-rc01" apply false
    id("org.jetbrains.kotlin.android") version "1.9.10" apply false
    id("com.google.devtools.ksp") version "1.9.20-1.0.14" apply false
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.10" apply false
}

Notice how in the working example both "org.jetbrains.kotlin.android" and "org.jetbrains.kotlin.plugin.serialization" plugin versions are 1.9.10

Expected behavior There should be no error and the serialization plugin should be applied when using versions of it and Kotlin of 1.9.20

Environment

linean commented 10 months ago

I can add it's not only about annotation warning. Generated serializers are not resolved by the IDE (but code compiles).

image
mcmouse88 commented 10 months ago

I've faced with the same problem, is there any solution?

pdvrieze commented 10 months ago

When you use "apply false" you are only loading the plugin in to memory, but not applying it. The plugin should be applied (as that will generate the serializer). There could be plugin conflicts though with KSP as that also applies a compiler plugin, but that shouldn't really happen.

linean commented 10 months ago

@pdvrieze In my example I apply plugin like that

build.gradle.kts (project level)
plugins {
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.20" apply false
}

build.gradle.kts (module level)
plugin {
    kotlin("plugin.serialization")
}

I think that's the correct way to apply plugin when you want to share version across modules.

pdvrieze commented 10 months ago

@linean That would be valid. It wasn't clear from your bug report though. And it is helpful to know what you are doing specifically. What happens if you disable ksp? Does the plugin apply properly in that case. As both ksp and serialization are compiler plugins they need to match the kotlin language/compiler version.

linean commented 10 months ago

It's not really related to KSP for me. I've set up a sample project so you can check it out and see the issue: https://github.com/linean/kotlinx.serialization-issue

pdvrieze commented 10 months ago

This is really weird. In the test project, if I run a ./gradlew clean asssembleDebug it works correctly. (The main application runs and the serializer is present/working - I changed the code to actually serialize to json). Do you have some caches interfering? Maybe the configuration cache? What platform/OS are you using? Which JDK version? (I tried it on Linux/JDK 17).

I didn't get any problems with the IDE either (Both Intellij 2023.2.5 and AS Iguana 2023.2.1 Canary 14). In AS it uses kotlin plugin: 232-1.9.0-release-358-AS10227.8.2321.11110254. Intellij also has the latest stable plugin (232-1.9.20-release-507-IJ10072.27).

linean commented 10 months ago

There is no problem with code compilation or running the application. This issue is about IDE not resolving serializers and displaying warning for the annotation. I kindly ask @mcmouse88 and @lifestreamy to check if you can reproduce the issue in my sample project.

@pdvrieze my IDE specs:

Android Studio Giraffe | 2022.3.1 Patch 4
Build #AI-223.8836.35.2231.11090377, built on November 13, 2023
Runtime version: 17.0.6+0-17.0.6b829.9-10027231 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 13.4.1

My friends can reproduce it on their systems, leading me to believe that a cache-related problem can be ruled out.

equeim commented 10 months ago

I have the same issue with Android Studio 2022.3.1 Patch 4 (also on macOS but idk it that's related).

pdvrieze commented 10 months ago

Trying to open the project on Giraffe (2022.3.1 Patch 4) it indeed fails (LInux, so OS doesn't seem to matter). I suspect this is a bug/incompatibility with older Intellij versions (the 2022.3.1 part of the Android Studio version). Note that the compiler plugin (and the corresponding IDE plugin) are managed through YouTrack.

lifestreamy commented 10 months ago

When you use "apply false" you are only loading the plugin in to memory, but not applying it. The plugin should be applied (as that will generate the serializer). There could be plugin conflicts though with KSP as that also applies a compiler plugin, but that shouldn't really happen.

@pdvrieze yes, of course I apply all the plugins in the module-level build.gradle, otherwise even the 1.9.10 + 1.9.10 combination would not have worked.

@linean

lifestreamy commented 10 months ago

There is no problem with code compilation or running the application. This issue is about IDE not resolving serializers and displaying warning for the annotation. I kindly ask @mcmouse88 and @lifestreamy to check if you can reproduce the issue in my sample project.

@pdvrieze my IDE specs:

Android Studio Giraffe | 2022.3.1 Patch 4
Build #AI-223.8836.35.2231.11090377, built on November 13, 2023
Runtime version: 17.0.6+0-17.0.6b829.9-10027231 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 13.4.1

My friends can reproduce it on their systems, leading me to believe that a cache-related problem can be ruled out.

@linean I've just tried you project. It does compile.

The annotation is still highlighted, the .serializer() is unresolved.

Running main gives an error

Error: Could not find or load main class com.serialization.issue.MainKt
Caused by: java.lang.ClassNotFoundException: com.serialization.issue.MainKt

Process finished with exit code 1

But a unit test with it has passed: testSerialize()

EDIT: after having launched the unit test the main function runs successfully for some reason. image

mcmouse88 commented 10 months ago

image_large jack @linean it has been reproduced )

Android Studio Giraffe | 2022.3.1 Patch 1
Build #AI-223.8836.35.2231.10671973, built on August 17, 2023
Runtime version: 17.0.6+0-17.0.6b829.9-10027231 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Linux 5.15.0-88-generic
Cores: 8

Current Desktop: X-Cinnamon
lifestreamy commented 10 months ago

@mcmouse88

I don't think this error is related to the problem with serialization plugin but rather to some initial project configuration and probably some file paths misaligned.

Try running a unit test first:

class ExampleUnitTest {

    @Serializable
    data class SomeDataClass(val a: Int)

    @Test
    fun testSerialize(){
        println(SomeDataClass.serializer())
    }
}
linean commented 10 months ago

@mcmouse88 Try to build project before you run main(). I should've mention that in my example 😅

carstenhag commented 10 months ago

Edit: I have tried out a bit more and I am also getting this with 1.9.0 and 1.9.10, so I guess this is not related to the original issue. My colleague pointed me to https://github.com/Kotlin/kotlinx.serialization/issues/2385#issuecomment-1764839583.

We are also facing this issue. AS Hedgehog 2023.1.1 RC 3, Kotlin/Serialization 1.9.20. The IDE is saying: kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project.

At runtime it only is a problem when using minification/proguard/r8 (setting: android.enableR8.fullMode = false). When trying to use

@Serializable
data class OtpCodeRequestDto(
    @SerialName("phoneNumber")
    val phoneNumber: String,
)

as request body in a Retrofit call, with r8 minification on, we are getting these exceptions:

Failed to request OTP code: java.lang.IllegalArgumentException: Unable to create converter for class java.lang.Object
    for method IMfaApi.requestOtpCode
java.lang.IllegalArgumentException: Unable to create converter for class java.lang.Object
    for method IMfaApi.requestOtpCode
    at retrofit2.Utils.methodError(Utils.java:54)
    at retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:126)
    at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:85)
    at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
    at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
    at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy5.requestOtpCode(Unknown Source)
    at com.bmw.chargenow.data.auth.OtpRepository.requestOtp(OtpRepository.kt:39)
mcmouse88 commented 10 months ago

@mcmouse88 Try to build project before you run main(). I should've mention that in my example 😅

it seems like I had built it before. There is still the error persisting in my project, and I'm hesitant to deploy it to the production.

mcmouse88 commented 10 months ago

My fault, yes, I forgot to build your project. Now, launch passes with code 0, but the error is displayed so far

ammargitham commented 10 months ago

Not sure if this issue is awaiting more info, but even I started getting

kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project.

warning for all @Serializable annotations since upgrading kotlinx.serialization to 1.6.1 and kotlin to 1.9.20.

Although serialization does seem to work without problems.

You can find my project at https://github.com/ammargitham/WallFlow/, the dependency update commit is https://github.com/ammargitham/WallFlow/commit/8cbbe35c02f7afa6aeb23c417b814e14b14f54de.

Jdbarad commented 10 months ago

It's Working on the below Environment:- Kotlin version: [1.9.0] Plugin version: [1.9.0] Kotlin platforms: [JVM] Gradle version: [8.2] IDE: Android Studio Giraffe | 2022.3.1 Patch 4

it's not the latest version but for now, we can use it.

lifestreamy commented 10 months ago

It's Working on the below Environment:- Kotlin version: [1.9.0] Plugin version: [1.9.0] Kotlin platforms: [JVM] Gradle version: [8.2] IDE: Android Studio Giraffe | 2022.3.1 Patch 4

it's not the latest version but for now, we can use it.

@Jdbarad 1.9.10 versions of both plugins work correctly together without giving any warnings. You, of course, can downgrade to 1.9.0 or 1.3.0 or whatever though, it is your choice.

Maybe the new releases with plugin versions 2.0.0+ will work as expected.

The current latest version for both plugins is 2.0.0-Beta1, I've not tested it.

dpasirst commented 10 months ago

Apologies in advance if this is a different issue - given the thread it seems to be connected so I'll share here.

I too am experiencing the kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project. and .serializer() not being available.

In my setup, I have an android project with app module and a second module library that requires serialization. After trying many combinations, I found the following seems to have worked:

In this setup, the test from @lifestreamy above did work.

A few other notes, using 1.9.20 and/or 1.6.1 does not work and results in the error message already mentioned. Second, I'm not sure if this setup is valid or going to cause other problems...

lifestreamy commented 10 months ago

@dpasirst hi.

  1. I am not sure about the need for the kotlin("jvm") one, you could have just changed the version of the kotlin.android plugin to 1.9.10 from 1.9.21.
  2. The order does not matter for the plugins in the plugins{} blocks.
  3. Better always declare all the plugins with their versions in the project-level gradle file (strictly with apply false), then just add the individual plugins in plugins{} blocks of each module where they are needed. That way you will have a consistent plugin version across all the modules that apply it.

No other problems with your current setup.

dpasirst commented 10 months ago

@lifestreamy Thank you! kotlin.android as 1.9.10 then removing `kotlin("jvm") did indeed work.

Regarding

Better always declare all the plugins with their versions in the project-level gradle file (strictly with apply false), then just add the individual plugins in plugins{} blocks of each module where they are needed. That way you will have a consistent plugin version across all the modules that apply it.

Just want to be 100% sure I understand your suggestion. Is it to add kotlin("plugin.serialization") version "1.9.10" apply false to the build.gradle.kts project then in the build.gradle.kts module add only kotlin("plugin.serialization")? That does seem to work and appears much cleaner... Thank You!

lifestreamy commented 10 months ago

@dpasirst yes, that is correct. You are welcome!

sandwwraith commented 10 months ago

Just a quick question before I jump into issue investigation — is this issue specific to Android Studio 2023.1? Does IDEA and other versions of AS import 1.9.20 correctly? Did you try to report this to Google or YouTrack? For now, it looks to me like IDE import problem and not serialization problem.

linean commented 10 months ago

For me issue is gone in the following IDEA:

IntelliJ IDEA 2023.2.5 (Community Edition)
Build #IC-232.10227.8, built on November 9, 2023
Runtime version: 17.0.9+7-b1000.46 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 13.4.1
Kotlin: 232-1.9.20-release-507-IJ10072.27

Based on the previous messages bug happens in Android Studio Giraffe 2022.3.1 and Android Studio Hedgehog 2023.1.1 RC 3

lifestreamy commented 10 months ago

For me issue is gone in the following IDEA:

IntelliJ IDEA 2023.2.5 (Community Edition)
Build #IC-232.10227.8, built on November 9, 2023
Runtime version: 17.0.9+7-b1000.46 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 13.4.1
Kotlin: 232-1.9.20-release-507-IJ10072.27

Based on the previous messages bug happens in Android Studio Giraffe 2022.3.1 and Android Studio Hedgehog 2023.1.1 RC 3

Yes. And I have just tested in IDEA 2023.2.5 (232.10227.8) and there is indeed no bug (with 'org.jetbrains.kotlin.jvm' version 1.9.20 plugin)

oxyroid commented 10 months ago

using 1.9.20 in Android Studio Hedgehog 2023.1.1 not work as well.

sandwwraith commented 9 months ago

Apparently, the issue is caused by a bug in the Kotlin 1.9.10 IDE plugin (not the Gradle plugin). It is described here: https://youtrack.jetbrains.com/issue/KTIJ-10755

To fix this problem, you need to update the Kotlin IDE plugin. Unfortunately, 1.9.20 IDE plugin version is not available for Hedgehog 2023.1.1 yet. There are two ways to fix it:

  1. Go to Settings -> Languages & Frameworks -> Kotlin or invoke action Configure Kotlin plugin updates. Select EAP channel in the window and update to 1.9.20-RC2 (per https://youtrack.jetbrains.com/issue/KTIJ-10755/HMPP-IDE-False-PLUGINISNOTENABLED-in-IDE-for-kotlinx-serialization-plugin-however-project-builds-correctly#focus=Comments-27-8389206.0-0)
  2. Update to Android Studio Iguana 2023.2.1 Canary or Intellij IDEA 2023.3 that have Kotlin 1.9.20 pre-installed.
PakuKim commented 9 months ago

For me, Fixed when removed Retrofit converter API. Guess Retrofit Gson library was conflicted with kotlinxSerialization plugins

varelycode commented 9 months ago

For me, using setting kotlin serialization to "1.6.2" fixed it after having enabled 1.9.20 EAP within Android Studio Hedgehog 2023.1.1

risalfajar commented 7 months ago

Using 1.9.20-RC2 IDE Plugin in Android Studio Hedgehog breaks Jetpack Compose Live Edit feature

Demoulidor commented 3 weeks ago

@pdvrieze In my example I apply plugin like that

build.gradle.kts (project level)
plugins {
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.20" apply false
}

build.gradle.kts (module level)
plugin {
    kotlin("plugin.serialization")
}

I think that's the correct way to apply plugin when you want to share version across modules.

It's not work for me.

My gradle's plugins are these:

build.gradle.kts (project level) plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.jetbrains.kotlin.android) apply false id("org.jetbrains.kotlin.plugin.serialization") version "1.9.20" apply false }

build.gradle.kts (module level) plugins { id("com.android.application") id("org.jetbrains.kotlin.android") kotlin("plugin.serialization") }