Reproduce

The issue does not occur in the JVM environment, but it fails in the native environment.

kotlin generic class

kotlin generic class edu.tyut.dating.bean.Result

import kotlinx.serialization.Serializable

@ConsistentCopyVisibility
@Serializable
internal data class Result <T> private constructor(
    internal val code: Int,
    internal val message: String,
    internal val data: T,
) {
    internal companion object {
        private const val SUCCESS: Int = 200
        private const val FAILURE: Int = 500
        internal fun <T> success(message: String, data: T) = Result<T>(code = SUCCESS, message = message, data = data)
        internal fun <T> failure(message: String, data: T) = Result<T>(code = FAILURE, message = message, data = data)
    }
}

source

https://github.com/myfaverate/KotlinWeb/tree/master/dating

next

./gradlew nativeRun

Access the URL http://localhost:8080/hello/success in a browser

Phenomenon

[2025-06-01 14:27:02] [qtp1710373188-63] HelloController.kt:38 INFO  e.t.d.controller.HelloController : success -> headers: {Host=localhost:8080, Connection=keep-alive, Cache-Control=max-age=0, sec-ch-ua="Chromium";v="136", "Microsoft Edge";v="136", "Not.A/Brand";v="99", sec-ch-ua-mobile=?0, sec-ch-ua-platform="Windows", Upgrade-Insecure-Requests=1, User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0, Accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7, Sec-Fetch-Site=none, Sec-Fetch-Mode=navigate, Sec-Fetch-User=?1, Sec-Fetch-Dest=document, Accept-Encoding=gzip, deflate, br, zstd, Accept-Language=zh-CN,zh;q=0.9,en;q=0.8}
[2025-06-01 14:27:02] [qtp1710373188-63] AbstractHandlerExceptionResolver.java:254 WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class edu.tyut.dating.bean.Result] with preset Content-Type 'null']

TAG

spring-boot kotlin generics kotlinx.serialization aot

Comment From: sdeleuze

I can indeed reproduce, can be workaround with:

@SpringBootApplication
@ImportRuntimeHints(DatingApplication::class)
private class DatingApplication : RuntimeHintsRegistrar {

    override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
        hints.reflection().registerType<Result.Companion> {
            it.withMembers(MemberCategory.INVOKE_DECLARED_METHODS)
        }
    }
}

Comment From: myfaverate

@sdeleuze You are my god, thank you very much! 🙏

Comment From: myfaverate

@sdeleuze Thank you very much. This issue has not only been resolved, but it also provided great inspiration for solving this issue: https://github.com/netty/netty/issues/15331. I really appreciate it!

Comment From: sdeleuze

You're welcome, I would like to try to see if it can be supported out-of-the-box so I will reopen it.

Comment From: myfaverate

@sdeleuze That's awesome!

Comment From: sdeleuze

Fixed, should now work out of-the-box.