feign icon indicating copy to clipboard operation
feign copied to clipboard

feign-kotlin: Decoder type returns "Object" when method is suspending

Open JayPeaSize opened this issue 1 year ago • 6 comments

Currently using feign-kotlin 12.3 and kotlin 1.8.10 while attempting to use a custom decoder. When my method in the the TestClient is suspending type is printed out as "java.lang.Object" however, when not using suspend it returns the proper type of TestObject. This is currently preventing me from being able to get the proper serializer

Client Snippet:

public interface TestClient  {
    @RequestLine("GET /{uuid}")
    public suspend fun testGet(@Param("uuid") uuid: UUID): TestObject
}

Decoder snippet:

public class CustomDecoder: Decoder {
    override fun decode(response: Response, type: Type): Any? {
        if (response.status() != 404 && response.status() != 204) {
                ...
                println(type)
               ...
            }
        } else {
           ...
        }
    }
}

JayPeaSize avatar Apr 23 '23 03:04 JayPeaSize

I'm not Kotlin expert, but this appears to be an issue related to reflection. type in this case is java.lang.reflect.Type, so you may need to consider using Kotlin reflection to obtain the type. Here's an example I found that explains this situation.

https://blog.kotlin-academy.com/a-little-reflection-about-coroutines-34050cbc4fe6

So I'm not sure if this a bug in Feign Kotlin or an issue with your decoder.

kdavisk6 avatar May 24 '23 14:05 kdavisk6

This issue is reproducible with the feign.jackson.JacksonDecoder from the io.github.openfeign:feign-jackson:12.4 dependency.

I set breakpoint at feign.Contract#parseAndValidateMetadata, and observed for a Kotlin suspend function signature like this:

suspend fun testGet(uuid: UUID): TestObject

It would translate to the following Java method signature:

public abstract java.lang.Object testGet(UUID, kotlin.coroutines.Continuation<TestObject>)

Currently, feign is taking the return type of the method as response type, but the generic parameter of the kotlin.coroutines.Continuation should be took instead.

It is not possible to implement any workaround in Decoder level, because feign passes java.lang.Object into the type parameter of the decode method.

sunny-chung avatar Sep 18 '23 09:09 sunny-chung