Open tjakopan opened 1 year ago
/cc @cescoffier (redis), @evanchooly (kotlin), @geoand (kotlin), @gsmet (redis), @machi1990 (redis)
Thanks for the report. Your approach looks good. Fancy a PR?
It might be worth to double check other primitives as well and apply the fix throughout and not just for long
Thanks for the report. Your approach looks good. Fancy a PR?
Sure, I'll do a PR, might be couple of days though.
Thanks for the report. Your approach looks good. Fancy a PR?
Sure, I'll do a PR, might be couple of days though.
Thanks @tjakopan shoutout if you need any help.
Thanks for the report. Your approach looks good. Fancy a PR?
Sure, I'll do a PR, might be couple of days though.
Couple of days turned into couple of months :-(. Previous company ended up not using quarkus and kotlin so completely forgot I have that PR almost ready.
I've upgraded the project to quarkus 3 and that issue is no longer there. With the changes to io.quarkus.redis.datasource.codecs.Codecs.JsonCodec
supporting type references, Long/long now defaults to JsonCodec and that case is now working correctly.
In fact, current IntegerCodec and DoubleCodec might not even be needed anymore.
I do have char, float, byte, short, long and boolean codecs implemented, if needed. @machi1990 @cescoffier
Definitely welcome!
Description
When trying to do a redis quide https://quarkus.io/guides/redis in kotlin I'm getting the following error
java.lang.IllegalArgumentException: Unable to encode object of type class java.lang.Long
when using ReactiveValueCommands with Long.private val countCommands: ReactiveValueCommands<String, Long> = dataSource.value(Long::class.java)
The issue is that
io.quarkus.redis.runtime.datasource.Marshaller
constructor is receivinglong
as a class hint which then resolves toJsonCodec
, but whenMarshaller.codec(Class<?>)
method is called in order to determine a codec,java.lang.Long
is passed as a param. Ultimately the codec cannot be found becauseMarshaller.codecs
map has a codec forlong
, not forjava.lang.Long
.The solution is to do this:
private val countCommands: ReactiveValueCommands<String, Long> = dataSource.value(Long::class.javaObjectType)
instead of this:private val countCommands: ReactiveValueCommands<String, Long> = dataSource.value(Long::class.java)
It would be easier to use this from kotlin without needing to explicitly specify
javaObjectType
.The reproducer is here in qs-redis module - https://github.com/tjakopan/quarkus-examples-kotlin. In order to reproduce the error, one can comment out line 13 and un-comment line 14 in
IncrementService
class and run the tests.Implementation ideas
io.quarkus.redis.datasource.codecs.Codecs
class could specify a LongCodec, similar to already existing codecs for double, int, String and byte[]. And then theCodecs.getDefaultCodecFor(Class<T>)
method could be changed to:Willing to contribute with this if needed.