replay-framework / replay

Fork of the Play1 Framework
Other
20 stars 11 forks source link

Binding of Kotlin collections in controller action methods fails #244

Open cies opened 1 year ago

cies commented 1 year ago

RePlay's binder for collections is not Kotlin-ready, it can only bind Java collections. See it here:

https://github.com/codeborne/replay/blob/1df33d413605cb40935db2adc19c8e75f26c00ba/framework/src/play/data/binding/Binder.java#L389

Here a relevant bit of the stack trace:

java.lang.ClassCastException: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl cannot be cast to class java.lang.Class (sun.reflect.generics.reflectiveObjects.WildcardTypeImpl and java.lang.Class are in module java.base of loader 'bootstrap')
    at play.data.binding.Binder.bindCollection(Binder.java:406)
    at play.data.binding.Binder.internalBind(Binder.java:188)
    at play.data.binding.Binder.bind(Binder.java:130)
    at play.mvc.ActionInvoker.getActionMethodArgs(ActionInvoker.java:521)

We've worked around it like this:

image

Since we have warnings as errors on for Kotlin we had to add a suppression.

cies commented 1 year ago

I'm not sure if adding Koltin's collection classes is a good idea since it would pull in a Kotlin dependency in to RePlay's framework while some may only need Java.

cies commented 12 months ago

Please close this as "wont fix" if you @asolntsev believe we should not make framework depend on Kotlin libs (which I think is a reasonable position, and a work around exist). This issue may can then document a work-around/ solution to anyone ever running into this issue as well (small chance but still).

asolntsev commented 9 months ago

Yes, I don't think Replay should depend on Kotlin libs. But Replay should work with Kotlin.

Or as an option, Replay could have a separate module like "replay-kotlin". Everyone who adds this dependency to their project, automatically gets Kotlin dependencies and support for collections and anything else.

cies commented 7 months ago

So we first need to make the binding more configurable that it is now. Currently we can create custom binding types with RePlay, but these cannot be container types (or parameterized interfaces) afaik.

I'm okay with the workaround (e.g. using java.util.List in Kotlin code) described above.