JMX API 의 기본 요소 - xrath.com 에서 번역됨

목차 | 전의 항목 | 다음의 항목 | Java Management Extensions (JMX) 테크놀러지의 튜토리얼

## 제 2 장

## JMX API 의 기본 요소

이 예에서는, 관리 대상 Bean, 즉 MBean 등의, Java Management Extensions (JMX) API 의 기본적인 개념을 소개합니다.

MBean 는 JavaBeanTM 를 닮은 관리 대상 Java 객체이며, 그 설계 패턴은 JMX 스펙의 계측 레벨의 규정에 따릅니다. MBean 를 사용해, 디바이스, 어플리케이션, 또는 관리가 필요한 모든 자원을 나타낼 수가 있습니다. MBean 는 관리 인터페이스, 즉 read와 기입의 한편 또는 양쪽 모두가 가능한 속성 세트라고 호출해 가능한 조작 세트, 및 자기 기술을 개시하고 있습니다. 관리 인터페이스는, MBean 인스턴스의 생존 기간을 통해서 변화하지 않습니다. 또, MBean 는, 정의 끝난 특정의 이벤트가 일어났을 경우에 통지를 발행합니다.

JMX 스펙에서는, 표준 MBean, 동적 MBean,open MBean, 및 model MBean 라고 하는 4 종류의 MBean 를 정의하고 있습니다. 이 장의 예에서는, 가장 단순한 MBean 인 표준 MBean 에 대해 설명합니다.

## 2.1 표준 MBean

표준 MBean 는, Java 인터페이스 `SomethingMBean` 와 그 인터페이스를 구현하는 Java 클래스 `Something` 를 기술하는 것으로 정의됩니다. 인터페이스의 모든 메소드는, MBean 의 속성이나 조작의 어느쪽이든을 정의합니다. 디폴트에서는, 모든 메소드는 조작을 정의합니다. 속성과 조작은, 특정의 설계 패턴에 따른 간단한 메소드입니다. 표준 MBean 는, 개시된 모든 속성과 조작의 메소드를 일람으로 한 MBean 인터페이스와 이 인터페이스를 구현해, 계측 된 자원에 기능을 할당하는 클래스로부터 구성됩니다.

이후의 섹션에서는, 표준 MBean 의 예와 MBean 를 관리하는 간단한 JMX 에이전트를 상세하게 분석합니다. 샘플 코드는 디렉토리 work_dir`/jmx_examples/Essential/com/example/mbeans` 로부터 발췌하고 있습니다.

### 2.1. 1 MBean 인터페이스

`HelloMBean` 라고 하는 매우 기본적인 MBean 인터페이스의 예를,코드예 2-1 에 나타냅니다.

코드예 2-1 MBean 인터페이스, HelloMBean 의 예

    package com.example.mbeans;

    public interface HelloMBean {

        public void sayHello();
        public int add(int x, int y);

        public String getName();

        public int getCacheSize();
        public void setCacheSize(int size);
    }

지금까지 말한 것처럼, MBean 인터페이스는 규칙에 의해, 이 인터페이스를 구현하는 Java 클래스의 이름의 뒤에 MBean 를 더해 이름을 구성합니다. 이 때문에, 이 경우, 인터페이스는 `HelloMBean` 라는 이름이 됩니다. 이 인터페이스를 구현하는 `Hello` 클래스에 대해서는,「2.1. 2 MBean 의 구현」 으로 설명합니다.

JMX 스펙에 의하면, MBean 인터페이스는, 이름과 형태의 지정된 read 가능해, 경우에 따라서는 기입해 가능한 속성과 MBean 가 관리하는 어플리케이션에 의해 호출하는 것이 가능한, 이름과 형태의 지정된 조작으로부터 구성됩니다. 코드예 2-1 에 나타낸 `HelloMBean` 인터페이스에서는, 다음의 2 개의 조작을 선언하고 있습니다. Java 메소드 `add()` 와 `sayHello()` 입니다.

`HelloMbean` 로 선언되는 2 개의 속성 가운데,`Name` 는 읽어들여 전용의 캐릭터 라인으로,`CacheSize` 는 read와 기입의 양쪽 모두가 가능한 정수입니다. 취득 메소드와 설정 메소드는, 관리 대상 어플리케이션에 속성의 값에의 액세스와 경우에 따라서는 값의 변경을 허가하기 위해서 선언됩니다. JMX 스펙에 정의되도록(듯이), 취득 메소드는 get 로부터 이름이 시작되어, void 를 돌려주지 않는 모든 public 메소드입니다. 취득 메소드를 사용하면(자), 매니저는 반환된 객체의 형태와 일치하는 속성의 값을 읽어들일 수가 있습니다. 설정 메소드는 이름이 set 로부터 시작되어, 단일의 파라미터를 취하는 모든 public 메소드입니다. 설정 메소드를 사용하면(자), 매니저는 파라미터와 같은 형태의 값을 속성에 새롭게 기입할 수가 있습니다.

다음의 섹션에서는, 이러한 조작 및 속성의 구현을 설명합니다.

### 2.1. 2 MBean 의 구현

코드예 2-2 에 나타낸 `Hello` 클래스는,`HelloMBean` 를 구현하고 있습니다.

코드예 2-2 MBean 의 구현예, 클래스 Hello

    package com.example.mbeans;

    public class Hello implements HelloMBean {
        public void sayHello() {
    	System.out.println("hello, world");
        }

        public int add(int x, int y) {
    	return x + y;
        }

        public String getName() {
    	return this.name;
        }

        public int getCacheSize() {
    	return this.cacheSize;
        }

        public synchronized void setCacheSize(int size) {
    	this.cacheSize = size;

    	System.out.println("Cache size now " + this.cacheSize);
        }

        private final String name = "Reginald";
        private int cacheSize = DEFAULT_CACHE_SIZE;
        private static final int DEFAULT_CACHE_SIZE = 200;
    }

