I'm trying to implement an abstract message-consumer with kotlin and jackson for RabbitMQ. The setup for the consumers works fine, so I omit that in the code-snippets. The Problem is only in regard to parsing the String-payload to a generic-type object.
My Goal is to have an abstract class like :
abstract class AbstractRetryConsumer<T>(val queueName:String) : MessageListener {
// Autowiring and seting up the Beans
...
override fun onMessage(msg: Message) {
val msgPayload = String(msg.body, Charsets.UTF_8)
// the following line doesn't compile
val readValue = objectMapper.readValue<T>(msgPayload)
processEvent(readValue)
}
abstract fun processEvent(payload: T)
...
}
Then I'd be able to implement a Consumer like:
@Service
class NotificationConsumer(
) : AbstractRetryConsumer<Notification>("myQueue") {
// gets the payload as a parsed object
override fun processEvent(payload: Notification) {
println("payload ist: $payload")
}
}
The compiler won't accept that. The error is: Cannot use 'T' as reified type parameter. Use a class instead.
I know there are many similar questions, but I didn't find an answer to my problem.
Thanks for your inquires and answers
CodePudding user response:
When using the Jackson Kotlin module, the object mapper has an inline extension readValue
with reified generic parameter. Since the paramter in your call objectMapper.readValue<T>(msgPayload)
is reified, your class AbstractRetryConsumer<T>
also needs to define a reified parameter T
. However, that means your class has to be inline, and it looks too big to be inline. Therefore, you should add a JavaClass argument to your constructor and call the non-extension version of readValue
:
val readValue = objectMapper.readValue(msgPayload, payloadClass)