I'm experimenting with KSP (Kotlin Symbol Processing) to see what it's capable of and I'm trying to get it working on a Kotlin Multiplatform project. When I only enable kspJvm, it works perfectly, as soon as I enable kspJs as well, it fails with "Collection has more than one element."
I've recreated the issue in this demo github project: https://github.com/janvladimirmostert/observable-demo
In my processor, I have the following config:
build.gradle.kts:
val kspVersion: String by project
group = "io.jvaas"
plugins {
kotlin("multiplatform")
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "11"
}
}
sourceSets {
val commonMain by getting
val jvmMain by getting {
dependencies {
implementation("com.google.devtools.ksp:symbol-processing-api:$kspVersion")
}
}
}
}
gradle.properties:
kotlinVersion=1.6.0
kspVersion=1.6.0-1.0.1
src/commonMain/kotlin/io/jvaas/observe/Observable.kt
package io.jvaas.observe
annotation class Observable
src/jvmMain/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
io.jvaas.observe.ObservableProcessorProvider
src/jvmMain/kotlin/io/jvaas/observe/ObservableProcessor.kt
class ObservableProcessor(
val codeGenerator: CodeGenerator,
val logger: KSPLogger,
) : SymbolProcessor {
...
}
class ObservableProcessorProvider : SymbolProcessorProvider {
override fun create(
environment: SymbolProcessorEnvironment
): SymbolProcessor {
return ObservableProcessor(environment.codeGenerator, environment.logger)
}
}
In my consumer I have the following:
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackOutput.Target.UMD
group = "com.od"
plugins {
application
id("com.google.devtools.ksp") version "1.6.0-1.0.1"
kotlin("plugin.serialization")
kotlin("multiplatform")
id("com.github.johnrengelman.shadow")
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "11"
}
}
js(IR) {
browser {
binaries.executable()
webpackTask {
output.libraryTarget = UMD
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
val serializationVersion = "1.3.1"
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
implementation("io.jvaas:jvaas-observe")
}
}
val commonTest by getting
val jvmMain by getting {
dependencies {
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test-junit"))
}
}
val jsMain by getting
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
}
}
dependencies {
add("kspJvm", "io.jvaas:jvaas-observe")
// add("kspJs", "io.jvaas:jvaas-observe") // <--- fails if enabled
//ksp("io.jvaas:jvaas-observe")
}
application {
mainClassName = "com.od.demo.Main"
}
applications/od-server/src/commonMain/kotlin/com/od/demo/Blah.kt
package com.od.demo
import io.jvaas.observe.Observable
@Observable
class Blah {
var test1: String = ""
var test2: Int = 0
var test3: Array<String> = arrayOf()
}
This correctly gets processed when the kspJvm option is enabled and correctly outpus a file at
applications/od-server/build/generated/ksp/jvmMain/kotlin/com/od/demo/BlahO.kt
If I enable it for kspJs, it fails
add("kspJs", "io.jvaas:jvaas-observe")
Execution failed for task ':applications:od-server:compileProductionExecutableKotlinJs'.
> Failed to calculate the value of task ':applications:od-server:compileProductionExecutableKotlinJs' property 'entryModule$kotlin_gradle_plugin'.
> Collection has more than one element.
I've tried the usual gradle build --info / --debug / --scan but it's not clear where I can start looking to resolve this issue.
As mentioned above, I made a demo project to demonstrate the error: https://github.com/janvladimirmostert/observable-demo
Any ideas on how to resolve that error?
Issue has been fixed in https://github.com/google/ksp/issues/744 but I'm not sure if it has been released yet.