Fork me on GitHub

I'm chatting with someone who is trying to use Java interop on a class where there is 1 method in a class with a particular name and 1 parameter, and it extends an abstract class that has several more methods with the same name and 1 parameter (different types for that parameter). When he is trying to call a method on an instance of the child class, but the method he wants to call is in the abstract parent class, Clojure reflection seems to prefer non-bridge methods over bridge methods, and all of the methods in the parent class are bridge methods in the child class. Even with an explicit type hint on the 1 parameter in the Clojure interop call, it gives a ClassCastException at Java interop call time, because it cannot cast the type of the parameter in the interop call to the type of a different method than the one the developer is trying to call. More details in thread.


Here is a link to the discussion (I hope, if I am doing this correctly):


Minimal repro is to fire up a REPL using the deps.edn file in the root dir of that repo, then evaluate these two expressions:

(require '[ventures.fierce.pdfbox.core :as c])
(in-ns 'ventures.fierce.pdfbox.core)


then eval the expression in the comment block at the end of the core.clj source file.


OK, maybe not minimal repro, but at least very quick to get to the exception.


and that one is the one that the Clojure Reflector code seems to find, even though it has the wrong type. The others are in the abstract parent class here:


I am not sure if this is a case that Clojure reflection is intended to handle correctly, or not.

Alex Miller (Clojure team)14:11:22

reminds me of an old issue with reflection and bridge methods, let me see if I can find it.


Thanks for the links, Alex! The description makes it sound like it could very well be exactly that issue. The workaround mentioned by one commenter is one that I mentioned to @U3FKR3KDF - define a small class in Java that calls only the java methods that you need. Make everything you need public, and then if it works, use Java interop to call those methods. A pain, but probably effective.


Thanks for that. I’ve created a class to manage the interop.