Jinq in Kotlin - how to convert lambda into java S

2019-08-02 14:29发布

Can I have serializable lambda in Kotlin? I am trying to use Jinq library from Kotlin, but it requires serializable lambdas. Is there any syntax that makes it possible?

Update:

My code:

var temp=anyDao.streamAll(Task::class.java)
   .where<Exception,Task> { t->t.taskStatus== TaskStatus.accepted }
   .collect(Collectors.toList<Task>());

I am getting this error:

Caused by: java.lang.IllegalArgumentException: 
Could not extract code from lambda. 
This error sometimes occurs because your lambda references objects that aren't Serializable.

All objects referenced in lambda are serializable (code results in no errors in java).

Update 2

After debugging it seems that kotlin lambda isn't translated into java.lang.invoke.SerializedLambda which is required by Jinq to get information from. So the problem is how to convert it to SerializedLambda.

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-08-02 15:17

I have no experience on Jinq, but according to the implementation in GitHub and my experience of using Java Library in Kotlin.

ref: https://github.com/my2iu/Jinq/blob/master/api/src/org/jinq/orm/stream/JinqStream.java

You can always fall back to use the native Java Interface in Kotlin.

var temp = anyDao.streamAll(Task::class.java)
   .where( JinqStream.Where<Task,Exception> { t -> t.taskStatus == TaskStatus.accepted } )
   .collect(Collectors.toList<Task>());

 // Alternatively, You you can import the interface first
 import org.jinq.orm.stream.JinqStream.*

  ... 

  // then you can use Where instead of JinqStream.Where
  var temp = anyDao.streamAll(Task::class.java)
       .where(Where<Task,Exception> { t -> t.taskStatus == TaskStatus.accepted } )
       .collect(Collectors.toList<Task>());

Or make a custom extension to wrap the implementation

fun JinqStream<T>.where(f: (T) -> Boolean): JinqStream<T> {
  return this.where(JinqStream.Where<T,Exception> { f(it) })
}

Disclaimer: The above codes have not been tested.

查看更多
别忘想泡老子
3楼-- · 2019-08-02 15:25

I'm the maker of Jinq. I haven't had the time to look at Kotlin-support, but based on your description, I'm assuming that Kotlin compiles its lambdas into actual classes or something else. As such, Jinq would probably need some special code for cracking open Kotlin lambdas, and it may also need special code for handling any unusual Kotlin-isms in the generated code. Jinq should be capable of handling it because it was previously retrofitted to handle Scala lambdas.

If you file an issue in the Jinq github about it, along with a small Kotlin example (in both source and .class file form), then I can take a quick peek at what might be involved. If it's small, I can make those changes. Unfortunately, if it looks like a lot of work, I don't think I can really justify putting a lot of resources into adding Kotlin support to Jinq.

查看更多
登录 后发表回答