Spec-Zone .ru
спецификации, руководства, описания, API
|
Содержание | Предыдущий | Следующий | Расширения управления Java (JMX) Технологическое Учебное руководство |
Эта глава представляет понятие стандартных и динамических бобов управления (MBeans) и также показывает, как использовать Расширения управления Java (JMX) технология, чтобы выполнить операции на MBeans, и локально и удаленно.
Этот пример демонстрирует стандартный и динамический MBeans только.
Как замечено в Главе 2, "Основы API JMX", стандартный MBean является тем, который статически определяет его интерфейс управления через имена методов, которые это содержит. Динамический MBean реализует определенный интерфейс Java и показывает его атрибуты и операции во время выполнения.
Технология JMX определяет соединитель, основанный на RMI. Соединитель RMI поддерживает стандартные транспорты RMI, Java Удаленный Протокол Метода (JRMP) и интернет-Межпосредник запросов к объектам (ШАР) Протокол (IIOP). Этот соединитель позволяет Вам соединяться с MBean в сервере MBean от удаленного расположения, и выполнять операции на этом, точно как будто операции выполнялись локально.
Цель этого примера состоит в том, чтобы демонстрировать реализацию стандартного MBean и динамического MBean. Это также показывает, как выполнить операции на них, и локально, и удаленно через соединение RMI между сервером и удаленным клиентом.
Когда Вы выполняете этот пример:
SimpleStandard
и a SimpleDynamic
MBean в локальном сервере MBeanПример соединителя RMI содержится в каталоге work_dir/jmx_examples/Basic
.
Следующие разделы анализируют каждый из классов, используемых в основном примере MBean, и объясняют, как они выполняют операции, описанные в предыдущем разделе.
Из-за его размера, Server.java
класс показывают в нескольких выборках кода.
public class Server { public static void main(String[] args) { try { MBeanServer mbs = MBeanServerFactory.createMBeanServer(); waitForEnterPressed(); String domain = mbs.getDefaultDomain(); waitForEnterPressed(); String mbeanClassName = "SimpleStandard"; String mbeanObjectNameStr = domain + ":type=" + mbeanClassName + ",name=1"; ObjectName mbeanObjectName = createSimpleMBean(mbs, mbeanClassName, mbeanObjectNameStr); waitForEnterPressed(); printMBeanInfo(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); manageSimpleMBean(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); mbeanClassName = "SimpleDynamic"; mbeanObjectNameStr = domain + ":type=" + mbeanClassName + ",name=1"; mbeanObjectName = createSimpleMBean(mbs, mbeanClassName, mbeanObjectNameStr); waitForEnterPressed(); printMBeanInfo(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); manageSimpleMBean(mbs, mbeanObjectName, mbeanClassName); waitForEnterPressed(); [...]
Исследуя этот класс, можно видеть, что следующее происходит:
Во-первых, Server.java
класс создает новый вызванный сервер MBean mbs
вызывая createMBeanServer()
метод MBeanServerFactory
класс.
Затем, домен по умолчанию, в котором регистрируется сервер MBean, получается со звонком getDefaultDomain()
метод MBeanServer
интерфейс. Домен идентифицируется строкой domain
.
Класс MBean называют SimpleStandard
также идентифицируется переменной, в этом случае строка mbeanClassName
. SimpleStandard
имя класса Java для объекта Java, которого этот MBean является экземпляром. SimpleStandard.java
объект исследуется в Разделе "SimpleStandard.java".
Другая переменная, строка mbeanObjectNameStr
, определяется как комбинация домена, плюс следующие key=value пары:
type
, который в этом случае является mbeanClassName
.name
, дифференцировать этот MBean от другого MBeans того же самого типа, который мог бы быть создан впоследствии. В этом случае число имени 1
.Цель mbeanObjectNameStr
должен дать MBean удобочитаемый идентификатор.
Звонок createSimpleMBean () создает и регистрирует SimpleStandard MBean в локальном сервере MBean с данным именем объекта.
Операции printMBeanInfo()
, и manageSimpleMBean()
тогда выполняются на SimpleStandard
MBean. Как createSimpleMBean()
, эти методы определяются позже в Server.java
код, и показывают в ПРИМЕРЕ КОДА 3-4 и ПРИМЕРЕ КОДА 3-5.
В коде, который не показывают здесь, второй MBean типа SimpleDynamic
создается и регистрируется в сервере MBean точно таким же образом как SimpleStandard
MBean. Как имя предполагает, этот MBean является экземпляром SimpleDynamic
Объект Java, который исследуется в Разделе "SimpleDynamic.java".
[...] JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); cs.start(); waitForEnterPressed(); cs.stop(); [...]
В ПРИМЕРЕ КОДА 3-2, создается сервер соединителя RMI так, чтобы операции могли быть выполнены на MBeans удаленно. Звонок в класс JMXServiceURL
создает новую службу вызванный URL url
, который служит адресом для сервера соединителя. В этом примере служба URL дается в форме JNDI, а не в закодированной форме (см. документацию API для javax.management.remote.rmi
пакет для объяснения формы JNDI). Эта служба URL определяет следующее:
rmi
.9999
на локальном узле, и адресе сервера будет зарегистрирован под именем server
. Порт 9999
определенный в примере произвольно; можно использовать любой доступный порт.Сервер соединителя RMI называют cs
создается, вызывая конструктора JMXConnectorServerFactory
, со службой URL url
, a null
карта среды, и сервер MBean mbs
как параметры. Сервер соединителя cs
запускается, вызывая start()
метод JMXConnectorServer
, после чего RMIConnectorServer
экспортирует объект RMI server
к реестру RMI. Соединение останется открытым, пока клавиша Enter не будет нажата, как проинструктировано простым методом waitForEnterPressed
, это определяется позже в Server
код.
[...] private static ObjectName createSimpleMBean(MBeanServer mbs, String mbeanClassName, String mbeanObjectNameStr) { echo("\n>>> Create the " + mbeanClassName + " MBean within the MBeanServer"); echo("ObjectName = " + mbeanObjectNameStr); try { ObjectName mbeanObjectName = ObjectName.getInstance(mbeanObjectNameStr); mbs.createMBean(mbeanClassName, mbeanObjectName); return mbeanObjectName; } catch (Exception e) { echo( "!!! Could not create the " + mbeanClassName + " MBean !!!"); e.printStackTrace(); echo("\nEXITING...\n"); System.exit(1); } return null; } [...]
ПРИМЕР КОДА 3-3 шоу определение createSimpleMBean()
метод. В этом методе, экземпляре MBean с именем объекта mbeanObjectNameStr
передается к getInstance()
метод ObjectName
интерфейс, чтобы создать новое имя объекта для того, чтобы зарегистрировать MBean в сервере MBean. Получающийся экземпляр имени объекта называют mbeanObjectName
. Звонок MBeanServer
метод createMBean()
тогда инстанцирует MBean, определенного комбинацией объекта Java, идентифицированного mbeanClassName
и экземпляр MBean mbeanObjectName
и регистры этот MBean в сервере MBean mbs
.
[...] private static void printMBeanInfo(MBeanServer mbs, ObjectName mbeanObjectName, String mbeanClassName) { MBeanInfo info = null; try { info = mbs.getMBeanInfo(mbeanObjectName); } catch (Exception e) { echo( "!!! Could not get MBeanInfo object for " + mbeanClassName +" !!!"); e.printStackTrace(); return; } MBeanAttributeInfo[] attrInfo = info.getAttributes(); if (attrInfo.length > 0) { for (int i = 0; i < attrInfo.length; i++) { echo(" ** NAME: " + attrInfo[i].getName()); echo(" DESCR: " + attrInfo[i].getDescription()); echo(" TYPE: " + attrInfo[i].getType() + "READ: "+ attrInfo[i].isReadable() + "WRITE: "+ attrInfo[i].isWritable()); } } else echo(" ** No attributes **"); [...]
В ПРИМЕРЕ КОДА 3-4 мы видим определение метода printMBeanInfo()
. printMBeanInfo()
вызовы метода MBeanServer
метод getMBeanInfo()
получить детали атрибутов и операций, которые представляются MBean mbeanObjectName
. MBeanAttributeInfo
определяет следующие методы, каждый из которых вызывают поочередно, чтобы получить информацию о mbeanObjectName
Атрибуты MBEAN:
getName
, получить имя атрибута.getDescription
, получить удобочитаемое описание атрибута.getType
, получить имя класса атрибута.isReadable
, определить, читаем ли атрибут.isWritable
, определить, перезаписываем ли атрибут.В коде, который не показывают здесь, вызовы выполняются, чтобы получить информацию о mbeanObjectName
Конструкторы MBEAN, операции и уведомления:
MBeanConstructorInfo
, получить информацию о классе Java MBEAN.MBeanOperationInfo
, изучить, что операции MBean выполняют, и какие параметры он берет.MBeanNotificationInfo
, узнать, что отправляют уведомления MBean, когда его операции выполняются.[...] private static void manageSimpleMBean(MBeanServer mbs, ObjectName mbeanObjectName, String mbeanClassName) { try { printSimpleAttributes(mbs, mbeanObjectName); Attribute stateAttribute = new Attribute("State", "new state"); mbs.setAttribute(mbeanObjectName, stateAttribute); printSimpleAttributes(mbs, mbeanObjectName); echo("\n Invoking reset operation..."); mbs.invoke(mbeanObjectName, "reset", null, null); printSimpleAttributes(mbs, mbeanObjectName); } catch (Exception e) { e.printStackTrace(); } } private static void printSimpleAttributes( MBeanServer mbs, ObjectName mbeanObjectName) { try { String State = (String) mbs.getAttribute(mbeanObjectName, "State"); Integer NbChanges = (Integer) mbs.getAttribute(mbeanObjectName, "NbChanges"); } catch (Exception e) { echo( "!!! Could not read attributes !!!"); e.printStackTrace(); } } [...]
ПРИМЕР КОДА 3-5 шоу метод для того, чтобы управлять простым MBean.
manageSimpleMBean()
метод прежде всего вызывает printSimpleAttributes()
метод, который также определяется Server
. printSimpleAttributes()
метод получает вызванный атрибут MBean state
от MBean mbeanObjectName
, так же как другой атрибут MBean вызывают NbChanges
. Оба из этих атрибутов определяются в SimpleStandard
класс, показанный в Разделе "SimpleStandard.java".
manageSimpleMBean()
метод тогда определяет вызванный атрибут stateAttribute
, который является экземпляром Attribute
класс. stateAttribute
припишите связывает значение new state
с существующим атрибутом state
, определенный SimpleStandard
. Звонок MBeanServer
метод setAttribute()
тогда наборы mbeanObjectName
Состояние MBEAN к новому состоянию, определенному stateAttribute
.
Наконец, звонок MBeanServer
метод invoke()
вызывает mbeanObjectName
MBean’s reset
работа. reset
работа определяется в SimpleStandard
класс.
SimpleStandardMBean.java
класс показывают в ПРИМЕРЕ КОДА 3-1.
public interface SimpleStandardMBean { public String getState(); public void setState(String s); public int getNbChanges(); public void reset(); }
SimpleStandardMBean.java
класс является прямым интерфейсом управления спецификации JMX для MBean SimpleStandard
. Этот интерфейс представляет эти четыре операции, определенные SimpleStandard
для управления через агент JMX.
SimpleStandard.java
класс показывают в ПРИМЕРЕ КОДА 3-1.
public class SimpleStandard extends NotificationBroadcasterSupport implements SimpleStandardMBean { public String getState() { return state; } public void setState(String s) { state = s; nbChanges++; } public int getNbChanges() { return nbChanges; } public void reset() { AttributeChangeNotification acn = new AttributeChangeNotification(this, 0, 0, "NbChanges reset", "NbChanges", "Integer", new Integer(nbChanges), new Integer(0)); state = "initial state"; nbChanges = 0; nbResets++; sendNotification(acn); } public int getNbResets() { return nbResets; } public MBeanNotificationInfo[] getNotificationInfo() { return new MBeanNotificationInfo[] { new MBeanNotificationInfo( new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE }, AttributeChangeNotification.class.getName(), "This notification is emitted when the reset() method is called.") }; } private String state = "initial state"; private int nbChanges = 0; private int nbResets = 0; }
SimpleStandard
класс определяет прямой стандарт спецификации JMX MBean.
SimpleStandard
MBean представляет операции и атрибуты для управления, реализовывая соответствие SimpleStandardMBean
интерфейс, показанный в Разделе "SimpleStandardMBean.java".
Простые операции, представленные этим MBean, следующие:
Уведомление, испускаемое работой сброса, является экземпляром класса AttributeChangeNotification
, который собирает информацию о числе изменений, выполненных на State
атрибут прежде, чем вызвать сброс. Контент отправленного уведомления определяется MBeanNotificationInfo
экземпляр.
SimpleDynamic
класс показывают в ПРИМЕРЕ КОДА 3-1.
public class SimpleDynamic extends NotificationBroadcasterSupport implements DynamicMBean { public SimpleDynamic() { buildDynamicMBeanInfo(); } [...]
SimpleDynamic
динамический MBean показывает, как представить атрибуты и операции для управления во время выполнения, реализовывая DynamicMBean
интерфейс. Это запускается, определяя метод, buildDynamicMBeanInfo()
, для того, чтобы получить информацию для MBean динамически. buildDynamicMBeanInfo()
метод создает MBeanInfo
для динамического MBean.
Остальная часть кода SimpleDynamic
соответствует реализации DynamicMBean
интерфейс. Атрибуты, операции и представленные уведомления идентичны представленным SimpleStandard
MBean.
ClientListener.java
класс показывают в ПРИМЕРЕ КОДА 3-1.
public class ClientListener implements NotificationListener { public void handleNotification(Notification notification, Object handback) { System.out.println("\nReceived notification: " + notification); } }
ClientListener
класс реализует прямого слушателя уведомления о спецификации JMX.
handleNotification()
метод NotificationListener
интерфейс вызывают на прием уведомления, и распечатывает сообщение, чтобы подтвердить, что уведомление было получено.
Client.java
класс показывают в ПРИМЕРЕ КОДА 3-1.
public class Client { public static void main(String[] args) { try { // Create an RMI connector client // JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); ClientListener listener = new ClientListener(); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); waitForEnterPressed(); // Get domains from MBeanServer // String domains[] = mbsc.getDomains(); for (int i = 0; i < domains.length; i++) { System.out.println("Domain[" + i + "] = " + domains[i]); } waitForEnterPressed(); String domain = mbsc.getDefaultDomain(); // Create SimpleStandard MBean ObjectName mbeanName = new ObjectName(domain +":type=SimpleStandard,name=2"); mbsc.createMBean("SimpleStandard", stdMBeanName, null, null); waitForEnterPressed(); // Create SimpleDynamic MBean ObjectName dynMBeanName = new ObjectName(domain +":type=SimpleDynamic,name=2"); echo("\nCreate SimpleDynamic MBean..."); mbsc.createMBean("SimpleDynamic", dynMBeanName, null, null); waitForEnterPressed(); // Get MBean count echo("\nMBean count = " + mbsc.getMBeanCount()); // Query MBean names echo("\nQuery MBeanServer MBeans:"); Set names = mbsc.queryNames(null, null); for (Iterator i = names.iterator(); i.hasNext(); ) { echo( "ObjectName = " + (ObjectName) i.next()); } waitForEnterPressed(); mbsc.setAttribute(stdMBeanName, new Attribute("State", "changed state")); SimpleStandardMBean proxy = JMX.newMBeanProxy( mbsc, stdMBeanName, SimpleStandardMBean.class, true); echo("\nState = " + proxy.getState()); ClientListener listener = new ClientListener(); mbsc.addNotificationListener(stdMBeanName, listener, null, null); mbsc.invoke(stdMBeanName, "reset", null, null); mbsc.removeNotificationListener(stdMBeanName, listener); mbsc.unregisterMBean(stdMBeanName); [...] jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } } [...]
Client.java
класс создает клиент соединителя RMI, который конфигурируется, чтобы соединиться с сервером соединителя RMI, создаваемым Server.java
.
Поскольку можно видеть, Client.java
определяет ту же самую службу URL url
как определенное Server.java
. Это позволяет клиенту соединителя получать названный тупик сервера соединителя RMI server
от реестра RMI, работающего на порту 9999
из локального узла, и соединяться с сервером соединителя RMI.
С реестром RMI, таким образом идентифицированным, может быть создан клиент соединителя. Клиент соединителя, jmxc
, экземпляр интерфейса JMXConnector
, создаваемый connect()
метод JMXConnectorFactory
. connect()
метод передают параметры url
и a null
карта среды, когда это вызывают.
Клиент также создает экземпляр ClientListener
, прислушиваться к уведомлениям, как показано в Разделе "ClientListener.java".
Экземпляр спецификации JMX MBeanServerConnection
, именованный mbsc
, тогда создается, вызывая getMBeanServerConnection()
метод JMXConnector
экземпляр jmxc
.
Клиент соединителя теперь соединяется с сервером MBean, создаваемым Server.java
, и может зарегистрировать MBeans и выполнить операции на них с соединением, остающимся абсолютно прозрачным к обоим концам.
Клиент создает и регистрируется SimpleStandard
MBean и SimpleDynamic MBean в сервере MBean со звонком createMBean()
метод MBeanServerConnection
, и выполняет операции, определенные SimpleStandard
и SimpleDynamic
как будто они были локальной спецификацией JMX операции MBean.
Прокси MBean позволяют Вам получать доступ к MBean через интерфейс Java, разрешая Вам сделать запросы к прокси вместо того, чтобы иметь необходимость записать длинный код, чтобы получить доступ к удаленному MBean. MBean проксирует для SimpleStandardMBean
создается здесь, вызывая метод newMBeanProxy()
в javax.management.JMX
класс, передавая это MBean’s MBeanServerConnection
, имя объекта, имя класса интерфейса MBean и истины, чтобы показать, что прокси должен вести себя как a NotificationBroadcaster
. Можно сделать прокси для MXBeans точно таким же образом что касается стандартного MBeans, просто вызывая newMXBeanProxy()
вместо newMBeanProxy()
.
Код для различных операций, выполняемых на SimpleDynamic
не показывается здесь, потому что операции являются тем же самым как выполняемыми на SimpleStandard
.
Наконец, клиент нерегистрируется SimpleStandard
MBean и завершения соединение. Финал removeNotificationListener
является дополнительным, поскольку слушатели, зарегистрированные удаленным клиентом, удаляются, когда тот клиент закрывается.
Исследовав классы в качестве примера, можно теперь выполнить пример. Чтобы выполнить пример, следуйте за шагами ниже, или см. README
файл:
$
javac *.java
9999
из локального узла.
Реестр RMI будет использоваться Server
зарегистрировать тупик соединителя RMI.
$
rmiregistry 9999 &
Server
класс.
$
java - путь к классу. Сервер
Вы будете видеть подтверждение создания сервера MBean и создания SimpleStandard
MBean в сервере MBean. Вы будете тогда запрошены нажать клавишу Enter, чтобы получить информацию о, и затем выполнить операции на, SimpleStandard
MBean.
Однажды операции на SimpleStandard
завершились, процесс будет повторен для SimpleDynamic
MBean.
И однажды MBeans были созданы и однажды их выполняемые операции, Вы видите создание сервера соединителя RMI, чтобы позволить операциям выполняться на MBeans от удаленного Client
.
Client
класс в другом окне терминала.
$
java - путь к классу. Клиент
Вы будете видеть подтверждение создания клиента соединителя RMI и соединения с сервером соединителя. Вам также сообщат о доменном имени, и создании и регистрации SimpleStandard
и SimpleDynamic MBeans. Клиент тогда выполнит операции на SimpleStandard
и SimpleDynamic MBeans, прежде, чем незарегистрировать их.