MBean(JMX)を触る

MBean(JMX)を触ってみたメモです。

たまに調査でサーバのリモートJMXにつないでプロファイルを取得したりする機会はあるのですが、
MBeanを一度も手動で作成したことないな、と思ったので触ってみようと思いました。

下記バージョンで試してみます。

  • kotlin 1.6.20
  • jconsole 17.0.2

とりあえず下記のチュートリアルをやってみます。
https://docs.oracle.com/javase/jp/1.5.0/guide/jmx/index.html

まずは開示するプロパティと操作を持つインターフェースを定義します。
MBeanインターフェースのルールで、クラス名の末尾にMBeanをつけます。

このインターフェースは読み込みのみ出来るnameプロパティと、読み書き出来るcacheSizeプロパティを持ちます。
取得するためのメソッドはgetから始まりpublicである必要がありますが、kotlinなのでこのままで大丈夫です。
設定するためのメソッドはsetから始まり単一の引数を取るpublicメソッドである必要があります。これもkotlinなので大丈夫です。

add()メソッドとsayHello()メソッドの2つの関数も定義しておきます。

HelloMBean.kt

interface HelloMBean {
    val name: String
    var cacheSize: Int
    fun sayHello()
    fun add(x: Int, y: Int): Int
}

次にHelloMBeanを実装したクラスを作成します。

nameは固定値を設定します。この値はvalで宣言しているので変更できません。
cacheSizeはデフォルト値を設定していますが、この値はvarで宣言しているので変えることができます。
sayHello()は単純な標準出力をし、add()は2つの整数を足して返します。

Hello.kt

class Hello : HelloMBean {
    companion object {
        private const val DEFAULT_CACHE_SIZE = 200
    }
    override val name = "Reginald"
    override var cacheSize = DEFAULT_CACHE_SIZE

    override fun sayHello() {
        println("hello, world")
    }

    override fun add(x: Int, y: Int) = x + y
}

MBeanサーバを取得し、MBeanを登録します。
MBeanのオブジェクト名定義のためにObjectNameを作成し、Hello MBeanのインスタンスを作成して
MBeanサーバに登録します。

実行後スリープして起動したままにしておきます。

Main.kt

fun main() {
    val mbs: MBeanServer = ManagementFactory.getPlatformMBeanServer()

    val name = ObjectName("com.example.jmx:type=Hello")

    val mbean = Hello()

    mbs.registerMBean(mbean, name)

    println("Waiting forever...")
    Thread.sleep(Long.MAX_VALUE)
}

起動

Waiting forever...

jconsoleでアクセスしてみます。

jconsoleを起動して起動したアプリケーションのプロセスを選択します。

Helloを選択するとMBeanの情報が見れます。

属性を選択するとCacheSizeNameの値を参照できます。

Nameを選択すると、書き込み可能がfalseになっていることがわかります。

CacheSizeを選択すると、書き込み可能がtrueになっていることがわかります。

操作を選択するとaddsayHelloのメソッドを参照できます。

addを選択し、数値を入力してaddボタンを押してみます。

addの結果がポップアップで表示されました。

sayHelloを選択し、sayHelloボタンを押してみます。

コンソールにhello, worldが表示されました。

hello, world

 
 
サンプルコードは下記にあげました。
 
 
おわり。
 
 
【参考】
https://docs.oracle.com/javase/jp/1.5.0/guide/jmx/index.html
https://www.javainthebox.net/laboratory/J2SE1.5/MonitoringAndManagement/JMX/JMX1.html
https://blog.cybozu.io/entry/2018/02/05/080000
https://docs.oracle.com/cd/F25597_01/document/products/wls/docs90/jmxinst/understanding.html