간단한 Java 클래스 `Hello` 는,`HelloMBean` 로 선언된 조작과 속성을 정의합니다. 이 예로부터 알도록(듯이),`sayHello()` 와 `add()` 의 조작은 극히 간단합니다만, 실제의 조작은 필요에 따라서 간단하게도, 복잡한 것에도 할 수 있습니다.

`Name` 속성을 취득하는 메소드와`cacheSize` 속성을 취득해 설정하는 메소드도 정의됩니다. 이 예에서는,`Name` 속성의 값은 바뀌지 않습니다만, 실제의 장면에서는, 관리 대상 자원의 실행에 의해 바뀌는 경우가 있습니다. 예를 들어, 속성은 가동 시간이나 메모리의 사용량등의 통계를 나타내는 경우가 있습니다. 여기에서는, 속성은 「Reginald」라고 하는 이름만입니다.

`setCacheSize` 메소드를 호출하면(자),`cacheSize` 속성의 값이 선언된 디폴트의 값 200 으로부터 변경할 수 있습니다. 실제로는,`cacheSize` 속성을 변경하는 경우는, 엔트리의 파기나 새로운 엔트리의 할당 등, 다른 조작을 실행하지 않으면 안됩니다. 이 예에서는, 캐쉬 사이즈가 변경된 것을 확인하는 메세지만이 인쇄됩니다만,`println()` 를 호출할 뿐(만큼)의 조작 대신에, 보다 복잡한 조작을 정의할 수가 있습니다.

간단한 `Hello` MBean 와 그 인터페이스를 정의하면(자), 다음의 섹션에 나타내도록(듯이), Hello MBean 와 인터페이스로 나타내지는 자원을 Hello MBean 와 인터페이스를 사용해 관리할 수가 있습니다.

### 2.1. 3 자원의 관리

「Java Management Extensions (JMX) 테크놀러지 개요」로 가리킨 것처럼, MBean 에 의해 자원이 계측 되면(자), 그 자원의 관리는 JMX 에이전트에 의해 행해집니다.

JMX 에이전트의 코어 컴퍼넌트는, MBean 를 등록하는 관리 대상 객체 서버인 MBean 서버입니다 (MBean 서버의 구현의 자세한 것은,`MBeanServer` 인터페이스의 API 문서를 참조). JMX 에이전트에는, MBean 를 관리하기 위한 일련의 서비스도 포함됩니다.

코드예 2-3 에서는,`Main` 라고 하는 기본적인 JMX 에이전트를 나타내고 있습니다.

