【问题标题】:Is it possible to create writeable bean from Clojure that I can manage from jconsole?是否可以从我可以从 jconsole 管理的 Clojure 创建可写 bean?
【发布时间】:2026-02-16 17:10:02
【问题描述】:

我正在探索Clojure java.jmx API Reference 并尝试那里提到的示例,例如

;; Can I serve my own beans?  Sure, just drop a Clojure ref
;; into an instance of clojure.java.jmx.Bean, and the bean
;; will expose read-only attributes for every key/value pair
;; in the ref:

  (jmx/register-mbean
     (create-bean
     (ref {:string-attribute "a-string"}))
     "my.namespace:name=Value")

效果很好,bean 的属性值在控制台中可见但它是只读的。

有没有办法创建一个可写的bean(以便它列在“操作”文件夹中并可以从控制台进行管理)?

【问题讨论】:

    标签: clojure jmx clojure-java-interop


    【解决方案1】:

    看起来clojure.java.jmx 代码支持setAttribute。 (参见https://github.com/clojure/java.jmx/blob/master/src/main/clojure/clojure/java/jmx.clj中的(deftype Bean ...)

    最简单的方法似乎只是使用atom 而不是ref

    然后,如果 JMX 更改了某些代码,您可以让 atom watchers 运行一些代码。 也许试试看。我已经忘记了大部分 JMX ;)

    编辑:快速尝试。看起来该属性仍然是只读的:( 我得看得更深。尽管如此,源代码还是很不错的,希望很容易理解。

    编辑2: 问题在于build-attribute-infofalse 传递给`MBeanAttributeInfo 中的writeable? 标志。

    你可以修改那个:

    
    (import 'java.jmx.MBeanAttributeInfo)
    (require '[clojure.java.jmx :as jmx])
    
    (defn build-my-attribute-info
      "Construct an MBeanAttributeInfo. Normally called with a key/value pair from a Clojure map."
      ([attr-name attr-value]
      (build-my-attribute-info
      (name attr-name)
      (.getName (class attr-value)) ;; you might have to map primitive types here
      (name attr-name) true true false)) ;; false -> true compared to orig code
      ([name type desc readable? writable? is?] (println "Build info:" name type readable? writable?) (MBeanAttributeInfo. name type desc readable? writable? is? )))
    
    ;; the evil trick one should only use in tests, maybe
    ;; overwrite the original definition of build-attribute-info with yours
    (with-redefs [jmx/build-attribute-info build-my-attribute-info]
       (jmx/register-mbean (jmx/create-bean (atom {:foo "bar"})) "my.bean:name=Foo"))
    
    ;; write to it
    (jmx/write! "my.bean:name=Foo" "foo" "hello world")
    
    ;; read it
    (jmx/read "my.bean:name=Foo" "foo")
    => "hello world"
    
    

    现在,不幸的是,Java Mission Control 仍然无法更改该值,但我不确定为什么。 MBean 信息是正确的。 必须是许可的事情。

    【讨论】:

    最近更新 更多