Skip to content

Commit 546139c

Browse files
committed
Allow setting attributes on beans created with java.jmx.
Patch for JMX-16 by Michael Nussbaum.
1 parent 1a595d6 commit 546139c

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

src/main/clojure/clojure/java/jmx.clj

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
(:import [clojure.lang Associative]
7777
java.lang.management.ManagementFactory
7878
[javax.management Attribute AttributeList DynamicMBean MBeanInfo
79-
ObjectName RuntimeMBeanException MBeanAttributeInfo]
79+
ObjectName RuntimeMBeanException MBeanAttributeInfo MBeanServerConnection]
8080
[javax.management.remote JMXConnectorFactory JMXServiceURL]))
8181

8282
(def ^{:dynamic true
@@ -235,9 +235,9 @@
235235
"Write an attribute value."
236236
[n attr value]
237237
(.setAttribute
238-
*connection*
239-
(as-object-name n)
240-
(Attribute. (name attr) value)))
238+
^MBeanServerConnection *connection*
239+
^ObjectName (as-object-name n)
240+
(Attribute. ^String (name attr) ^String value)))
241241

242242
(defn ^{:skip-wiki true} attribute-info
243243
"Get the MBeanAttributeInfo for an attribute."
@@ -333,10 +333,36 @@
333333
(let [result (AttributeList.)]
334334
(doseq [attr attrs]
335335
(.add result (Attribute. attr (.getAttribute _ attr))))
336-
result)))
336+
result))
337+
(setAttribute [_ attr]
338+
(let [attr-name (.getName attr)
339+
attr-value (.getValue attr)
340+
state-update {(keyword attr-name) attr-value}]
341+
(condp = (type state-ref)
342+
clojure.lang.Agent
343+
(await (send state-ref (fn [state state-update] (merge state state-update)) state-update))
344+
345+
clojure.lang.Atom
346+
(swap! state-ref merge state-update)
347+
348+
clojure.lang.Ref
349+
(dosync
350+
(ref-set state-ref
351+
(merge @state-ref state-update))))))
352+
(setAttributes [_ attrs]
353+
(let [attr-names (map (fn [attr]
354+
(.setAttribute _ attr)
355+
(.getName attr))
356+
attrs)]
357+
(.getAttributes _ (into-array attr-names)))))
358+
337359

338360
(defn create-bean
339361
"Expose a reference as a JMX bean. state-ref should be a Clojure
340-
reference (ref, atom, agent) containing a map."
362+
reference (ref, atom, agent) containing a map.
363+
364+
Using an agent for the state-ref is not recommended when the bean may
365+
be modified with the setAttribute(s) methods. The setAttribute(s) methods
366+
will block on the agent to complete all submitted actions (via await)."
341367
[state-ref]
342368
(Bean. state-ref))

src/test/clojure/clojure/java/test_jmx.clj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,27 @@
175175
1 (.getAttribute bean "a")
176176
2 (.getAttribute bean "b"))))))
177177

178+
(deftest test-setAttribute
179+
(doseq [reftype [ref atom agent]]
180+
(let [state (reftype {:a 1 :b 2})
181+
bean (jmx/create-bean state)]
182+
(testing (str "setting values on a " (class state))
183+
(.setAttribute bean (Attribute. "a" 3))
184+
(are [result expr] (= result expr)
185+
3 (.getAttribute bean "a")
186+
2 (.getAttribute bean "b"))))))
187+
188+
(deftest test-setAttributes
189+
(doseq [reftype [ref atom agent]]
190+
(let [state (reftype {:r 5 :d 4})
191+
bean (jmx/create-bean state)
192+
atts (.setAttributes bean (AttributeList. [(Attribute. "r" 6)
193+
(Attribute. "d" 5)]))]
194+
(are [x y] (= x y)
195+
AttributeList (class atts)
196+
["r" "d"] (map (memfn getName) (seq atts))
197+
[6 5] (map (memfn getValue) (seq atts))))))
198+
178199
(deftest test-bean-info
179200
(let [state (ref {:a 1 :b 2})
180201
bean (jmx/create-bean state)

0 commit comments

Comments
 (0)