Groovy, Callable and ExecutorService

Suppose you want submit job to ExecutorService.

The Baroque version

You could create a class that implements Callable:
class MyJob implements Callable<Integer> {
    @Override
    Integer call() throws Exception {
        return 42
    }
}
and give it to the executor service:
def 'submit callable as MyJob object'() {
    expect:
        executorService.submit(new MyJob()).get() == 42
}
The response is, as expected, 42.

Map as Callable version

You want to use this job only in one place so why not inline this class:
def 'submit callable as map'() {
    expect:
        executorService.submit([call: { 42 }] as Callable).get() == 42
}
The response is again 42.

Groovy closure version

Why not use closure instead of map?
def 'submit callable as closure'(){
    expect:
        executorService.submit { 42 }.get() == 42
}
The response is ... null.
Condition not satisfied:
executorService.submit { 42 }.get() == 42
|               |             |     |
|               |             null  false
|               java.util.concurrent.FutureTask@21de60b4
java.util.concurrent.Executors$FinalizableDelegatedExecutorService@1700915
Why? It is because Groovy treats this closure as Runnable, not Callable and Future#get returns null when task is complete.

Groovy closure version with cast

We have to cast our closure before submiting to executor service:
def 'submit callable as closure with cast'() {
    when:
        int result = executorService.submit({ return 42 } as Callable<Integer>).get()
    then:
        result == 42
}
The response is, as expected, again 42.

What interesting, the same test with inlined result variable fails... Strange... It could be Spock framework error.

Source code is available here.