kotlinx.serialization: R8 task fails with missing StringConcatFactory when using AGP 8.0

Describe the bug I’ve had an issue with R8 task failing because the StringConcatFactory rule was missing in my proguard-rules.pro. Agp now treats missing classes as errors since 8.0, and kotlinx.serialization utilizes StringConcatFactory which R8 then is unable to find because it’s stripped from the actual code (sanitized away when targeting jvm 8+) Please find exact details of the discussion in the following topic https://issuetracker.google.com/issues/250197571#comment19 The conclusion me and the Google team arrived at is that libraries should specify a -dontwarn rule for such cases. This ticket is therefore a request to add the missing rules.

To Reproduce Compile a library android module that uses kotlinx.serialization and targets jdk 11 on AGP 8.0-alpha. Compilation will fail.

Expected behavior

Environment

  • Kotlin version: N/A
  • Library version: 1.4.0
  • Kotlin platforms: JVM
  • Gradle version: 7.6
  • IDE version : N/A
  • Other relevant context : N/A

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 4
  • Comments: 32 (9 by maintainers)

Most upvoted comments

It still seems to be an issue even on 1.5.0 stable.

Same issue with 1.5.1

An alternative to using the -dontwarn in the ProGuard rules for building the library is to turn off generation of invokedynamic for string concatenation for kotlinc when building the with the option -Xstring-concat=inline. In AGP one can use the following in build.gradle or build.gradle.kts for the library:

android {
    kotlinOptions {
        jvmTarget = "11"
        freeCompilerArgs = listOf(
            "-Xstring-concat=inline"
        )
    }
}

AGP already turns off off generation of invokedynamic for string concatenation for javac.

Facing this issue with Gradle 8 and latest kotlinx-serialization (1.5.1) version.

Just to clarify this comment on the bug I would like to understand why the use of the StringConcatFactory is not removed for an Android build. As StringConcatFactory is not currently supported on Android the code path using it must be dead. Therefore it should be possible to restructure the code so that R8 can see that and fully remove this code, so that the -dontwarn is not needed.

If the -dontwarn is needed it is a better option to put it on the classes in kotlinx.serialization using StringConcatFactory and not directly on java.lang.invoke.StringConcatFactory, as -dontwarn is global and could then hide issues in unrelated code from other libraries.

Sorry, but I only tested with Kotlin Script (build.gradle.kts). For Groovey (build.gradle) try freeCompilerArgs = ["-Xstring-concat=inline"].

Facing this issue with AGP 8.0.1 and latest kotlinx-serialization version. Did anybody find any issues ? I am using JDK 11 for building

When I add freeCompilerArgs = listOf("-Xstring-concat=inline") to my kotlinOptions in my build.gradle, I get…

"Could not find method listOf() for arguments [-Xstring-concat=inline] on object of type org.jetbrains.kotlin.gradle.plugin.AndroidProjectHandler$configureTarget$kotlinOptions$1."

Any advice on how to resolve this? Thank you!

Finally spend dome time to actually figure out where this warning is coming from, see https://issuetracker.google.com/250197571#comment25. As it has nothing to do with Kotlin Serialization so adding the suggested -dontwarn to kotlinx.serialization is not a solution as @sandwwraith has already mentioned.

The -dontwarn should be added to the ProGuard rules for the library build, not to the library consumer rules.

I think this can be closed as working as intended.

@Nek-12 As I said, kotlinx.serialization does not require that rules. Your code (compiled with jvmTarget = 11) does. Therefore, as author of the library, you should provide the rules 😃

Why is it logical to have users of the library provide proguard rules for that library?

I have researched around the source code of NowInAndroid and they are not using the @Keep annotation which actually uses StringConcatFactory behind the scenes above Java 8. They are using @Serializable annotation with Json factory converter. Thus mitigating this issue altogether while using Java 11.

Hi, we are working on a solution to the problem.

Adding a common -dontwarn for java.lang.invoke.StringConcatFactory, or for all serialization classes does not solve the problem, but hide it in the serialization itself, or in the unrelated code of other dependencies.

It would be really nice for us to have a user-defined reproducer (in any form that we can checkout & run), so we can understand the root cause of the problem and to pinpoint it instead of potentially treating the symptoms

is there any plans to fix this soon?