Skip to content

Instantly share code, notes, and snippets.

@egamble
Last active May 16, 2023 12:41
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save egamble/7781127 to your computer and use it in GitHub Desktop.
Save egamble/7781127 to your computer and use it in GitHub Desktop.
Two ways to call private methods in Clojure.
;; This fn allows calling any method, as long as it's the first with that name in getDeclaredMethods().
;; Works even when the arguments are primitive types.
(defn call-method
[obj method-name & args]
(let [m (first (filter (fn [x] (.. x getName (equals method-name)))
(.. obj getClass getDeclaredMethods)))]
(. m (setAccessible true))
(. m (invoke obj (into-array Object args)))))
;; This function comes from clojure.contrib.reflect. A version of it is also in https://github.com/arohner/clj-wallhack.
;; It allows calling any method whose arguments have class types, but not primitive types.
(defn call-method
"Calls a private or protected method.
params is a vector of classes which correspond to the arguments to the method
obj is nil for static methods, the instance object otherwise.
The method-name is given a symbol or a keyword (something Named)."
[klass method-name params obj & args]
(-> klass (.getDeclaredMethod (name method-name)
(into-array Class params))
(doto (.setAccessible true))
(.invoke obj (into-array Object args))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment