'How to return Generic List in FallbackHandler using Kotlin
I am trying to return List with Generic type from handle(context: ExecutionContext?) method of MicroProfile FallbackHandler using Kotlin. But it's throwing exception like " org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceDefinitionException: Invalid @Fallback on getDistanceData(java.lang.String): fallback handler's type java.util.List<? extends java.lang.String> is not the same as method's return type " RestClient :
@GET
@Path("/testFallbackUrl")
@Fallback(DistanceServiceFallback::class)
@CircuitBreaker(
requestVolumeThreshold = 4, failureRatio = 0.75, delay = 5000, successThreshold = 3
)
fun getDistanceData(@QueryParam("date") date: String) : List<String>
Handler:
@RegisterForReflection
class DistanceServiceFallback : FallbackHandler<List<String>> {
@field:Default
@field:Inject
lateinit var logger: Logger
override fun handle(context: ExecutionContext?): List<String> {
logger.error("Inside DistanceServiceFallback handler. ")
return listOf("Hello")
}
}
Solution 1:[1]
This is because of a difference in type inference when your kotlin code is processed in Java. The return type of getDistanceData is java.util.List<String> and the handler's return type is as mentioned in the exception java.util.List<? extends java.lang.String>.
The return type java.util.List<String> is observed from the CDI interceptor so I am not sure how exactly it is extracted but obviously it is not carrying <? extends E> information.
The handler's type java.util.List<? extends java.lang.String> is on the other hand extracted from kotlin.collections.List which is defined as public interface List<out E> : Collection<E> which I think is correct as <out E> should translate to <? extends E>.
However, there is an easy workaround:
@GET
@Path("/testFallbackUrl")
@Fallback(DistanceServiceFallback::class)
@CircuitBreaker(
requestVolumeThreshold = 4, failureRatio = 0.75, delay = 5000, successThreshold = 3
)
fun getDistanceData(@QueryParam("date") date: String) : MutableList<String> {
return mutableListOf("Default")
}
@RegisterForReflection
class DistanceServiceFallback : FallbackHandler<MutableList<String>> {
@field:Default
@field:Inject
lateinit var logger: Logger
override fun handle(context: ExecutionContext?): MutableList<String> {
logger.error("Inside DistanceServiceFallback handler. ")
return mutableListOf("Hello")
}
}
which works because MutableList is defined as public interface MutableList<E> : List<E>, MutableCollection<E> and thus it has now an exact generic type.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | xstefank |
