Why when using suspend in my controller it breaks?


Im using Kotlin since very few time and I am facing a difficult problem now.

I have a controller that receives the body in a JSON format, worked fine but now I need to call a service that returns a Deferred , because of that I need to annotate my method with suspend.

Unfortunately now I get a serie of multiple errors that I feel are related with this new suspended functionality.

[FATAL] Method public final java.lang.Object MyResource.sayHello(StudentRequest,kotlin.coroutines.Continuation) on resource class MyResource contains multiple parameters with no annotation. Unable to resolve the injection source.;

handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@a0bf272]}, definitionMethod=public final java.lang.Object my.org.package.MyResource(sayHello,k**otlin.coroutines.Continuation**), 

Any idea of what could it be? or how can I implement a simple controller like the one I am trying to?

Hi there, suspending methods are something internal to kotlin, when compiled to Java, an additional Continuation parameter is added to the method, this continuation is what kotlin uses internally to keep track of the execution context (local variable for example).

If you write a suspending method, java library (such as glassfish in your example) don’t know how to provide the extra continuation parameter, leading to the error you see.

the two available solutions are: don’t use suspending methods, or use frameworks that support suspending function (such as spring boot or ktor)

1 Like

Thanks for your reply! is there any example/doc where I can look for to see how actually implement one? Or any configuration of frameworks you recommend? I am using dropwizard at the moment, but would like to keep that framework (since is not my decision to implement it) , I thought Deferred could help me with this, any idea if is possible?

Hey sorry for the late reply, I never used dropwizard and don’t know anything about it, but if it support asynchronous return types (Deferred, Future, Promise, you name it) you can simply launch a coroutine inside your controller (using launch(){}) and resolve your deferred inside it.

as for implementing a support for suspending function , you should search if your framework allows you to customize the way a controller is called, and if so, you can write a way to call suspending function (simply by launching a coroutine and calling the controller). Look into Spring framework, they support suspending controller and their implementation is quite straightforward.

1 Like