코드예 2-3 JMX 에이전트의 작성

    package com.example.mbeans;

    import java.lang.management. *;
    import javax.management. *;

    public class Main {

       public static void main(String[] args) throws Exception {

          MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

          ObjectName name = new ObjectName("com.example.mbeans:type=Hello");

          Hello mbean = new Hello();

          mbs.registerMBean(mbean, name);

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

JMX 에이전트 `Main` 는, 우선 `java.lang.management.ManagementFactory` 클래스의 `getPlatformMBeanServer()` 메소드를 호출해, 플랫폼상에서 가동하는 임의의 MBean 서버를 가져옵니다. 플랫폼상에서 가동중의 MBean 가 존재하지 않는 경우,`getPlatformMBeanServer()` 에 의해 JMX 메소드 `MBeanServerFactory.createMBeanServer()` 가 불려 가 자동적으로 가동중의 MBean 가 작성됩니다. `Main` 로 취득되는 `MBeanServer` 인스턴스는,`mbs` 의 이름을 붙일 수 있습니다.

다음에 `Main` 는 작성하는 MBean 인스턴스를 위해서(때문에), 객체명을 정의합니다. 모든 JMX Mbean 에 객체명이 정의될 필요가 있습니다. 객체명은 JMX 클래스 `ObjectName` 의 인스턴스이며, 도메인과 키프로파티의 리스트를 반드시 포함하는 등, JMX 스펙으로 정의되는 구문에 따를 필요가 있습니다 (이 구문의 자세한 것은,`ObjectName` 클래스의 API 문서를 참조). `Main` 로 정의되는 객체명,`name` 에서는, 도메인은 `com.example.mbeans` (MBean 의 예가 포함된 패키지)입니다. 또, 키프로파티는 이 객체가 `Hello` 형인 것을 선언합니다.

`Hello` 객체의 인스턴스,`mbean` 가 작성됩니다. 이 `Hello` 객체는, 이것 자체가 「2.1. 2 MBean 의 구현」 으로 정의된 MBean `Hello` 의 인스턴스입니다.

다음에 `Hello` 객체 `mbean` 는, 객체명 `name` 를 사용해 MBean server `mbs` 에 MBean 로서 등록됩니다. 이 때문에, 객체와 객체명을 건네주어 JMX 메소드 `MBeanServer.registerMBean()` 를 호출합니다.

`Hello` MBean 를 MBean 서버에 등록한 후,`Main` 는 관리 조작이 `Hello` 로 실행되는 것을 대기합니다. 이 예의 범위에서는, 이러한 관리 조작은 `sayHello()` 와 `add()` 를 호출해, 속성치를 취득 및 설정해 있습니다.

### 2.1. 4 표준 MBean 의 예제의 실행

클래스의 예제를 검증한 후, 이번은 예제를 실행합니다. Java Platform, Standard Edition 에는 JConsole 라고 하는 관리·감시 콘솔이 부속되어 있어 이 예에서는 MBean 와의 대화에 사용되고 있습니다. JConsole 는 JavaSE_HOME`/bin/jconsole` 에 있습니다. JavaSE_HOME 는 Java Platform, Standard Edition (Java SE 플랫폼)가 인스톨 된 디렉토리입니다.

예제를 실행하려면 , 다음의 순서에 따르는지,`README` 파일을 참조합니다.

1. work_dir`/jmx_examples/Essential` 를 아직 열려 있지 않은 경우는 엽니다.

`$` cd work_dir/jmx_examples/Essential

2. Java 클래스의 예를 컴파일 합니다.

`$` javac com/example/mbeans/*.java

3. `Main` 어플리케이션을 기동합니다.

`$` java com.example.mbeans.Main

이벤트의 발생을 대기중의 `Main` 에 관한 확인이 표시됩니다.

4. 같은 머신의 다른 단말 윈도우로, JConsole 를 기동합니다.

`$` jconsole

JConsole 툴이 열려, 접속 가능한 가동중의 JMX 에이전트의 리스트가 표시됩니다.

5. 「New Connection」윈도우의 리스트로부터 `com.example.mbeans.Main` 를 선택해, 「Connect」를 클릭합니다.

플랫폼의 현재의 액티버티의 개요가 표시됩니다.

6. 「MBean」탭을 클릭합니다.

이 패널에, 현재 MBean 서버에 등록되어 모든 MBean 가 표시됩니다.

7. 왼쪽 프레임의 MBean 트리에 있는 `com.example.mbeans` 노드를 전개합니다.

`Main` 로 작성되어 등록된 MBean `Hello` 의 예가 표시됩니다. 「`Hello`」를 클릭하면(자), 관련하는 Attributes 및 Operations 노드가 MBean 트리에 표시됩니다.

8. MBean 트리에 있는 `Hello` MBean 노드를 클릭합니다.

`Hello` MBean 의 메타데이타와 거기에 관련하는 기술자가 표시됩니다.

9. MBean 트리에 있는 `Hello` MBean 의 `Attributes` 노드를 클릭합니다.

`Hello` 클래스에서 정의된 MBean 속성이 표시됩니다.

10. `CacheSize` 속성의 값을 150 으로 변경합니다.

`Main` 를 기동한 단말 윈도우에, 이 속성의 변경을 확인하는 prompt가 표시됩니다.

11. MBean 트리에 있는 Hello MBean 의 `Operations` 노드를 클릭합니다.

여기서,`Hello` MBean 로 선언된 2 개의 조작,`sayHello()` 와 `add()` 가 표시됩니다.

12. `［sayHello］` 버튼을 클릭해,`sayHello()` 조작을 기동합니다.

메소드가 정상적으로 불려 갔던 것이 JConsole 의 다이알로그 박스에 통지되어`Main` 가 기동하고 있는 단말의 윈도우에 「hello, world」라고 하는 메세지가 표시됩니다.

13. `add()` 조작으로 가산하는 2 개의 정수를 지정해,`[add]` 버튼을 클릭합니다.

[JConsole] 다이알로그 박스에 해답이 통지됩니다.

14. 「Connection」를 클릭해, 다음에 「Exit」를 클릭해, JConsole 를 종료합니다.

## 2.2 통지의 송신

MBean 는 상태의 변화, 검출된 이벤트, 또는 문제등을 알리는 통지를 생성합니다.

MBean 가 통지를 생성하기 위해서는, 인터페이스 `NotificationBroadcaster` 인가, 또는 그 서브 인터페이스 `NotificationEmitter` 를 구현하고 있을 필요가 있습니다. 통지의 송신에 필요한 조작은, 클래스 `javax.management.Notification` 또는 서브 클래스 (`AttributeChangedNotification` 등)의 인스턴스를 구축해, 그것을 `NotificationBroadcasterSupport.sendNotification` 에 건네줄 뿐입니다.

모든 통지에 발행원이 있습니다. 발행원은 통지를 발행한 MBean 의 객체명입니다.

모든 통지에는 순서 번호가 할당해지고 있습니다. 순서가 중요한 의미를 가지는 경우, 및 통지가 잘못한 순서로 처리되는 위험성이 있는 경우, 이 번호를 사용해 같은 소스로부터 도착한 통지를 늘어놓을 수가 있습니다. 순서 번호를 제로로 해도 괜찮습니다가, 특정의 MBean 로부터 통지가 도착할 때마다 인크리먼트(increment) 하는 (분)편이 적절합니다.

표준 MBean 가 디렉토리 work_dir`/jmx_examples/Notification/com/example/mbeans` 로 통지를 발행하는 예를 생각해 보겠습니다. 이 예는,「2.1 표준 MBean」 로 가리킨 예제와 기본적으로는 같습니다만,`Hello` MBean 가 `NotificationBroadcaster` 인터페이스를 구현하고 있는 점으로써 차이가 납니다.

### 2.2. 1 NotificationBroadcaster 인터페이스

전술과 같이, 이 예제와 「2.1 표준 MBean」 로 가리킨 예제의 유일한 차이는, MBean 의 구현에 의해 통지의 송신을 할 수 있다고 하는 점입니다.

코드예 2-4 에 나타낸 것처럼, 통지는 `NotificationBroadcaster` 인터페이스를 구현하는 것으로 기동합니다.

코드예 2-4 MBean 의 통지의 구현

    package com.example.mbeans;

    import javax.management. *;

    public class Hello
            extends NotificationBroadcasterSupport implements HelloMBean {

        public void sayHello() {
            System.out.println("hello, world");
        }

        public int add(int x, int y) {
            return x + y;
        }

        public String getName() {
            return this.name;
        }

        public int getCacheSize() {
            return this.cacheSize;
        }

        public synchronized void setCacheSize(int size) {
            int oldSize = this.cacheSize;
            this.cacheSize = size;

            System.out.println("Cache size now " + this.cacheSize);

            Notification n =
                new AttributeChangeNotification(this,
    					    sequenceNumber++,
    					    System.currentTimeMillis(),
    					    "CacheSize changed",
    					    "CacheSize",
    					    "int",
    					    oldSize,
    					    this.cacheSize);

    	sendNotification(n);
        }

        @Override
        public MBeanNotificationInfo[] getNotificationInfo() {
            String[] types = new String[] {
                AttributeChangeNotification.ATTRIBUTE_CHANGE
            };
            String name = AttributeChangeNotification.class.getName();
            String description = "An attribute of this MBean has changed";
            MBeanNotificationInfo info =
                new MBeanNotificationInfo(types, name, description);
            return new MBeanNotificationInfo[] {info};
        }

        private final String name = "Reginald";
        private int cacheSize = DEFAULT_CACHE_SIZE;
        private static final int DEFAULT_CACHE_SIZE = 200;

        private long sequenceNumber = 1;
    }

코드예 2-4 에 나타냈던 대로, 이 `Hello` MBean 의 구현에 의해 `NotificationBroadcasterSupport` 클래스가 확장되어 이 클래스 자체에 `NotificationEmitter` 인터페이스가 구현됩니다.

조작과 속성의 설정 방법법은 이전과 같습니다만, 유일 바뀐 것은 `cacheSize` 속성의 설정 메소드가 `oldSize` 라고 하는 새로운 값을 정의하는 점입니다. 이 값은 설정 조작전에 `cacheSize` 속성의 값을 기록합니다.

통지는,`javax.management.Notification` 를 확장하는 JMX 클래스 `AttributeChangeNotification` 의 인스턴스 `n` 로부터 구축됩니다. 이 통지는 `AttributeChangeNotification` 에 파라미터로서 건네받는 다음의 정보에 근거해,`setCacheSize()` 메소드의 정의내에서 구축됩니다.

- `Hello` MBean 등의 통지의 발행원의 객체명. 간단하게 `this` 와 나타내진다
- 순서 번호. 이 예에서는, 롱명 `setCacheSize()` 가 사용되어 1 으로 설정된 후, 1 개(살)씩 인크리먼트(increment) 한다
- 타임 스탬프
- 통지 메세지의 내용
- 변경된 속성의 이름. 이 경우는 `cacheSize`
- 변경된 속성의 형태
- 낡은 속성치. 이 경우는 `oldSize`
- 새로운 속성치. 이 경우는 `this.cacheSize`

이 후, 통지 n 가 `NotificationBroadcasterSupport.sendNotification()` 메소드에게 건네집니다.

마지막으로,`MBeanNotification` 가 정의되어 특정의 Java 클래스의 통지, 이 경우는 `AttributeChangeNotification` 에 대해서 MBean 가 발행한 다른 통지 인스턴스의 특성이 설명됩니다.

MBean 인터페이스 `HelloMBean` 와 JMX 에이전트 `Main` 는, 전출의 예로 사용된 것 것과 같습니다.

### 2.2. 2 MBean 의 통지의 예제의 실행

클래스의 예제를 검증한 후, 이번은 예제를 실행합니다. 이 예에서는,`Hello` MBean 와의 대화에 재차 JConsle 를 사용합니다. 예를 실행하는 경우는, 다음의 순서에 따르는지,`README` 파일을 참조해 주세요.

1. work_dir`/jmx_examples/Notification` 를 아직 열려 있지 않은 경우는, 엽니다.

`$` cd work_dir/jmx_examples/Notification

2. Java 클래스의 예를 컴파일 합니다.

`$` javac com/example/mbeans/*.java

3. `Main` 어플리케이션을 기동합니다.

`$` java com.example.mbeans.Main

이벤트의 발생을 대기중의 `Main` 에 관한 확인이 표시됩니다.

4. 같은 머신의 다른 단말 윈도우로, JConsole 를 기동합니다.

`$` jconsole

JConsole 툴이 열려, 접속 가능한 가동중의 JMX 에이전트의 리스트가 표시됩니다.

5. 「New Connection」윈도우의 리스트로부터 `com.example.mbeans.Main` 를 선택해, 「Connect」를 클릭합니다.

플랫폼의 현재의 액티버티의 개요가 표시됩니다.

6. 「MBean」탭을 클릭합니다.

이 패널에, 현재 MBean 서버에 등록되어 모든 MBean 가 표시됩니다.

7. 왼쪽 프레임의 MBean 트리에 있는 `com.example.mbeans` 노드를 전개합니다.

`Main` 로 작성되어 등록된 MBean `Hello` 의 예가 표시됩니다. 「`Hello`」를 클릭하면(자), 관련하는`Attributes`,`Operations`,`Notifications` 의 각 노드가 MBean 트리에 표시됩니다.

8. MBean 트리에 있는 `Hello` MBean 노드를 클릭합니다.

이것에 의해, MBean 의 메타데이타와 관련하는 기술자가 표시됩니다.

9. MBean 트리에 있는 Hello MBean 의 `Notifications` 노드를 클릭합니다.

빈 상태(empty)의 패널이 표시됩니다.

10. 「Subscribe」버튼을 클릭합니다.

현재의 수령 통지수 (0)가, Notifications 노드 라벨에 표시됩니다.

11. MBean 트리에 있는 `Hello` MBean 의 `Attributes` 노드를 클릭해,`CacheSize` 속성을 150 으로 변경합니다.

`Main` 를 기동한 단말 윈도우에, 이 속성의 변경을 확인하는 prompt가 표시됩니다. 또, Notifications 노드에 표시되는 수령 통지수가 1 으로 변경되고 있습니다.

12. MBean 트리에 있는 `Hello` MBean 의 `Notifications` 노드를 이제(벌써) 1 번 클릭합니다.

송신된 통지의 상세가 표시됩니다.

13. 「Connection」를 클릭해, 다음에 「Exit」를 클릭해, JConsole 를 종료합니다.

## 2.3 MXBean 의 도입

MXBean 는 새로운 타입의 MBean 입니다. 정의 끝난 형태 세트만을 참조하는 MBean 의 코딩을 간단하게 할 수 있습니다. 이 방법이라면, 원격 클라이언트를 포함한 클라이언트는, MBean 의 형태를 나타내는 모델 고유의 클래스에 액세스 하지 않아도, MBean 를 이용할 수 있습니다. MXBean 는, 클라이언트에 특히 번들 조작의 구성을 요구하는 일 없이, 관련하는 값을 번들 하는 편리한 수법을 제공합니다.

표준 MBean 의 경우와 같이, MXBean 를 정의하려면 ,Something `MXBean` 라고 하는 Java 인터페이스와 그 인터페이스를 구현하는 Java 클래스를 기술합니다. 다만, 표준 MBean 과는 달리, MXBean 에서는 그 Java 클래스를 `Something` 라고 부를 필요는 없습니다. 이 인터페이스내의 각 메소드는, MXBean 의 속성과 조작의 어느쪽이든을 정의합니다. 그 외 ,`@MXBean` 주석을 사용하는 경우는, 인터페이스명에 MXBean 확장자(extension)를 붙이는 대신에, Java 인터페이스에 주석을 붙일 수도 있습니다.

MXBean 는, 클라이언트에 특히 번들 조작의 구성을 요구하는 일 없이, MBean 라고 대화하면서 관련하는 값을 MBean 에 번들 하는 편리한 수법을 제공합니다. MXBean 는 Java 2 Platform, Standard Edition (J2SE) 5.0 의 `java.lang.management` 패키지에 들어가 있습니다. Java SE 6 플랫폼에서는,`java.lang.management` 로 정의된 표준 세트 뿐만이 아니라, 사용자 자신의 MXBean 를 정의할 수 있습니다.

MXBean 의 주된 의도는, MXBean 인터페이스로 참조되는 `java.lang.management.MemoryUsage` 등의 형태 (이 경우는 `java.lang.management.MemoryMXBean`)를 표준형 세트에 맵 하는 것에 있습니다. 그 표준형 세트는 Open Type 로 불려`javax.management.openmbean` 패키지로 정의됩니다. 정확한 매핑의 규칙은 「MXBean 의 스펙」에 기재되어 있습니다만, 대략적으로 말하면,`int` 나 `String` 와 같이 단순한 형태로 변경은 없고,`MemoryUsage` 와 같이 복잡한 형태는 `CompositeDataSupport` 표준형에 맵 됩니다.

`jmx_examples.zip` 파일을 다운로드해 해동하면(자), MXBean 의 조작을 설명한 샘플 프로그램이 work_dir`/jmx_examples/MXBean/com/example/mxbeans` 디렉토리에 작성됩니다. MXBean 의 샘플에는, 다음의 파일이 포함되어 있습니다.

- `QueueSamplerMXBean` 인터페이스.
- `QueueSampler` 클래스. MXBean 인터페이스를 구현한다.
- `QueueSample` Java 의 형태. MXBean 인터페이스의 `getQueueSample()` 메소드에 의해 반환된다.
- `Main`. 샘플을 설정해 실행하는 프로그램

MXBean 의 샘플에는, 다음의 액션이 포함되어 있습니다.

- `type Queue<String>` 의 자원을 관리하는, 단순한 MXBean 를 정의한다.
- 불려 간다고 큐의 snapshot를 작성하는 MXBean 의 취득 메소드 `getQueueSample` 를 선언해, 다음의 값을 번들 하는 Java 클래스 `QueueSample` 를 돌려준다.

- snapshot가 작성되었을 때 각.
- 큐의 사이즈.
- 지정되었을 때 각의 큐의 선두.

- MBean 서버에 MXBean 를 등록한다.

### 2.3. 1 QueueSamplerMXBean 인터페이스

코드예 2-5 는,`QueueSamplerMXBean` 인터페이스의 샘플 코드를 나타내고 있습니다.

코드예 2-5 QueueSamplerMXBean 인터페이스

    package com.example.mxbeans;

    public interface QueueSamplerMXBean {
        public QueueSample getQueueSample();
        public void clearQueue();
    }

이 예로부터 알도록(듯이), MXBean 인터페이스의 선언은 표준 MBean 의 선언과 완전히 같습니다. `QueueSamplerMXBean` 인터페이스에서는,`getQueueSample` 와 `clearQueue` 라고 하는 2 개의 조작을 선언하고 있습니다.

### 2.3. 2 QueueSampler 클래스

`QueueSampler` 클래스는, 코드예 2-6 에 나타내도록(듯이),`QueueSamplerMXBean` 인터페이스를 구현하고 있습니다.

코드예 2-6 QueueSampler 클래스

    package com.example.mxbeans;

    import java.util.Date;
    import java.util.Queue;

    public class QueueSampler implements QueueSamplerMXBean {

        private Queue<String> queue;

        public QueueSampler(Queue<String> queue) {
           this.queue = queue;
        }

        public QueueSample getQueueSample() {
            synchronized (queue) {
                return new QueueSample(new Date(), queue.size(), queue.peek());
            }
        }

        public void clearQueue() {
            synchronized (queue) {
                queue.clear();
            }
        }
    }

MXBean 인터페이스로 선언된 MXBean 조작의 getQueueSample() 및 clearQueue()는,`QueueSampler` 로 정의됩니다. getQueueSample() 조작은 단순하게,`QueueSample` Java 형 (java.util. `Queue` 메소드의 `peek()` 및 `size()` 에 의해 반환된 값을 사용해 작성)의 인스턴스와 java.util.Date 의 인스턴스를 돌려줍니다.

### 2.3. 3 QueueSampler 클래스

`QueueSampler` 에 의해 반환된 `QueueSample` 인스턴스는,코드예 2-7 에 나타낸 `QueueSample` 클래스에서 정의됩니다.

코드예 2-7 QueueSampler 클래스

    package com.example.mxbeans;

    import java.beans.ConstructorProperties;
    import java.util.Date;

    public class QueueSample {

        private final Date date;
        private final int size;
        private final String head;

        @ConstructorProperties({"date", "size", "head"})
        public QueueSample(Date date, int size, String head) {
            this.date = date;
            this.size = size;
            this.head = head;
        }

        public Date getDate() {
            return date;
        }

        public int getSize() {
            return size;
        }

        public String getHead() {
            return head;
        }
    }

`QueueSample` 클래스에서는, MXBean 시스템가 `QueueSample` 의 취득 메소드를 모두 호출해, 지정된 인스턴스를 `CompositeData` 로 변환해,`@ConstructorProperties` 주석을 사용해, `CompositeData` 로부터 `QueueSample` 인스턴스를 재구축 합니다.

### 2.3. 4 MXBean 의 작성과 MBean 서버에의 등록

MXBean 인터페이스와 이것을 구현하는 클래스, 및 반환되는 Java 형을 정의하면(자), 다음은 MXBean 를 작성해 MBean 서버에 등록할 필요가 있습니다. 이러한 액션은, 샘플 클래스 `Main` 에 의해 행해집니다.

코드예 2-8 MXBean 의 Main 클래스의 예

    package com.example.mxbeans;

    import java.lang.management.ManagementFactory;
    import java.util.Queue;
    import java.util.concurrent.ArrayBlockingQueue;
    import javax.management.MBeanServer;
    import javax.management.ObjectName;

    public class Main {

        public static void main(String[] args) throws Exception {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

            ObjectName name =
                    new ObjectName("com.example.mxbeans:type=QueueSampler");

            Queue<String> queue = new ArrayBlockingQueue<String>(10);
            queue.add("Request-1");
            queue.add("Request-2");
            queue.add("Request-3");
            QueueSampler mxbean = new QueueSampler(queue);

            mbs.registerMBean(mxbean, name);

            System.out.println("Waiting...");
            Thread.sleep(Long.MAX_VALUE);
        }
    }

`Main` 클래스는, 플랫폼 MBean 서버를 취득해, MXBean `QueueSampler` 의 객체명을 작성해,`QueueSampler` MXBean 의 `Queue` 인스턴스를 작성해 처리합니다. 다음에, 이 Queue 인스턴스를, 신규 작성된 `QueueSampler` MXBean 에 보냅니다. 이것으로 표준 MBean 와 완전히 똑같이, MXBean 가 MBean 서버에 등록됩니다.

### 2.3. 5 MXBean 의 예제의 실행

예제를 실행하려면 , 다음의 순서에 따르는지,`README` 파일을 참조합니다.

1. work_dir`/jmx_examples/MXBean` 를 아직 열려 있지 않은 경우는 엽니다.

`$` cd work_dir/jmx_examples/MXBean

2. Java 클래스의 예를 컴파일 합니다.

`$` javac com/example/mxbeans/*.java

3. `Main` 어플리케이션을 기동합니다.

`$` java com.example.mxbeans.Main

이벤트의 발생을 대기중의 `Main` 에 관한 확인이 표시됩니다.

4. 같은 머신의 다른 단말 윈도우로, JConsole 를 기동합니다.

`$` jconsole

JConsole 툴이 열려, 접속 가능한 가동중의 JMX 에이전트의 리스트가 표시됩니다.

5. 「New Connection」윈도우의 리스트로부터 `com.example.mxbeans.Main` 를 선택해, 「Connect」를 클릭합니다.

플랫폼의 현재의 액티버티의 개요가 표시됩니다.

6. 「MBean」탭을 클릭합니다.

이 패널에, 현재 MBean 서버에 등록되어 모든 MBean 가 표시됩니다.

7. 왼쪽 프레임에 있는 MBean 트리의 `com.example.mxbeans` 노드를 전개합니다.

Main 로 작성되어 등록된 MBean `QueueSampler` 의 예가 표시됩니다. `QueueSampler` 를 클릭하면(자), 관련하는 Attributes 및 Operations 노드가 MBean 트리에 표시됩니다.

8. `Attributes` 노드를 선택합니다.

오른쪽 페인에 `QueueSample` 속성과 그 `javax.management.openmbean.CompositeDataSupport` 의 값이 표시됩니다.

9. `CompositeDataSupport` 치를 더블 클릭 합니다.

MXBean 시스템가 `QueueSample` 인스턴스를 `CompositeData` 로 변환했기 때문에,`QueueSample` 의 값인 `date`,`head`, 및 `size` 가 표시됩니다. `QueueSampler` 를 MXBean 는 아니고 표준 MBean 로서 정의했을 경우,`QueueSample` 클래스는 그 클래스 패스에는 존재하지 않기 때문에 JConsole 로부터는 발견되지 않습니다. `QueueSampler` 가 표준 MBean 의 경우,`QueueSample` 속성치를 추출하면(자) `ClassNotFoundException` 가 돌려주어집니다. 이와 같이, JConsole 와 같이 범용적인 JMX 클라이언트로 JMX 에이전트에 접속할 경우에 MXBean 를 사용하면(자) 편리합니다.

10. `Operations` 노드를 선택합니다.

`clearQueue` 조작을 호출하는 버튼이 표시됩니다.

11. 「`clearQueue`」버튼을 클릭합니다.

메소드의 호출에 성공했던 것이 통지됩니다.

12. `Attributes` 노드를 이제(벌써) 1 번 선택해,`CompositeDataSupport` 치를 더블 클릭 합니다.

이것으로 큐가 리셋 됩니다.

13. 「Connection」를 클릭해, 다음에 「Exit」를 클릭해, JConsole 를 종료합니다.

이 예에서는, JConsole 가 JMX 클라이언트로서 사용되었습니다만, JMX 클라이언트의 자작 프로그램으로부터 MXBean 에 액세스 하는 경우는 다음의 2 개의 방법의 어느 쪽인지로 실시합니다.

- 일반적으로는 다음의 코드를 사용한다.
코드예 2-9 MXBean 에 직접 액세스 한다

    MBeanServer mbs = ...whatever...;
    ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler");
    CompositeData queueSample = (CompositeData) mbs.getAttribute(name,
                                 "QueueSample");
    int size = (Integer) queueSample.get("size");

- 프록시 경유. 다음의 코드를 사용한다.

> 코드예 2-10 프록시 경유로 MXBean 에 액세스 한다

>     MBeanServer mbs = ...whatever...;
>     ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler");
>     QueueSamplerMXBean proxy = JMX.newMXBeanProxy(mbs, name,
>                                                   QueueSamplerMXBean.class);
>     QueueSample queueSample = proxy.getQueueSample();
>     int size = queueSample.getSize();

> 코드예 2-10 에서는, newMXBeanProxy 메소드를 사용해 MXBean 프록시를 작성합니다. `newMBeanProxy` 라고 하는 등가의 메소드가 있는 것은, 다른 형태의 MBean 로 사용하는 프록시를 작성하기 (위해)때문에입니다. `newMBeanProxy` 및 `newMXBeanProxy` 메소드의 사용법은 완전히 같습니다.

## 2.4 MBean 기술자

기술자에 의해, MBean 에 관한 추가 정보를 관리 클라이언트에 제공할 수 있습니다. 예를 들어, MBean 속성에 관한 기술자로 계측 단위나 최대치로 최소치를 나타내는 경우도 있습니다. Java SE 6 의 시점에서, 기술자는 JMX API 에 포함되어 있어 어느 MBean 에서도 사용 가능합니다.

기술자는, 임의의 메타데이타를 MBean 에 추가하는 경우에 편리합니다. 기술자는 JMX API 에 반드시 있습니다만, Java SE 6 까지는 Model MBean 와 따로 사용할 수 없습니다.

`MBean*Info` 클래스 (`MBeanInfo`,`MBeanAttributeInfo` 등)의 대부분의 생성자 의 경우, 각각 공통되는 파라미터와 추가 파라미터 `javax.management.Descriptor` 를 가지는 병렬 생성자 이 존재합니다. `OpenMBean*InfoSupport` 의 경우도 같습니다. `MBean*Info` 및 `OpenMBean*InfoSupport` 클래스에는,`getDescriptor()` 메소드가 포함되어 있습니다.

Open MBean 는,`OpenMBeanParameterInfo` 및 `OpenMBeanAttributeInfo` 의 메소드 `getDefaultValue()`,`getLegalValues()`,`getMaxValue()`,`getMinValue()` 로부터, 디폴트에 관한 정보와 유효한 값을 돌려줍니다. 이 정보는, 대응하는 기술자에게도 존재합니다. 또, 다른 MBean 에서도, 각각의 기술자에게 있는 정보를 돌려줄 수가 있습니다.

`jmx_examples.zip` 파일을 다운로드해 해동하면(자), MBean 기술자를 설명한 샘플 프로그램이 work_dir`/jmx_examples/Descriptors/com/example/mxbeans` 디렉토리에 작성됩니다. MBean 기술자의 샘플에는, 다음의 파일이 포함되어 있습니다.

- `Author`. MBean 인터페이스의 저자명을 나타내는 주석.
- `DisplayName`. MBean 인터페이스의 메소드의 표시명을 나타내는 주석.
- `Main`. 샘플을 설정해 실행하는 프로그램.
- `QueueSamplerMXBean` 인터페이스.
- `QueueSampler` 클래스. MXBean 인터페이스를 구현한다.
- `QueueSample` Java 의 형태. MXBean 인터페이스내의 `getQueueSample()` 메소드에 의해 반환된다.
- `Version`. MBean 인터페이스의 현재의 버젼을 나타내는 주석.

이 예에 나타내는 `QueueSampler` MXBean 는,제 2 장 「MXBean 의 도입」 에 나타낸 MXBean 의 예와 기본적으로 같은 액션을 실행하고 있습니다만, MBean 기술자가 추가되고 있는 점이 다릅니다. 이 예는,`DescriptorKey` 메타 주석을 사용하는 것으로, 표준 MBean (또는 MXBean) 인터페이스내의 주석에 의해 표준 MBean (또는 MXBean)의 기술자에게 새로운 기술자를 추가하는 방법을 나타내고 있습니다.

### 2.4. 1 DescriptorKey 주석

새로운 주석 `DescriptorKey` 를 사용하는 것으로, 표준 MBean (또는 MXBean) 인터페이스내의 주석에 의해 표준 MBean (또는 MXBean)의 기술자에게 정보를 추가할 수 있습니다. 이것에 의해, 툴로 기존의 관리 모델로부터 표준 MBean 를 생성해, 그 모델로부터의 정보를 다른 파일은 아니고 생성된 MBean 인터페이스에 포함할 수가 있습니다.

코드예 2-11 는,`Author` 주석의 정의를 나타내고 있습니다.

코드예 2-11 Author 주석

    package com.example.mxbeans;

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import javax.management.DescriptorKey;

    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Author {
        @DescriptorKey("author")
        String value();
    }

이 주석은, MBean 인터페이스의 작성자의 이름을 제공합니다. 새로운 필드 `author` 는,`@Author` 주석에 의해 정의된 값을 가지는 `MBeanInfo` 기술자에게 추가됩니다. 파일 `Version` 및 `DisplayName` 는, 이러한 이름의 주석을, 전술의 `Author` 의 경우와 완전히와 같이 정의합니다. `Version` 및 `DisplayName` 의 `@DescriptorKey` 치는, 각각`「version」`와`「displayname」`입니다.

Version 의 경우, 새로운 필드 `version` 는 `@Version` 주석에 의해 정의된 값을 가지는 `MBeanInfo` 기술자에게 추가됩니다.

`DisplayName` 의 경우, 새로운 필드 `displayName` 는, 주석을 붙일 수 있었던 메소드가 취득 메소드/설정 메소드와 조작의 어디에서 있을까에 응해, 각각 `@DisplayName` 주석에 의해 정의된 값을 가지는 `MBeanAttributeInfo` 기술자 또는 `MBeanOperationInfo` 기술자에게 추가됩니다.

### 2.4. 2 MBean 기술자의 사용

다음의 예로 사용되고 있는 `QueueSamplerMXBean` 인터페이스는, MBean 기술자를 구현해 그 정보의 일부를 공개하는 범위에 한정해, MXBean 의 예로 사용되고 있는 인터페이스와는 조금 다릅니다.

코드예 2-12 기술자를 사용한 QueueSamplerMXBean

    package com.example.mxbeans;

    @Author("Mr Bean")
    @Version("1. 0")
    public interface QueueSamplerMXBean {
        @DisplayName("GETTER: QueueSample")
        public QueueSample getQueueSample();
        @DisplayName("OPERATION: clearQueue")
        public void clearQueue();
    }

이것으로 `@Author` 주석은 `Mr. Bean`, `@Version` 주석은 `1.0`, `@DisplayName` 는 속성 `QueueSample` 와 조작 `clearQueue` 의 어느 쪽인가의 이름으로 설정됩니다.

### 2.4. 3 MBean 기술자의 예제의 실행

예제를 실행하려면 , 다음의 순서에 따르는지,`README` 파일을 참조합니다.

1. work_dir`/jmx_examples/Descriptors` 를 아직 열려 있지 않은 경우는 엽니다.

`$` cd work_dir/jmx_examples/Descriptors

2. Java 클래스의 예를 컴파일 합니다.

`$` javac com/example/mxbeans/*.java

3. `Main` 어플리케이션을 기동합니다.

`$` java com.example.mxbeans.Main

이벤트의 발생을 대기중의 `Main` 에 관한 확인이 표시됩니다.

4. 같은 머신의 다른 단말 윈도우로, JConsole 를 기동합니다.

`$` jconsole

JConsole 툴이 열려, 접속 가능한 가동중의 JMX 에이전트의 리스트가 표시됩니다.

5. 「New Connection」윈도우의 리스트로부터 `com.example.mxbeans.Main` 를 선택해, 「Connect」를 클릭합니다.

플랫폼의 현재의 액티버티의 개요가 표시됩니다.

6. 「MBean」탭을 클릭합니다.

이 패널에, 현재 MBean 서버에 등록되어 모든 MBean 가 표시됩니다.

7. 왼쪽 프레임에 있는 MBean 트리의 `com.example.mxbeans` 노드를 전개합니다.

Main 로 작성되어 등록된 MBean `QueueSampler` 의 예가 표시됩니다. `QueueSampler` 를 클릭하면(자), 관련하는 Attributes 및 Operations 노드가 MBean 트리에 표시됩니다. 또,`MBeanInfo` 기술자표에는 `author` 및 `version` 필드도 표시됩니다.

8. `QueueSampler` MBean 노드아래에 있는 `Attributes` 및 `Operations` 노드를 전개합니다.

Attributes 와 Operations 가 개별적으로 표시됩니다.

9. `QueueSample` 노드를 선택합니다.

`MBeanAttributeInfo` 기술자표에 `displayName` 필드가 표시됩니다.

10. `clearQueue` 노드를 선택합니다.

`MBeanOperationInfo` 기술자표에 `displayName` 필드가 표시됩니다.

11. 「Connection」를 클릭해, 다음에 「Exit」를 클릭해, JConsole 를 종료합니다.

목차 | 전의 항목 | 다음의 항목 | Java Management Extensions (JMX) 테크놀러지의 튜토리얼 Java Management Extensions (JMX), Java Platform, Standard Edition 6

Copyright © 2006 Sun Microsystems, Inc. All rights reserved.