clojure-dev

Issues: https://clojure.atlassian.net/browse/CLJ | Guide: https://insideclojure.org/2015/05/01/contributing-clojure/
2020-11-30T04:08:47.281200Z

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.

alexmiller 2020-11-30T14:45:22.284700Z

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

alexmiller 2020-11-30T14:49:42.284900Z

https://clojure.atlassian.net/browse/CLJ-1243 is the one I'm thinking of

alexmiller 2020-11-30T14:51:31.285100Z

https://ask.clojure.org/index.php/4255/cannot-resolve-public-generic-method-package-private-class is the equivalent ask clojure page for public voting or comments

2020-11-30T15:55:00.285400Z

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 @stuartrexking - 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.

stuartrexking 2020-12-01T06:37:59.285600Z

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

2020-11-30T04:12:52.281700Z

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

2020-11-30T04:13:48.282200Z

Public git repo of @stuartrexking code: https://github.com/stuartrexking/pdfboxing

2020-11-30T04:14:48.282500Z

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)

2020-11-30T04:15:00.282700Z

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

2020-11-30T04:15:27.282900Z

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

2020-11-30T04:17:15.283100Z

The method named setNonStrokingColor has 1 signature in the class PDAppearanceContentStream here: https://github.com/apache/pdfbox/blob/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAppearanceContentStream.java#L168

2020-11-30T04:18:29.283500Z

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: https://github.com/apache/pdfbox/blob/fffad2fe3ff74eaca909fce65cf1dd4191ceb036/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAbstractContentStream.java#L76

2020-11-30T04:18:46.283900Z

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