Search code examples
javamultithreadingjenkinsexecutorservicecallable

reference to submit is ambiguous: <T>submit(Callable<T>) in ExecutorService and method submit(Runnable) in ExecutorService match


I am registering a callable and saving it into a future object like this:

final Future<SomeObject> objectFuture= Executors.newFixedThreadPool(5).submit(
                    () -> methodReturnsSomeObject(someValue));

I am getting the following compilation error but its building locally:

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /c:/1/5889/001/target/clover/src/com/... reference to submit is ambiguous

both method submit(java.util.concurrent.Callable) in java.util.concurrent.ExecutorService and method submit(java.lang.Runnable) in java.util.concurrent.ExecutorService match

This happens when there are ambiguity in overloaded methods e.g. Integer... and int... according to Compiler error : reference to call ambiguous. I do not see why its showing this here. I am clearly passing a Callable here in the above method. Please let me know how it is ambiguous? Also, since my maven build is passing locally and not in Jenkins, do I need to look at the Jenkins server configuration? Thanks in advance

Java version: 1.8 Maven Version: 3.0.5


Solution

  • submit() has 2 overloads with one argument. The arguments are both functional interfaces, with the following methods:

    Your lambda expression is () -> methodReturnsSomeObject(someValue).

    If the method hadn't returned anything, i.e. was a void method, it could only implement Runnable, so there would have been no ambiguity.

    But since the method has a return value matching type T (SomeObject in your case), the lambda expression can implement Callable, but it can also implement Runnable by ignoring/discarding the return value. Having it implement Callable is of course preferable.

    Be aware that some compilers will resolve to Callable, especially newer versions of the compiler, which will have improved inference handling, so you will not always experience this issue.

    To resolve an ambiguity, cast to the parameter type you desire. In this case, we desire Callable, so:

    final Future<SomeObject> objectFuture = Executors.newFixedThreadPool(5).submit(
                        (Callable<SomeObject>) () -> methodReturnsSomeObject(someValue));