java.lang.IllegalArgumentException: More than one matching method found: submit - when "letting" an ExecutorService

270 views
Skip to first unread message

Alf Kristian Støyle

unread,
Jul 16, 2011, 7:13:11 AM7/16/11
to clo...@googlegroups.com
Hi guys. Experimenting a bit with code from "The joy of Clojure", and
I ran into a little problem. Trying to run this in the REPL gives the
following error:

user=> (import [java.util.concurrent Executors])
java.util.concurrent.Executors

user=> (let [*pool* (Executors/newFixedThreadPool (+ 2
(.availableProcessors (Runtime/getRuntime))))]
(defn dothreads! [f & {thread-count :threads
exec-count :times
:or {thread-count 1 exec-count 1}}]
(dotimes [t thread-count]
(.submit *pool* #(dotimes [_ exec-count] (f))))))
java.lang.IllegalArgumentException: More than one matching method
found: submit (NO_SOURCE_FILE:7)


However if I define pool as a Var it seems to work fine:

user=> (import '(java.util.concurrent Executors))
java.util.concurrent.Executors

user=> (def *pool* (Executors/newFixedThreadPool
(+ 2 (.availableProcessors (Runtime/getRuntime)))))
#'user/*pool*

user=> (defn dothreads! [f & {thread-count :threads
exec-count :times
:or {thread-count 1 exec-count 1}}]
(dotimes [t thread-count]
(.submit *pool* #(dotimes [_ exec-count] (f)))))
#'user/dothreads!

(from https://github.com/joyofclojure/book-source/blob/master/src/joy/mutation.clj)

ExecutorService has three submit methods, and two with one parameter,
a Runnable and a Callable. Since Clojure functions are both, I
understand the compiler error, but why does it work when *pool* is a
Var?

The "let" version works when I cast the function to Runnable or
Callable, just wondering why there is a difference.

Cheers,
Alf

Alex Miller

unread,
Mar 11, 2014, 4:44:36 PM3/11/14
to clo...@googlegroups.com
In the let case, the *pool* will be tagged with the proper type so the ambiguity is detected.

In the def case, the *pool* will be seen as an object and the compiler is just deferring to reflection at runtime to figure it out. If you turn on *warn-on-reflection*, you'll see a reflection warning in this case. Reflection is just picking the first one that matches in that case. If you type hinted the def case, you'd see the same error.

Alex Miller

unread,
Mar 11, 2014, 4:46:09 PM3/11/14
to clo...@googlegroups.com
Sorry for the deep storage reply - this was just referenced from a ticket and I didn't realize it was super old. :) 
Reply all
Reply to author
Forward
0 new messages