# Functional way to handle JMSConnection open and close with Clojure

I wrote this code to automatically open and close my JMSConnection's in Clojure:

(defn with-jms
([provider-url context-factory factory-name fn args]
(with-open [jndi-ctx (new InitialContext (populate-env provider-url context-factory))
jms-conn (-> (.lookup jndi-ctx factory-name)
(.createConnection))]
(apply fn (-> (sequence args)
(conj jms-conn)
(conj jndi-ctx)))))
([fn args]
(let [{provider-url    "provider-url"
context-factory "context-factory"
factory-name    "factory-name"} jms-properties]
(with-jms provider-url context-factory factory-name fn args))))


Note how properties are used for convenience. Please also note that populate-env is a function that returns a HashTable populated with the necessary JMS properties.

I can then define JMS functions the following way:

(defn send-text-message! [jndi-ctx jms-conn topic content]
(with-open [session (.createSession jms-conn false Session/AUTO_ACKNOWLEDGE)
producer (.createProducer session (.lookup jndi-ctx topic))]
(let [message (.createTextMessage session content)]
(.send producer message))))


I can combine both functions in the following way :

(with-jms send-text-message! ["clojureTopic" "azerty"])


However I'm not 100% satisfied with it. These are the things that puzzle me:

• In with-jms, the args in with-jms is an array, because overloading and multi-varied arguments is not supported in Clojure. Is there a better alternative?
• In with-jms, the (apply fn (-> (sequence args) (conj jms-conn) (conj jndi-ctx))) part feels really clunky, is there a better way to write that?
• When I call with-jms function, I must remember to exclude the jndi-ctx and the jms-conn from the argument lists even if it's in the called function signature. I don't like it, I find it confusing. I tried to write a wrapper that returns a partial function but it felt unnecessary and tedious to do for every JMS function. Maybe there's a better way to write with-jms?

Any help would be appreciated !