JMX (Java Management Extensions)

JMXとはJava Management Extensionsの略で、アプリケーションやシステムオブジェクト、サービス指向ネットワークの管理と監視を行うツールを提供するJava技術です。この記事ではJMXの使い方をご紹介します。

目次

  1. JMXとは?
  2. MBean
    1. MBeanインターフェースの定義
    2. MBean実装クラスの作成
    3. MBeanの登録と管理
    4. 実行と確認
  3. JConsole
  4. API
    1. java.lang.management
      1. ManagementFactory
    2. javax.management
      1. MBeanServerConnection
      2. JMX
      3. ObjectName
    3. javax.management.openmbean
    4. javax.management.remote
      1. JMXConnector
      2. JMXConnectorFactory
      3. JMXServiceURL
  5. Jolokia

JMXとは

JMX (Java Management Extensions)はアプリケーション、システムオブジェクト、デバイス及びサービス指向ネットワークの管理と監視を行うツールを提供するJava技術である。

JMXでは監視及び管理対象のリソースをMBeanと呼ばれるオブジェクトで表現して、アプリケーション側からはJMX Agent (MBean Server)を介してアクセスする。JMX Agentへのリモートアクセスは、通信プロトコルごとに用意されたConnectorと呼ばれる通信モジュールを介して行う。

MBean

JMXでは管理対象とするデバイス、アプリケーション又はリソースの属性及び操作をまとめたBeanで管理する。この管理対象BeanをMBeanと呼ぶ。

MBeanインターフェースの定義

MBeanは、管理対象となるリソースのインターフェースを定義する。インターフェース名は、クラス名の末尾に MBean をつけるのが慣例となっている。

public interface HelloMBean {
    public void sayHello();
    public String getName();
    public void setName(String name);
}

MBean実装クラスの作成

MBeanインターフェースを実装するクラスを作成する。このクラスが、実際に管理されるリソースである。

public class Hello implements HelloMBean {
    private String name = "World";

    @Override
    public void sayHello() {
        System.out.println("Hello, " + name + "!");
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }
}

MBeanの登録と管理

MBeanServerにMBeanを登録し、JMXクライアントからアクセスできるようにする。このコードを実行すると、JMXコンソール(jconsole や JVisualVM など)から、Hello MBeanの属性や操作を確認・変更できる。

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;

public class Main {
    public static void main(String[] args) throws Exception {
        // MBeanServerのインスタンスを取得
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

        // MBeanの名前を定義 (ドメイン:キー=値)
        ObjectName name = new ObjectName("com.example:type=Hello");

        // MBeanのインスタンスを作成
        Hello mbean = new Hello();

        // MBeanServerにMBeanを登録
        mbs.registerMBean(mbean, name);

        System.out.println("MBeanが登録されました。JMXクライアントで確認してください。");
        System.out.println("プログラムを終了するにはCtrl+Cを押してください。");

        // プログラムを終了させないように待機
        Thread.sleep(Long.MAX_VALUE);
    }
}

実行と確認

  1. 上記の3つのJavaファイルを同じディレクトリに保存する。
  2. コンパイルする。
    $ javac Main.java
  3. 実行する。
    $ java Main
  4. 別のターミナルを開き、jconsole を実行する。
    jconsole
    Figure 1 jconsole
  5. jconsole の画面で、実行中の Main プロセスを選択し、「接続」をクリックする。
  6. 「MBeans」タブに移動し、左側のツリーから com.example.jmx -> type=Hello を見つけると、定義した属性 (Name) と操作 (sayHello) が表示される。
    jconsole
    Figure 2 MBeans

JConsole

JCconsole (Java Monitoring & Management Console)はJMX仕様に準拠した監視ツールである。jconsoleはJDK_HOME/binディレクトリに配置されている。

jconsole [-interval=n] [-notile] [-pluginpath path] [-version] [connection ...]

connectionには、次に示す形式で接続先を指定する。

pid|host:port|service:jmx:protocol://url

JConsoleには次に示すオプションを指定できる。

-interval=n
更新間隔をn秒に設定する。
-notile
最初にウィンドウを並べて表示しない。
-plaginpath path
JConsoleがプラグインを参照するために使用するパスを設定する。
-version
バージョン情報を表示する。

API

JMXには次のパッケージが用意されている。

javax.management
JMXの核となるクラスを提供するパッケージ
javax.management.openmbean
公開データ型とOpen MBean記述子クラスを提供するパッケージ
javax.management.remote
JMX Beanサーバにリモートアクセスするためのインタフェースを提供するパッケージ

