Kotlin, Callable and ExecutorService

I’ve recently written about using Callable in Groovy, but how does it look like in kotlin?Callable instance as separete class First, let’s create class which implements Callable interface:class MyJob : Callable<Int> { override fun call() = 42}…

I’ve recently written about using Callable in Groovy, but how does it look like in kotlin?

Callable instance as separete class

First, let’s create class which implements Callable interface:

class MyJob : Callable {
    override fun call() = 42
}

Now we could pass instance of this class to executorService:

fun callableAsClassInstance() = executorService.submit(MyJob()).get()

When we run it, as we expect, it returns 42. (Tests are written in groovy, not in kotlin).

def 'should submit callable as class instance from kotlin'() {
    expect:
        callableExample.callableAsClassInstance() == 42
}

Casting to Callable

If we create map with string “call” to closure or just closure and try to cast to Callable, we always obtain CastClassException:

fun callableAsMap() = executorService.submit(mapOf("call" to { 42 }) as Callable).get()

fun callableAsClosure() = executorService.submit({ 42 } as Callable).get()
def 'should submit callable as closure from kotlin'() {
    when:
        callableExample.callableAsClosure() == 42
    then:
        thrown(ClassCastException)
}

def 'should submit callable as map from kotlin'() {
    when:
        callableExample.callableAsMap() == 42
    then:
        thrown(ClassCastException)
}

It does not work as in groovy…

Pass instance method

So maybe passing an instance method which produces value will work?

private fun callMe() = 42

fun callableAsPassedFunction(): Int? {
    return executorService.submit(::callMe).get()
}

It does not even compile. Why? It moans that there is no submit method which could be called with such argument…

But, what interesting, if we create a value to which we assign closure and pass it to submit method then everything is ok and get returns 42.

private val callMe = { 42 }

fun callableAsPassedLocalFunction(): Int? {
    return executorService.submit(callMe).get()
}

Inline implementation

Of course, there is also an option to create Callable inline:

fun callableAsInlineImplementation() = executorService.submit(Callable { 42 }).get()

And this is IHMO the best and the most comfortable way to create Callable in kotlin, because its syntax is much nicer than in java or groovy.

Source code is available here.

You May Also Like

Spring security authentication-success-handler-ref and authentication-failure-handler-ref does not work with KerberosServiceAuthenticationProvider

I'm using SpringSecurity with KerberosServiceAuthenticationProvider which is Kerberos security extension. You can read how to use it on extension author's blog.But you cannot use handler on form-login to catch authorization result. It's because of inne...I'm using SpringSecurity with KerberosServiceAuthenticationProvider which is Kerberos security extension. You can read how to use it on extension author's blog.But you cannot use handler on form-login to catch authorization result. It's because of inne...

Cross-platform mobile apps – possible or not?

What is Titanium and how it works. Titanium is an open-source solution for cross-platform, almost-native mobile app development. It has its own MVC, JavaScript and XML-based framework Alloy. Titanium is based on assumption, that each app can be divided into two parts: UI, which is platform-specific part and application core – business logic, common to all […]What is Titanium and how it works. Titanium is an open-source solution for cross-platform, almost-native mobile app development. It has its own MVC, JavaScript and XML-based framework Alloy. Titanium is based on assumption, that each app can be divided into two parts: UI, which is platform-specific part and application core – business logic, common to all […]