Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.7.2 builtin UUID serializer breaks compatibility with gradle #2803

Closed
mgroth0 opened this issue Aug 30, 2024 · 7 comments
Closed

1.7.2 builtin UUID serializer breaks compatibility with gradle #2803

mgroth0 opened this issue Aug 30, 2024 · 7 comments
Assignees
Labels

Comments

@mgroth0
Copy link

mgroth0 commented Aug 30, 2024

Gradle ships with a specific Kotlin version, and Gradle version 8.8 is the newest gradle version that is verified compatible with kotlin 2.0.20. However, Gradle 8.8 itself in its buildscript and settings script runs Kotlin version 1.9.22 as can be seen by printing KotlinVersion.CURRENT in a build.gradle.kts script.

If a gradle plugin author tries to include serialization plugin 1.7.1, everything works fine. But upon upgrading to 1.7.2, we are immediately hit with a runtime error during a gradle build:

Caused by: java.lang.NoClassDefFoundError: kotlin/uuid/Uuid
	at kotlinx.serialization.internal.PrimitivesKt.<clinit>(Primitives.kt:20)
	at kotlinx.serialization.descriptors.SerialDescriptorsKt.PrimitiveSerialDescriptor(SerialDescriptors.kt:91)

This error is unavoidable, as the serialization plugin attempts to load the new kotlin UUID class regardless of whether or not the consumer is trying to serialize or deserialize a UUID.

To Reproduce

  1. Write a gradle plugin which depends on serialization 1.7.2
  2. Apply that gradle plugin in a project using Gradle 8.8
  3. In the buildscript, settings script, or in the plugin itself, attempt to serialize or deserialize something
  4. Observe error

Expected behavior

I think its ok for consumers of get a runtime error if they try to serialize or deserialize a kotlin.uuid.UUID in a gradle build. In that case, of course the UUID class will not be available. But for this whole library to fail seems unnecessary. Making the loading of the UUID class conditional on whether or not it is used would retain backwards compatibility in the library.

@sandwwraith
Copy link
Member

Hm, normally, 1.7.x versions shouldn't work with Kotlin 1.9 because the compiler should reject them (release notes explain why. Does Gradle uses 2.0.20 compiler to compile buildscript, but then Kotlin 1.9 to run? Why there are no compiler errors about Your current Kotlin version is 1.9.22, while kotlinx.serialization core runtime 1.7.2 requires at least Kotlin 2.0.0-RC1. Please update your Kotlin compiler and IDE plugin?

@mgroth0
Copy link
Author

mgroth0 commented Aug 30, 2024

Good question. But regardless of what gradle compiles buildscripts with, gradle plugins can compile with serialization 1.7.X and kotlin 2.0.20 and run fine on gradle 8.8 until serialization 1.7.2.

@sandwwraith sandwwraith self-assigned this Aug 30, 2024
@martinbonnin
Copy link
Contributor

martinbonnin commented Sep 5, 2024

Minimal reproducer:

import kotlinx.serialization.serializerOrNull

buildscript {
  dependencies {
    classpath("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
  }

  repositories {
    mavenCentral()
  }
}

@OptIn(kotlinx.serialization.InternalSerializationApi::class)
println(Float::class.serializerOrNull())

Does Gradle uses 2.0.20 compiler to compile buildscript, but then Kotlin 1.9 to run

I believe Gradle uses 1.9 to compile and forces 1.9 at runtime. Because there is n+1 forward compatibility, it compiles fine.

Why there are no compiler errors

Looks like the error is triggered from the serialization compiler plugin? It might not be always applied.

@pdvrieze
Copy link
Contributor

pdvrieze commented Sep 5, 2024

A very important thing to serialize is that in gradle buildSrc is special, and classes added to the classpath there are added to a very high level class loader (thus can not be overridden/specified in the project itself). This basically creates a Kotlin plugin version conflict. There is a workaround, use includeBuild instead and have that define a plugin (for the project) that is applied like a normal plugin. You can then build the plugin with gradle's Kotlin version, and then use it with a newer kotlin plugin version. See also: https://discuss.gradle.org/t/different-behaivor-between-buildsrc-and-include-build-build-logic/47705 and https://discuss.gradle.org/t/different-behaivor-between-buildsrc-and-include-build-build-logic/47705

@mny459
Copy link

mny459 commented Sep 15, 2024

same error

kotlin 2.0.10
kotlinx.serialization 1.7.1 or 1.7.2
ktor: 3.0.0-rc-1

@cyberkaidev
Copy link

I have the same problem:
Your current Kotlin version is 1.9.0, while kotlinx.serialization core runtime 1.7.1 requires at least Kotlin 2.0.0-RC1. Please update your Kotlin compiler and IDE plugin.

@cyberkaidev
Copy link

I fixed it just by changing the version: org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants