From ba916cfbdb001e6f9fcfb8191d78d2f53b69da92 Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Mon, 4 Nov 2024 12:16:45 +0100
Subject: [PATCH 1/3] Update CHANGELOG.md
---
CHANGELOG.md | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5183a65a3..41779d6e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+# 0.4.0
+> Published 5 November 2024
+
+### Features ๐
+* Experimental support for: KRPC-125 Manual stream scope management by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/214
+* Introduce @Rpc annotation by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/216
+* Support Kotlin 2.0.21 and 2.0.20 by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/217
+
+### Breaking Changes ๐ด
+* Introduce @Rpc annotation by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/216
+* Remove support for Kotlin versions prior to 2.0 by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/218
+
+### Infra ๐ง
+* Added proxy repository settings by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/191
+* Added Kotlin for ide configs to project by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/219
+
+### Bug fixes ๐
+* Fix for KT-41082 by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/225
+
+### Other Changes ๐งน
+* Bump core deps by @Mr3zee in https://github.com/Kotlin/kotlinx-rpc/pull/220
+
+**Full Changelog**: https://github.com/Kotlin/kotlinx-rpc/compare/0.3.0...0.4.0
+
# 0.3.0
> Published 1 October 2024
From fca125949484a1b784333485467d2e3dc1056564 Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 5 Nov 2024 16:57:46 +0100
Subject: [PATCH 2/3] Samples update (#224)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
.../ktor-all-platforms-app/build.gradle.kts | 12 ------
.../composeApp/build.gradle.kts | 1 -
.../gradle/libs.versions.toml | 39 +++++++++----------
.../server/build.gradle.kts | 1 -
.../src/commonMain/kotlin/UserService.kt | 6 ++-
samples/ktor-android-app/app/build.gradle.kts | 3 +-
.../kotlin/kotlinx/rpc/sample/MyService.kt | 8 ++--
.../gradle/libs.versions.toml | 35 ++++++++---------
.../ktor-android-app/server/build.gradle.kts | 1 -
samples/ktor-web-app/build.gradle.kts | 1 -
.../common/src/commonMain/kotlin/Common.kt | 6 ++-
.../ktor-web-app/frontend/build.gradle.kts | 1 -
.../ktor-web-app/gradle/libs.versions.toml | 23 ++++++-----
samples/ktor-web-app/server/build.gradle.kts | 1 -
samples/simple-ktor-app/build.gradle.kts | 20 +++++-----
.../src/main/kotlin/ImageRecognizer.kt | 6 ++-
16 files changed, 75 insertions(+), 89 deletions(-)
diff --git a/samples/ktor-all-platforms-app/build.gradle.kts b/samples/ktor-all-platforms-app/build.gradle.kts
index 48b39e282..4176fc7cf 100644
--- a/samples/ktor-all-platforms-app/build.gradle.kts
+++ b/samples/ktor-all-platforms-app/build.gradle.kts
@@ -12,17 +12,5 @@ plugins {
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.kotlinPluginSerialization) apply false
alias(libs.plugins.kotlinx.rpc) apply false
- alias(libs.plugins.kotlinx.rpc.platform) apply false
alias(libs.plugins.compose.compiler) apply false
}
-
-allprojects {
- configurations.all {
- resolutionStrategy {
- // Workaround for https://youtrack.jetbrains.com/issue/CMP-6658
- force(libs.kotlinx.serialization.core)
- force(libs.kotlinx.serialization.json)
- force(libs.kotlin.stdlib)
- }
- }
-}
diff --git a/samples/ktor-all-platforms-app/composeApp/build.gradle.kts b/samples/ktor-all-platforms-app/composeApp/build.gradle.kts
index a30b21321..e51d28ac1 100644
--- a/samples/ktor-all-platforms-app/composeApp/build.gradle.kts
+++ b/samples/ktor-all-platforms-app/composeApp/build.gradle.kts
@@ -13,7 +13,6 @@ plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.compose.compiler)
- alias(libs.plugins.kotlinx.rpc.platform)
}
kotlin {
diff --git a/samples/ktor-all-platforms-app/gradle/libs.versions.toml b/samples/ktor-all-platforms-app/gradle/libs.versions.toml
index 6af85b4be..3043bce74 100644
--- a/samples/ktor-all-platforms-app/gradle/libs.versions.toml
+++ b/samples/ktor-all-platforms-app/gradle/libs.versions.toml
@@ -1,25 +1,25 @@
[versions]
-kotlin = "2.0.10"
+kotlin = "2.0.21"
-agp = "8.6.1"
-android-compileSdk = "34"
+agp = "8.7.2"
+android-compileSdk = "35"
android-minSdk = "24"
-android-targetSdk = "34"
-androidx-activityCompose = "1.9.2"
+android-targetSdk = "35"
+androidx-activityCompose = "1.9.3"
androidx-appcompat = "1.7.0"
-androidx-constraintlayout = "2.1.4"
-androidx-core-ktx = "1.13.1"
+androidx-constraintlayout = "2.2.0"
+androidx-core-ktx = "1.15.0"
androidx-espresso-core = "3.6.1"
androidx-material = "1.12.0"
androidx-test-junit = "1.2.1"
-compose = "1.7.2"
-compose-plugin = "1.6.11"
+compose = "1.7.5"
+compose-plugin = "1.7.0"
junit = "4.13.2"
-ktor = "3.0.0-rc-1"
-logback = "1.5.8"
-serialization = "1.7.1"
+ktor = "3.0.1"
+logback = "1.5.12"
+serialization = "1.7.3"
coroutines = "1.9.0"
-kotlinx-rpc = "0.3.0"
+kotlinx-rpc = "0.4.0"
[libraries]
# kotlin
@@ -58,12 +58,12 @@ ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
# kotlinx-rpc
-kotlinx-rpc-core = { module = "org.jetbrains.kotlinx:kotlinx-rpc-core" }
-kotlinx-rpc-krpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client" }
-kotlinx-rpc-krpc-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-server" }
-kotlinx-rpc-krpc-ktor-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client" }
-kotlinx-rpc-krpc-ktor-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server" }
-kotlinx-rpc-krpc-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json" }
+kotlinx-rpc-core = { module = "org.jetbrains.kotlinx:kotlinx-rpc-core", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-server", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-ktor-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-ktor-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json", version.ref = "kotlinx-rpc" }
# other
logback = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
@@ -81,4 +81,3 @@ kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinx-rpc = { id = "org.jetbrains.kotlinx.rpc.plugin", version.ref = "kotlinx-rpc" }
-kotlinx-rpc-platform = { id = "org.jetbrains.kotlinx.rpc.platform", version.ref = "kotlinx-rpc" }
diff --git a/samples/ktor-all-platforms-app/server/build.gradle.kts b/samples/ktor-all-platforms-app/server/build.gradle.kts
index 21cace246..a65847c32 100644
--- a/samples/ktor-all-platforms-app/server/build.gradle.kts
+++ b/samples/ktor-all-platforms-app/server/build.gradle.kts
@@ -5,7 +5,6 @@
plugins {
alias(libs.plugins.kotlinJvm)
alias(libs.plugins.ktor)
- alias(libs.plugins.kotlinx.rpc.platform)
application
}
diff --git a/samples/ktor-all-platforms-app/shared/src/commonMain/kotlin/UserService.kt b/samples/ktor-all-platforms-app/shared/src/commonMain/kotlin/UserService.kt
index 0481f1417..91ed09431 100644
--- a/samples/ktor-all-platforms-app/shared/src/commonMain/kotlin/UserService.kt
+++ b/samples/ktor-all-platforms-app/shared/src/commonMain/kotlin/UserService.kt
@@ -3,7 +3,8 @@
*/
import kotlinx.coroutines.flow.Flow
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.serialization.Serializable
@Serializable
@@ -12,7 +13,8 @@ data class UserData(
val lastName: String,
)
-interface UserService : RPC {
+@Rpc
+interface UserService : RemoteService {
suspend fun hello(user: String, userData: UserData): String
suspend fun subscribeToNews(): Flow
diff --git a/samples/ktor-android-app/app/build.gradle.kts b/samples/ktor-android-app/app/build.gradle.kts
index 2bea80f38..78b2f5a29 100644
--- a/samples/ktor-android-app/app/build.gradle.kts
+++ b/samples/ktor-android-app/app/build.gradle.kts
@@ -6,13 +6,12 @@ plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.kotlinPluginSerialization)
- alias(libs.plugins.kotlinx.rpc.platform)
alias(libs.plugins.compose.compiler)
}
android {
namespace = "kotlinx.rpc.sample"
- compileSdk = 34
+ compileSdk = 35
packaging {
resources {
diff --git a/samples/ktor-android-app/common/src/main/kotlin/kotlinx/rpc/sample/MyService.kt b/samples/ktor-android-app/common/src/main/kotlin/kotlinx/rpc/sample/MyService.kt
index 5260ee4f9..8fd7d9b0f 100644
--- a/samples/ktor-android-app/common/src/main/kotlin/kotlinx/rpc/sample/MyService.kt
+++ b/samples/ktor-android-app/common/src/main/kotlin/kotlinx/rpc/sample/MyService.kt
@@ -5,10 +5,12 @@
package kotlinx.rpc.sample
import kotlinx.coroutines.flow.Flow
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
-interface MyService : RPC {
+@Rpc
+interface MyService : RemoteService {
suspend fun hello(user: String, userData: UserData): String
suspend fun subscribeToNews(): Flow
-}
\ No newline at end of file
+}
diff --git a/samples/ktor-android-app/gradle/libs.versions.toml b/samples/ktor-android-app/gradle/libs.versions.toml
index b5caa4936..37383d37c 100644
--- a/samples/ktor-android-app/gradle/libs.versions.toml
+++ b/samples/ktor-android-app/gradle/libs.versions.toml
@@ -1,21 +1,21 @@
[versions]
-agp = "8.6.1"
-kotlin = "2.0.10"
-androidx-activityCompose = "1.9.2"
+agp = "8.7.2"
+kotlin = "2.0.21"
+androidx-activityCompose = "1.9.3"
androidx-appcompat = "1.7.0"
-androidx-constraintlayout = "2.1.4"
-androidx-core-ktx = "1.13.1"
+androidx-constraintlayout = "2.2.0"
+androidx-core-ktx = "1.15.0"
androidx-test-junit = "1.2.1"
-compose = "1.7.2"
+compose = "1.7.5"
compose-plugin = "1.5.14" # https://mvnrepository.com/artifact/androidx.compose.compiler/compiler
-compose-bom = "2024.09.02"
-material3 = "1.3.0"
+compose-bom = "2024.10.01"
+material3 = "1.3.1"
junit = "4.13.2"
-ktor = "3.0.0-rc-1"
+ktor = "3.0.1"
kotlinx-serialization-json = "1.7.3"
kotlinx-coroutines-core = "1.9.0"
-logback = "1.5.8"
-kotlinx-rpc = "0.3.0"
+logback = "1.5.12"
+kotlinx-rpc = "0.4.0"
[libraries]
# kotlin
@@ -66,12 +66,12 @@ junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-junit" }
# kotlinx-rpc
-kotlinx-rpc-core = { module = "org.jetbrains.kotlinx:kotlinx-rpc-core" }
-kotlinx-rpc-krpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client" }
-kotlinx-rpc-krpc-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-server" }
-kotlinx-rpc-krpc-ktor-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client" }
-kotlinx-rpc-krpc-ktor-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server" }
-kotlinx-rpc-krpc-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json" }
+kotlinx-rpc-core = { module = "org.jetbrains.kotlinx:kotlinx-rpc-core", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-server", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-ktor-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-ktor-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json", version.ref = "kotlinx-rpc" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
@@ -80,5 +80,4 @@ kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlinPluginSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlinx-rpc = { id = "org.jetbrains.kotlinx.rpc.plugin", version.ref = "kotlinx-rpc" }
-kotlinx-rpc-platform = { id = "org.jetbrains.kotlinx.rpc.platform", version.ref = "kotlinx-rpc" }
ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
diff --git a/samples/ktor-android-app/server/build.gradle.kts b/samples/ktor-android-app/server/build.gradle.kts
index 779f328e7..b30cf67db 100644
--- a/samples/ktor-android-app/server/build.gradle.kts
+++ b/samples/ktor-android-app/server/build.gradle.kts
@@ -6,7 +6,6 @@ plugins {
alias(libs.plugins.kotlinJvm)
alias(libs.plugins.kotlinPluginSerialization)
alias(libs.plugins.ktor)
- alias(libs.plugins.kotlinx.rpc.platform)
application
distribution
diff --git a/samples/ktor-web-app/build.gradle.kts b/samples/ktor-web-app/build.gradle.kts
index 88c9664fb..4de8f5c84 100644
--- a/samples/ktor-web-app/build.gradle.kts
+++ b/samples/ktor-web-app/build.gradle.kts
@@ -5,7 +5,6 @@
plugins {
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.kotlinx.rpc) apply false
- alias(libs.plugins.kotlinx.rpc.platform) apply false
}
allprojects {
diff --git a/samples/ktor-web-app/common/src/commonMain/kotlin/Common.kt b/samples/ktor-web-app/common/src/commonMain/kotlin/Common.kt
index 924461c8e..d2b40503e 100644
--- a/samples/ktor-web-app/common/src/commonMain/kotlin/Common.kt
+++ b/samples/ktor-web-app/common/src/commonMain/kotlin/Common.kt
@@ -3,7 +3,8 @@
*/
import kotlinx.coroutines.flow.Flow
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.serialization.Serializable
@Serializable
@@ -12,7 +13,8 @@ data class UserData(
val lastName: String,
)
-interface MyService : RPC {
+@Rpc
+interface MyService : RemoteService {
suspend fun hello(user: String, userData: UserData): String
suspend fun subscribeToNews(): Flow
diff --git a/samples/ktor-web-app/frontend/build.gradle.kts b/samples/ktor-web-app/frontend/build.gradle.kts
index eb2d3281e..51a5e440f 100644
--- a/samples/ktor-web-app/frontend/build.gradle.kts
+++ b/samples/ktor-web-app/frontend/build.gradle.kts
@@ -5,7 +5,6 @@
plugins {
kotlin("multiplatform")
alias(libs.plugins.kotlin.plugin.serialization)
- alias(libs.plugins.kotlinx.rpc.platform)
}
kotlin {
diff --git a/samples/ktor-web-app/gradle/libs.versions.toml b/samples/ktor-web-app/gradle/libs.versions.toml
index cde10b6b9..7f245a080 100644
--- a/samples/ktor-web-app/gradle/libs.versions.toml
+++ b/samples/ktor-web-app/gradle/libs.versions.toml
@@ -1,11 +1,11 @@
[versions]
-kotlin = "2.0.10"
-kotlin-wrappers-bom = "1.0.0-pre.812"
-ktor = "3.0.0-rc-1"
+kotlin = "2.0.21"
+kotlin-wrappers-bom = "1.0.0-pre.823"
+ktor = "3.0.1"
kotlinx-serialization-json = "1.7.3"
kotlinx-coroutines-core = "1.9.0"
-logback = "1.5.8"
-kotlinx-rpc = "0.3.0"
+logback = "1.5.12"
+kotlinx-rpc = "0.4.0"
[libraries]
# kotlin
@@ -41,16 +41,15 @@ ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
# krpc
-kotlinx-rpc-core = { module = "org.jetbrains.kotlinx:kotlinx-rpc-core" }
-kotlinx-rpc-krpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client" }
-kotlinx-rpc-krpc-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-server" }
-kotlinx-rpc-krpc-ktor-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client" }
-kotlinx-rpc-krpc-ktor-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server" }
-kotlinx-rpc-krpc-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json" }
+kotlinx-rpc-core = { module = "org.jetbrains.kotlinx:kotlinx-rpc-core", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-server", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-ktor-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-ktor-server = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server", version.ref = "kotlinx-rpc" }
+kotlinx-rpc-krpc-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json", version.ref = "kotlinx-rpc" }
[plugins]
kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlinx-rpc = { id = "org.jetbrains.kotlinx.rpc.plugin", version.ref = "kotlinx-rpc" }
-kotlinx-rpc-platform = { id = "org.jetbrains.kotlinx.rpc.platform", version.ref = "kotlinx-rpc" }
diff --git a/samples/ktor-web-app/server/build.gradle.kts b/samples/ktor-web-app/server/build.gradle.kts
index 2185e27fb..5eac4363c 100644
--- a/samples/ktor-web-app/server/build.gradle.kts
+++ b/samples/ktor-web-app/server/build.gradle.kts
@@ -5,7 +5,6 @@
plugins {
kotlin("jvm")
alias(libs.plugins.kotlin.plugin.serialization)
- alias(libs.plugins.kotlinx.rpc.platform)
application
distribution
}
diff --git a/samples/simple-ktor-app/build.gradle.kts b/samples/simple-ktor-app/build.gradle.kts
index 23e6e80bf..d0c86a58c 100644
--- a/samples/simple-ktor-app/build.gradle.kts
+++ b/samples/simple-ktor-app/build.gradle.kts
@@ -3,10 +3,10 @@
*/
plugins {
- kotlin("jvm") version "2.0.10"
- kotlin("plugin.serialization") version "2.0.10"
- id("io.ktor.plugin") version "3.0.0-rc-1"
- id("org.jetbrains.kotlinx.rpc.plugin") version "0.3.0"
+ kotlin("jvm") version "2.0.21"
+ kotlin("plugin.serialization") version "2.0.21"
+ id("io.ktor.plugin") version "3.0.1"
+ id("org.jetbrains.kotlinx.rpc.plugin") version "0.4.0"
}
group = "kotlinx.rpc.sample"
@@ -28,16 +28,16 @@ kotlin {
}
dependencies {
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-client")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-server")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json")
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-client:0.4.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-server:0.4.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json:0.4.0")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server")
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client:0.4.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server:0.4.0")
implementation("io.ktor:ktor-client-cio")
implementation("io.ktor:ktor-server-netty-jvm")
- implementation("ch.qos.logback:logback-classic:1.5.8")
+ implementation("ch.qos.logback:logback-classic:1.5.12")
testImplementation("io.ktor:ktor-server-test-host")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:2.0.10")
diff --git a/samples/simple-ktor-app/src/main/kotlin/ImageRecognizer.kt b/samples/simple-ktor-app/src/main/kotlin/ImageRecognizer.kt
index 30e8f8d37..57a3df5e0 100644
--- a/samples/simple-ktor-app/src/main/kotlin/ImageRecognizer.kt
+++ b/samples/simple-ktor-app/src/main/kotlin/ImageRecognizer.kt
@@ -7,8 +7,9 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.RPCEagerField
+import kotlinx.rpc.annotations.Rpc
import kotlinx.serialization.Serializable
import kotlin.coroutines.CoroutineContext
@@ -25,7 +26,8 @@ enum class Category {
CAT, DOG
}
-interface ImageRecognizer : RPC {
+@Rpc
+interface ImageRecognizer : RemoteService {
@RPCEagerField
val currentlyProcessedImage: StateFlow
From 12559e8e797a7783e6b33cc8d5dbff13d00f7b4a Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 5 Nov 2024 17:01:06 +0100
Subject: [PATCH 3/3] Updated docs for 0.4.0; bumped version (#222)
Co-authored-by: Viktoriya Nikolova
---
.github/workflows/docs.yml | 2 +-
README.md | 65 ++++---------
docs/pages/kotlinx-rpc/help-versions.json | 2 +-
docs/pages/kotlinx-rpc/rpc.tree | 1 +
docs/pages/kotlinx-rpc/topics/0-4-0.topic | 90 ++++++++++++++++++
docs/pages/kotlinx-rpc/topics/features.topic | 14 ++-
.../kotlinx-rpc/topics/get-started.topic | 22 ++---
docs/pages/kotlinx-rpc/topics/plugins.topic | 92 ++-----------------
docs/pages/kotlinx-rpc/topics/services.topic | 10 +-
docs/pages/kotlinx-rpc/topics/transport.topic | 2 +-
docs/pages/kotlinx-rpc/topics/versions.topic | 9 +-
docs/pages/kotlinx-rpc/v.list | 5 +-
docs/pages/kotlinx-rpc/writerside.cfg | 2 +-
gradle.properties | 2 +-
versions-root/libs.versions.toml | 2 +-
15 files changed, 159 insertions(+), 161 deletions(-)
create mode 100644 docs/pages/kotlinx-rpc/topics/0-4-0.topic
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 382e1a045..9cc8b7380 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -20,7 +20,7 @@ env:
ALGOLIA_INDEX_NAME: 'prod_kotlin_rpc'
ALGOLIA_KEY: '${{ secrets.ALGOLIA_KEY }}'
CONFIG_JSON_PRODUCT: 'kotlinx-rpc'
- CONFIG_JSON_VERSION: '0.3.0'
+ CONFIG_JSON_VERSION: '0.4.0'
jobs:
build:
diff --git a/README.md b/README.md
index 593376240..125e43e37 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
[](https://kotlinlang.org/docs/components-stability.html)
[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
-[](http://kotlinlang.org)
+[](http://kotlinlang.org)
[](http://www.apache.org/licenses/LICENSE-2.0)
[//]: # ([](https://teamcity.jetbrains.com/viewType.html?buildTypeId=Build_kRPC_All&guest=1))
@@ -84,33 +84,18 @@ Check out our [getting started guide](https://kotlin.github.io/kotlinx-rpc) for
### Plugin dependencies
-`kotlinx.rpc` has the following plugin dependencies:
-- The `org.jetbrains.kotlinx.rpc.plugin` will set up BOM and code generation for targets in the project.
-- The `org.jetbrains.kotlinx.rpc.platform` will only set up BOM. It is useful when you want to split your app into modules,
-and some of them will contain service declarations, thus using code generation, while others will only consume them.
+`kotlinx.rpc` provides Gradle plugin `org.jetbrains.kotlinx.rpc.plugin`
+that will set up code generation in a project.
-Example of plugins setup in a project's `build.gradle.kts`:
+Example of a setup in a project's `build.gradle.kts`:
```kotlin
plugins {
- kotlin("jvm") version "2.0.10"
- kotlin("plugin.serialization") version "2.0.10"
- id("org.jetbrains.kotlinx.rpc.plugin") version "0.3.0"
+ kotlin("multiplatform") version "2.0.21"
+ kotlin("plugin.serialization") version "2.0.21"
+ id("org.jetbrains.kotlinx.rpc.plugin") version "0.4.0"
}
```
-For Kotlin versions prior to 2.0,
-KSP plugin is required
-(Corresponding configurations will be set up automatically by `org.jetbrains.kotlinx.rpc.plugin` plugin):
-
-```kotlin
-// build.gradle.kts
-plugins {
- kotlin("jvm") version "1.9.25"
- kotlin("plugin.serialization") version "1.9.25"
- id("com.google.devtools.ksp") version "1.9.25-1.0.20"
- id("org.jetbrains.kotlinx.rpc.plugin") version "0.3.0"
-}
-```
### Runtime dependencies
To use `kotlinx.rpc` runtime dependencies, add Maven Central to the list of your repositories:
```kotlin
@@ -121,16 +106,16 @@ repositories {
And now you can add dependencies to your project:
```kotlin
dependencies {
- // client API
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-client")
- // server API
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-server")
- // serialization module. also, protobuf and cbor are available
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json")
+ // Client API
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-client:0.4.0")
+ // Server API
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-server:0.4.0")
+ // Serialization module. Also, protobuf and cbor are provided
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-serialization-json:0.4.0")
- // transport implementation for Ktor
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server")
+ // Transport implementation for Ktor
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-client:0.4.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-ktor-server:0.4.0")
// Ktor API
implementation("io.ktor:ktor-client-cio-jvm:$ktor_version")
@@ -143,7 +128,7 @@ You can see example projects in the [samples](samples) folder.
`kotlinx.rpc` is designed to be transport agnostic.
That means that the library aims to provide the best RPC experience regardless of how the resulting messages are transferred.
That allows for easy integration into existing solutions, such as Ktor, without the need to rewrite code.
-Just plug-in `kotlinx.rpc`, provide it with means to transfer encoded data (or use out-of-the-box integrations) and it will run.
+Add `kotlinx.rpc`, provide it with means to transfer encoded data (or use out-of-the-box integrations) and it will run.
With enough time it might even work with [avian carriers](https://en.wikipedia.org/wiki/IP_over_Avian_Carriers).
`kotlinx.rpc` provides its own transfer protocol called kRPC, which takes responsibility for tracking serializing and handling other complex request operations.
@@ -154,26 +139,12 @@ Besides that, one can even provide their own protocol or integration with one to
Though possible, it is much more complicated way to use the library and generally not needed.
`kotlinx.rpc` aims to provide most common protocols integrations as well as the in-house one called kRPC.
Integrations in progress:
-- Integration with [gRPC](https://grpc.io/) (in prototype)
+- Integration with [gRPC](https://grpc.io/) (in prototype)
## Kotlin compatibility
We support all stable Kotlin versions starting from 2.0.0:
- 2.0.0, 2.0.10, 2.0.20, 2.0.21
-To simplify project configuration, our Gradle plugin sets a proper library version automatically using BOM,
-based on the project's Kotlin version:
-```kotlin
-plugins {
- kotlin("jvm") version "2.0.10"
- id("org.jetbrains.kotlinx.rpc.plugin") version "0.3.0"
-}
-
-dependencies {
- // version 0.3.0 is set by the Gradle plugin
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-core")
-}
-```
-
For a full compatibility checklist,
see [Versions](https://kotlin.github.io/kotlinx-rpc/versions.html).
diff --git a/docs/pages/kotlinx-rpc/help-versions.json b/docs/pages/kotlinx-rpc/help-versions.json
index aefc80e92..a5e4e23e9 100644
--- a/docs/pages/kotlinx-rpc/help-versions.json
+++ b/docs/pages/kotlinx-rpc/help-versions.json
@@ -1,3 +1,3 @@
[
- {"version":"0.3.0","url":"/kotlinx-rpc/0.3.0/","isCurrent":true}
+ {"version":"0.4.0","url":"/kotlinx-rpc/0.4.0/","isCurrent":true}
]
diff --git a/docs/pages/kotlinx-rpc/rpc.tree b/docs/pages/kotlinx-rpc/rpc.tree
index 23ab1e140..53f20105a 100644
--- a/docs/pages/kotlinx-rpc/rpc.tree
+++ b/docs/pages/kotlinx-rpc/rpc.tree
@@ -26,6 +26,7 @@
+
diff --git a/docs/pages/kotlinx-rpc/topics/0-4-0.topic b/docs/pages/kotlinx-rpc/topics/0-4-0.topic
new file mode 100644
index 000000000..7878c27b2
--- /dev/null
+++ b/docs/pages/kotlinx-rpc/topics/0-4-0.topic
@@ -0,0 +1,90 @@
+
+
+
+
+ Version 0.4.0
introduces breaking changes.
+
+
+
+ This version brings changes to service definitions. Starting with this version, service definitions require
+ the @Rpc
annotation.
+
+
+ Prior to 0.4.0
, a service was defined as follows:
+
+
+ interface MyService : RPC
+
+
+ Starting from 0.4.0
, the new service definition should be:
+
+
+ @Rpc
+ interface MyService
+
+
+ This definition is sufficient for the project to build. However, it will not fully support IDE features,
+ such as code highlighting.
+ All interfaces annotated with @Rpc
are inherently of type RemoteService
, which is
+ added by the compiler plugin, but IDEs won't be able to resolve it.
+
+
+ To ensure proper IDE support, add explicit typing:
+
+
+ @Rpc
+ interface MyService : RemoteService
+
+
+
+ The reasoning behind this update is that the Kotlin Compiler Plugin API has changed.
+ Versions 2.0.0
and 2.0.10
allowed our plugin to resolve marker interfaces (like RPC
)
+ before the code generation phase. Starting from version 2.0.20
, this behaviour changed,
+ making annotations the only reliable way to detect RPC services.
+
+
+ To track changes in this regard, we raised an issue
+ with the compiler team.
+ Note that this approach is subject to change, and the final API design may be updated before the stable
+ release.
+
+
+
+
+
+ We stopped publishing compiler plugin artifacts for Kotlin versions prior to 2.0.0
.
+ The reason being its high maintenance cost with little to no usage.
+ We encourage the migration to Kotlin 2.0, where all stable versions are now supported.
+
+
+
+ Currently supported Kotlin versions: 2.0.0
, 2.0.10
, 2.0.20
, 2.0.21
+
+
+
+
+ The Gradle plugin with id org.jetbrains.kotlinx.rpc.platform
is not being published anymore.
+ The reason is that it's sole role was to set BOM in the project, which is now considered unnecessary.
+ Gradle version catalogs
+ can be used instead.
+
+
+
+
+ The Gradle plugin with id org.jetbrains.kotlinx.rpc.plugin
+ does not set BOM for the project anymore.
+
+
+ To configure BOM manually, add the following dependency:
+
+
+ dependencies {
+ implementation(platform("org.jetbrains.kotlinx:kotlinx-rpc-bom:%kotlinx-rpc-version%"))
+ }
+
+
+
\ No newline at end of file
diff --git a/docs/pages/kotlinx-rpc/topics/features.topic b/docs/pages/kotlinx-rpc/topics/features.topic
index 9b236eae8..9a611edba 100644
--- a/docs/pages/kotlinx-rpc/topics/features.topic
+++ b/docs/pages/kotlinx-rpc/topics/features.topic
@@ -36,7 +36,8 @@
that will provide your flows with their lifetime:
- interface MyService {
+ @Rpc
+ interface MyService : RemoteService {
suspend fun sendFlow(flow: Flow<Int>)
}
@@ -81,6 +82,17 @@
}
Note that this API is experimental and may be removed in future releases.
+
+ Another way of managing streams is to do it manually.
+ For this, you can use the StreamScope
constructor function together with
+ withStreamScope
:
+
+
+ val streamScope = StreamScope(myJob)
+ withStreamScope(streamScope) {
+ // use streams here
+ }
+
Our protocol provides you with an ability to declare service fields:
diff --git a/docs/pages/kotlinx-rpc/topics/get-started.topic b/docs/pages/kotlinx-rpc/topics/get-started.topic
index 1b2652ec3..6ba7fe8f1 100644
--- a/docs/pages/kotlinx-rpc/topics/get-started.topic
+++ b/docs/pages/kotlinx-rpc/topics/get-started.topic
@@ -110,21 +110,8 @@
- kotlinx.rpc
provides two Gradle plugins:
-
-
-
- org.jetbrains.kotlinx.rpc.platform
-
-
-
-
- org.jetbrains.kotlinx.rpc.plugin
-
-
-
- To add a plugin to your project, you need to define the following in your build.gradle.kts:
+ To add a Gradle plugin to your project, you need to define the following in your build.gradle.kts:
@@ -132,11 +119,14 @@
id("org.jetbrains.kotlinx.rpc.plugin") version "%kotlinx-rpc-version%"
}
- To learn more about versioning, see .
+
+
+ This will configure code generation for your project.
+
- kotlinx.rpc
requires you to add
+
kotlinx.rpc
requires you to add the
kotlinx.serialization
Gradle plugin to your project.
diff --git a/docs/pages/kotlinx-rpc/topics/plugins.topic b/docs/pages/kotlinx-rpc/topics/plugins.topic
index e799e7df8..7e1620329 100644
--- a/docs/pages/kotlinx-rpc/topics/plugins.topic
+++ b/docs/pages/kotlinx-rpc/topics/plugins.topic
@@ -9,98 +9,24 @@
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
title="Plugins" id="plugins">
- The kotlinx.rpc
library offers plugins that simplify project configuration by automating repetitive
- tasks.
- Specifically, kotlinx.rpc
provides two Gradle plugins:
+ The kotlinx.rpc
library offers a Gradle plugin
+ that simplifies project configuration by automating repetitive tasks: `org.jetbrains.kotlinx.rpc.plugin`
-
-
-
- org.jetbrains.kotlinx.rpc.platform
-
-
-
-
- org.jetbrains.kotlinx.rpc.plugin
-
-
-
-
- The org.jetbrains.kotlinx.rpc.platform
plugin
- is particularly useful for versioning project dependencies.
- It adds BOM
- dependency to your project, that specifies proper versions for kotlinx.rpc
dependencies.
- With this, you can skip specifying versions for each runtime dependency:
-
-
- plugins {
- kotlin("jvm") version "%kotlin-version%"
- id("org.jetbrains.kotlinx.rpc.platform") version "%kotlinx-rpc-version%"
- }
-
- dependencies {
- // versions are set automatically to %kotlinx-rpc-version%
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-client")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-server")
- }
-
- Using this plugin with version catalogs, your code can be rewritten like this:
-
-
- # gradle / libs.versions.toml
- [versions]
- kotlinx-rpc-core = "%kotlinx-rpc-version%";
-
- [libraries]
- kotlinx-rpc-client = { module = "org.jetbrains.kotlinx:kotlinx-rpc-krpc-client" }
-
- [plugins]
- kotlinx-rpc-platform = { id = "org.jetbrains.kotlinx.rpc.platform"; version.ref = "kotlinx-rpc-core"; }
-
-
-
- // build.gradle.kts
- plugins {
- alias(libs.plugins.kotlinx.rpc.platform)
- }
-
- dependencies {
- implementation(libs.kotlinx.rpc.client)
- }
-
-
- The org.jetbrains.kotlinx.rpc.plugin
plugin
- has the same BOM functionality as org.jetbrains.kotlinx.rpc.platform
and it also sets
- up code generation configurations.
+ The org.jetbrains.kotlinx.rpc.plugin
plugin sets up code generation configurations.
- It is useful for multi-project setups
- where you define your RPC services in one set of subprojects and use in the
- other. In such a setup, you can add the plugin only to modules with service definitions
- to save time on building your project.
-
plugins {
kotlin("jvm") version "%kotlin-version%"
id("org.jetbrains.kotlinx.rpc.plugin") version "%kotlinx-rpc-version%"
}
-
-
-
- If you are using a version of Kotlin prior to 2.0,
- you must also add the KSP (Kotlin Symbol Processing) Gradle plugin:
-
-
- plugins {
- kotlin("jvm") version "1.9.25"
- id("org.jetbrains.kotlinx.rpc.plugin") version "%kotlinx-rpc-version%"
- id("com.google.devtools.ksp") version "1.9.25-1.0.20"
- }
-
-
+
+ For multi-project setups
+ where you define your RPC services in one set of subprojects and use them in
+ another, you can add the plugin only to modules with service definitions.
+
-
\ No newline at end of file
+
diff --git a/docs/pages/kotlinx-rpc/topics/services.topic b/docs/pages/kotlinx-rpc/topics/services.topic
index a2840eb18..b10a1dee0 100644
--- a/docs/pages/kotlinx-rpc/topics/services.topic
+++ b/docs/pages/kotlinx-rpc/topics/services.topic
@@ -9,10 +9,16 @@
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
title="Services" id="services">
Services are the centerpieces of the library.
- A service is an interface annotated with the RPC
annotation,
+ A service is an interface annotated with the @Rpc
annotation,
and contains a set of methods and fields
that can be executed or accessed remotely.
- A simple service can be declared as follows:
+ Additionally, a service always has a type of RemoteService
,
+ which can be specified explicitly, or assumed implicitly by the compiler.
+
+
+ Note that implicit typing is currently not supported in IDEs, but is a work in progress.
+
+ A simple service can be declared as follows:
@Rpc
diff --git a/docs/pages/kotlinx-rpc/topics/transport.topic b/docs/pages/kotlinx-rpc/topics/transport.topic
index a89f193db..17547d0f6 100644
--- a/docs/pages/kotlinx-rpc/topics/transport.topic
+++ b/docs/pages/kotlinx-rpc/topics/transport.topic
@@ -88,7 +88,7 @@
@Rpc
interface ImageService : RemoteService {
- suspend fun processImage(url: Srting): ProcessedImage
+ suspend fun processImage(url: String): ProcessedImage
}
// ### CLIENT CODE ###
diff --git a/docs/pages/kotlinx-rpc/topics/versions.topic b/docs/pages/kotlinx-rpc/topics/versions.topic
index 08ed609c9..7a5611c8c 100644
--- a/docs/pages/kotlinx-rpc/topics/versions.topic
+++ b/docs/pages/kotlinx-rpc/topics/versions.topic
@@ -8,7 +8,7 @@
- As kotlinx.rpc
uses Kotlin compiler plugin and KSP plugins,
+
As kotlinx.rpc
uses Kotlin compiler plugin,
we rely on internal functionality that may change over time with any new Kotlin version.
To prevent the library from breaking with an incompatible Kotlin version,
we use version prefix for artifacts with code generating functionality.
@@ -69,9 +69,12 @@
id("org.jetbrains.kotlinx.rpc.plugin") version "%kotlinx-rpc-version%"
}
- Our Gradle plugin will add this dependency to all applicable configurations:
+ Our Gradle plugin will add these dependencies to all applicable configurations:
- org.jetbrains.kotlinx:kotlinx-rpc-compiler-plugin:%kotlin-version%-%kotlinx-rpc-version%
+ org.jetbrains.kotlinx:kotlinx-rpc-compiler-plugin-cli:%kotlin-version%-%kotlinx-rpc-version%
+ org.jetbrains.kotlinx:kotlinx-rpc-compiler-plugin-common:%kotlin-version%-%kotlinx-rpc-version%
+ org.jetbrains.kotlinx:kotlinx-rpc-compiler-plugin-k2:%kotlin-version%-%kotlinx-rpc-version%
+ org.jetbrains.kotlinx:kotlinx-rpc-compiler-plugin-backend:%kotlin-version%-%kotlinx-rpc-version%
Such dependencies are managed automatically, and should not be used explicitly.
diff --git a/docs/pages/kotlinx-rpc/v.list b/docs/pages/kotlinx-rpc/v.list
index 1897ccfc9..8a6dc0d6c 100644
--- a/docs/pages/kotlinx-rpc/v.list
+++ b/docs/pages/kotlinx-rpc/v.list
@@ -14,7 +14,6 @@
-
-
-
+
+
diff --git a/docs/pages/kotlinx-rpc/writerside.cfg b/docs/pages/kotlinx-rpc/writerside.cfg
index 2fc05fd86..0a0f6d429 100644
--- a/docs/pages/kotlinx-rpc/writerside.cfg
+++ b/docs/pages/kotlinx-rpc/writerside.cfg
@@ -12,5 +12,5 @@
-
+
diff --git a/gradle.properties b/gradle.properties
index 2d4b2c2fc..1f2386b10 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -16,7 +16,7 @@ org.gradle.workers.max=6
org.gradle.caching=true
org.gradle.configuration-cache=true
-# development mode for kotlinx.rpc gradle plugin. Uses local project paths to apply ksp and compiler plugins
+# development mode for kotlinx.rpc gradle plugin. Uses local project paths to apply the compiler plugin
kotlinx.rpc.plugin.internalDevelopment=true
# https://github.com/gradle/gradle/issues/20416
diff --git a/versions-root/libs.versions.toml b/versions-root/libs.versions.toml
index 3ed3b4133..1646cd8b4 100644
--- a/versions-root/libs.versions.toml
+++ b/versions-root/libs.versions.toml
@@ -1,6 +1,6 @@
[versions]
# core library version
-kotlinx-rpc = "0.3.0"
+kotlinx-rpc = "0.4.0"
# kotlin
kotlin-lang = "2.0.21" # or env.KOTLIN_VERSION