java.lang.management

java.lang.managementには、以下に示すクラスがある。

クラス
クラス 説明
ManagementFactory Javaプラットフォームの管理対象Beanを取得するためのファクトリ・クラス

ManagementFactory

ManagementFactoryクラスは、Javaプラットフォームの管理対象Beanを取得するためのファクトリ・クラスである。

メソッド
メソッド 説明
getPlatformMBeanServer() プラットフォームMBeanServerを返す。
getPlatformMBeanServer()

プラットフォームMBeanServerを返す。

public static MBeanServer getPlatformMBeanServer()

javax.management

javax.managementは、JMXの核となるクラスを提供するパッケージである。

javax.managementパッケージには、以下に示すインタフェースがある。

インタフェース
インタフェース 説明
MBeanServerConnection MBeanサーバとの通信方法

javax.managementパッケージには、以下に示すクラスがある。

クラス
クラス説明
JMXJMX APIからのstaticメソッド
ObjectNameMBeanのオブジェクト名

javax.managementパッケージには、以下に示す例外がある。

javax.managementパッケージの例外
例外説明
MalformedObjectNameException文字列の形式が有効なObjectNameに対応していない

javax.management.MBeanServerConnection

javax.management.MBeanServerConnectionはMBeanサーバとの通信方法を表すインタフェースである。

javax.management.JMX

javax.management.JMXはJMX APIからのstaticメソッドを提供するクラスである。JMXクラスのインスタンスは存在しない。

JMXクラスのメソッド
MethodDescription
newMBeanProxyローカル又はリモートのMBeanサーバ内に標準MBeanプロキシを作成する。
javax.management.ObjectName

javax.management.ObjectNameはMBeanのオブジェクト名、又は複数のMBean名に一致するパターンを表すクラスである。

javax.management.openmbean

javax.management.openmbeanは公開データ型とOpen MBean記述子クラスを提供するパッケージである。

javax.management.openmbeanパッケージのインタフェース
InterfaceDescription
TabularDataテーブルデータ構造を表す公開データ

javax.management.remote

javax.management.remoteはJMX Beanサーバにリモートアクセスするためのインタフェースを提供するパッケージである。

インタフェース

javax.management.remoteパッケージのインタフェース
InterfaceDescription
JMXConnectorJMX APIのクライアント側
javax.management.remote.JMXConnector

javax.management.remote.JMXConnectorはJMX APIコネクタのクライアント側を表すインタフェースである。

JMXConnectorのメソッド
MethodDescription
closeクライアントとサーバの接続を終了する。
getMBeanServerConnectionリモートMBeanサーバを表すMBeanServerConnctionオブジェクトを返す。

クラス

javax.management.remoteパッケージのクラス
ClassDescription
JMXConnectorFactoryJMX APIコネクタクライアントを作成するファクトリ
JMXServiceURLJMX APIコネクタサーバのアドレス
javax.management.remote.JMXConnectorFactory

javax.management.remote.JMXConnectorFactoryはJMX APIコネクタクライアントを作成するファクトリである。JMXConnectorFactoryクラスのインスタンスは存在しない。通常、JMXへの接続はJMXConnectorFactoryクラスのconnectメソッドにより確立される。

javax.management.remote.JMXServiceURL

javax.management.remote.JMXServiceURLはJMX APIコネクタサーバのサービスURLを表すクラスである。

サービスURLは次に示す形式である。

service:jmx:protocol:sap

protocolはコネクタサーバに接続する際に使用する転送プロトコルである。

sapはコネクタサーバが検出されたアドレスで、次に示す形式である。

//[host[:port]][url]

Jolokia

JolokiaとはMBeanにHTTP経由でアクセスできるエージェントである。応答はJSONで返ってくる。

JMXクライアントプログラムの例を次に示す。

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JmxClient {
  public static void main(String[] args) {
    HashMap<String, String[]> environment = new HashMap<String, String[]>();
    String username = "karaf";
    String password = "karaf";
    String[] credentials = new String[] { username, password };
    environment.put("jmx.remote.credentials", credentials);

    try {
      JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-trun");
      JMXConnector jmxc = JMXConnectorFactory.connect(url, environment);
      MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
      String domains[] = mbsc.getDomains();

      for (int i = 0; i < domains.length; i++) {
        System.out.println("Domain[" + i + "] = " + domains[i]);
      }

      jmxc.close();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}