I'm writing a Clojure wrapper for the Braintree Java library to provide a more concise and idiomatic interface. I'd like to provide functions to instantiate the Java objects quickly and concisely, like:

(transaction-request :amount 10.00 :order-id "user42")

I know I can do this explicitly, as shown in this question:

(defn transaction-request [& {:keys [amount order-id]}]
  (doto (TransactionRequest.)
    (.amount amount)
    (.orderId order-id)))

But this is repetitive for many classes and becomes more complex when parameters are optional. Using reflection, it's possible to define these functions much more concisely:

(defn set-obj-from-map [obj m]
  (doseq [[k v] m]
    (clojure.lang.Reflector/invokeInstanceMethod
      obj (name k) (into-array Object [v])))
  obj)

(defn transaction-request [& {:as m}]
  (set-obj-from-map (TransactionRequest.) m))

(defn transaction-options-request [tr & {:as m}]
  (set-obj-from-map (TransactionOptionsRequest. tr) m))

Obviously, I'd like to avoid reflection if at all possible. I tried defining a macro version of set-obj-from-map but my macro-fu isn't strong enough. It probably requires eval as explained here.

Is there a way to call a Java method specified at runtime, without using reflection?

Thanks in advance!

Updated solution:

Following the advice from Joost, I was able to solve the problem using a similar technique. A macro uses reflection at compile-time to identify which setter methods the class has and then spits out forms to check for the param in a map and call the method with it's value.

Here's the macro and an example use:

; Find only setter m
Edit
Report