Kotlin Multiplatform 上的 KSP 在 kspJs 上失败,并显示“Collection has more than one element”。

Posted

技术标签:

【中文标题】Kotlin Multiplatform 上的 KSP 在 kspJs 上失败,并显示“Collection has more than one element”。【英文标题】:KSP on Kotlin Multiplatform fails on the kspJs with "Collection has more than one element." 【发布时间】:2022-01-05 09:24:24 【问题描述】:

我正在尝试使用 KSP(Kotlin 符号处理)来了解它的功能,并且我正在尝试让它在 Kotlin 多平台项目上运行。 当我只启用 kspJvm 时,它工作得很好,只要我也启用 kspJs,它就会失败,并显示“集合有多个元素”。

我在这个演示 github 项目中重新创建了问题: https://github.com/janvladimirmostert/observable-demo

在我的处理器中,我有以下配置:

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)
    

在我的消费者中,我有以下内容:

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()


当启用 kspJvm 选项并正确输出文件时,会正确处理

applications/od-server/build/generated/ksp/jvmMain/kotlin/com/od/demo/BlahO.kt

如果我为 kspJs 启用它,它会失败

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.

我已经尝试了通常的 gradle build --info / --debug / --scan 但不清楚我可以从哪里着手解决这个问题。

如上所述,我做了一个演示项目来演示错误: https://github.com/janvladimirmostert/observable-demo

关于如何解决该错误的任何想法?

【问题讨论】:

在此处提交的错误报告:github.com/google/ksp/issues/744 【参考方案1】:

问题已在https://github.com/google/ksp/issues/744 中修复,但我不确定它是否已经发布。

【讨论】:

以上是关于Kotlin Multiplatform 上的 KSP 在 kspJs 上失败,并显示“Collection has more than one element”。的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Kotlin/Multiplatform 项目中使用 .klib 库

Kotlin-Multiplatform 中的 CPointer

Kotlin-multiplatform:如何执行 iOS 单元测试

Kotlin Multiplatform (KMM) 中的对象在 Swift 函数中实例化。函数结束它的作用域。谁释放了对象?

在 kotlin-multiplatform 上生成 UUID?

Kotlin Multiplatform 项目包含 cocoapod 依赖项