Weird Java Interop issues

@pesterhazy those are some good questions, I’m also no expert on these things, but I do know clojure.lang.Reflector has gotten a lot more complex and strict in recent versions (1.10? 1.9?) to accomodate the Java 9 module system. Before that reflection sometimes allowed you to bypass some Java visibility rules, whereas now it will also enforce these.

That still leaves me puzzled as to what’s going on here

(let [mixer (get-mixer (:mixer-info (get-current-mixer-info @cameba.core/*state)))
      [method] (clojure.lang.Reflector/getMethods
                (class mixer)
                1
                "getLine"
                false)]
  {:method method
   :mixer-class (class mixer)
   :canAccess (.canAccess method mixer)})
;;=>
;; {:method
;;  #object[java.lang.reflect.Method 0x5f1d6566 "public javax.sound.sampled.Line com.sun.media.sound.PortMixer.getLine(javax.sound.sampled.Line$Info) throws javax.sound.sampled.LineUnavailableException"],
;;  :mixer-class com.sun.media.sound.PortMixer,
;;  :canAccess false}
  • We’re calling .getLine on an instance of com.sun.media.sound.PortMixer
  • The Reflector is able to find that method, you can see the signature:
public javax.sound.sampled.Line com.sun.media.sound.PortMixer.getLine(javax.sound.sampled.Line$Info)
  • but it won’t call it, because the Java reflection API (Method.canAccess) says that this class may not access this method

So I don’t think it’s a Clojure bug, it’s merely doing what Java tells it to do, but why .canAccess returns false for what is simply calling a public method directly on the object I have no idea.

1 Like