openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] Generation with `kotlinx_serialization` generates unnecessary `@Serializable` on interfaces and double `@Serializable@Serializable` on classes

Open javac9 opened this issue 1 year ago • 2 comments

Kotlin Client openapi generator version 7.6.0

Description

Generated interfaces have @Serializable and classes @Serializable@Serializable annotations which requires manual correction.

openapi-generator version

7.6.0

Steps to reproduce

My gradle task uses this to generate:

    generatorName.set("kotlin")
    library.set("multiplatform")
    inputSpec.set("path/to/my/openapi-spec.json")
    outputDir.set("$projectDir/build")
    ....
    configOptions.set(
        mapOf(
            "serializationLibrary" to "kotlinx_serialization",
            "dateLibrary" to "kotlinx-datetime",
            "idea" to "true",
           ....

javac9 avatar Jun 11 '24 14:06 javac9

I just ran into this as well. Have not found a workaround as yet.

cbeams avatar Jun 15 '24 09:06 cbeams

Here's a quick workaround I'm using that effectively edits generated sources in place after generation and before compilation:

// work around https://github.com/OpenAPITools/openapi-generator/issues/18904
tasks.register<ReplaceInFilesTask>("dedupeSerializableAnnotation") {
    group = "Custom"
    description = "Replaces occurrences of @Serializable@Serializable with @Serializable in source files " +
            "to work around the bug described at https://github.com/OpenAPITools/openapi-generator/issues/18904"

    sourceDir.set(file("src"))
    targetString.set("@Serializable@Serializable")
    replacementString.set("@Serializable")
}

abstract class ReplaceInFilesTask : DefaultTask() {
    @get:InputDirectory
    abstract val sourceDir: DirectoryProperty

    @get:Input
    abstract val targetString: Property<String>

    @get:Input
    abstract val replacementString: Property<String>

    @TaskAction
    fun replaceStrings() {
        val target = targetString.get()
        val replacement = replacementString.get()
        val sourceDir = sourceDir.get().asFile

        if (sourceDir.exists()) {
            sourceDir.walkTopDown()
                .filter { it.isFile }
                .forEach { file ->
                    val content = file.readText()
                    val newContent = content.replace(target, replacement)
                    if (content != newContent) {
                        file.writeText(newContent)
                        println("Replaced in: ${file.absolutePath}")
                    }
                }
        } else {
            println("Source directory does not exist: $sourceDir")
        }
    }
}

tasks.getByName("openApiGenerate").finalizedBy("dedupeSerializableAnnotation")
tasks.getByName("compileKotlinJvm").dependsOn("openApiGenerate")
tasks.getByName("allMetadataJar").dependsOn("openApiGenerate") // to avoid "implicit dependency" error at [1]

// [1]: https://docs.gradle.org/8.7/userguide/validation_problems.html#implicit_dependency

cbeams avatar Jun 15 '24 16:06 cbeams

I had the doubled annotation issue as well, for me it was solved by removing:

"serializationLibrary" to "kotlinx_serialization",

heitorcolangelo avatar Oct 30 '24 13:10 heitorcolangelo

I had the doubled annotation issue as well, for me it was solved by removing:

"serializationLibrary" to "kotlinx_serialization",

It also works for me. My library.set("multiplatform") is Multiplatform and generator uses kotlinx-serialization without "serializationLibrary" to "kotlinx_serialization" line.

stakancheck avatar Nov 16 '24 18:11 stakancheck