clojure-dev 2023-09-04

Someone ran into an issue in babashka when calling Thread/sleep on a java.lang.Integer. bb uses reflection to find the right method (largely based on clojure.lang.Reflector) and it doesn't manage to find the method. A similar case can be constructed in Clojure itself:

user=> (def x (int 1))
#'user/x
user=> (type x)
java.lang.Integer
user=> (Thread/sleep x)
Execution error (IllegalArgumentException) at user/eval5 (REPL:1).
No matching method sleep found taking 1 args
I wonder if clojure.lang.Reflector itself could/should be updated to account for this, or maybe not? Any thoughts welcome.

This is on Java version 19 btw. Not sure if this issue happened before but from 19+ on Thread/sleep has multiple overloads

I think this might vaguely follow the java behavior (not sure though), that you can't pass an Integer(boxed object) to a method that takes a long(primitive), but you can pass an int to a method that takes a long

like this?

user=> (def x (int 1))
#'user/x
user=> (Thread/sleep ^int x)
nil
user=> (Thread/sleep ^java.lang.Integer x)
Execution error (IllegalArgumentException) at user/eval3 (REPL:1).
No matching method sleep found taking 1 args

But clojure does the conversion, or part of it for you in some cases, like whatever codepath it used before the sleep overload was added

We definitely had to wrap (long ...) around the arg in a lot of sleep calls when we started testing on 19+ javas

This is why I advocated for dedicated sleep function somewhere in the stdlib