Обнаружение недавно зарегистрированных MBeans - PullRequest
6 голосов
/ 29 марта 2011

Я использую сервер MBeans платформы в Java 1.6, работающий в контейнере OSGi.

Использование MBeans в основном для статистических счетчиков и событий.Их реализация находится в одном комплекте, но они создаются в нескольких других пакетах.Каждый MBean автоматически регистрируется на сервере MBean платформы.

Проблема в том, что когда я присоединяюсь через JMX и запрашиваю MBeans, я получаю только те из них, которые зарегистрированы в данный момент, и они не будут зарегистрированы, пока не будут зарегистрированы.создание экземпляра (либо потому, что статические классы не существуют до первого доступа, либо потому, что пакет еще не запущен, либо счетчик глубоко в некоторой логике, которой не будет до первого использования)

Мне нужен какой-то способподписка на «регистрацию» событий на сервере MBeans.Или какой-то другой способ определения, когда на сервер добавляются новые MBean-компоненты.Обнаружение удаленных MBean-компонентов было бы дополнительным бонусом, но не обязательно.

Единственное решение, которое у меня есть, - это поток, который опрашивает сервер каждые 5 секунд и сравнивает результат с сохраненным списком MBean-компонентов, и этодовольно некрасиво.

Ответы [ 2 ]

13 голосов
/ 01 апреля 2011

Все совместимые MBeanServers будут уведомлять слушателей о событиях регистрации и отмены регистрации MBean. Ключ заключается в том, чтобы зарегистрировать прослушиватель уведомлений на MBeanServerDelegate.

Например, javax.management.NotificationListener реализация:

public class MBeanEventListener implements NotificationListener {
    public void handleNotification(Notification notification, Object handback) {
        MBeanServerNotification mbs = (MBeanServerNotification) notification;
        if(MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
            log("MBean Registered [" + mbs.getMBeanName() + "]");
        } else if(MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
            log("MBean Unregistered [" + mbs.getMBeanName() + "]");
        }
    }       
}

Чтобы зарегистрировать прослушиватель, добавьте прослушиватель уведомлений против MBeanServerDelegate . Вы можете использовать MBeanServerNotificationFilter , если хотите отфильтровать, о каких MBean вы действительно уведомляетесь. В этом примере фильтр включен для всех ObjectNames.

    // Get a reference to the target MBeanServer
    MBeanServerConnection server = ManagementFactory.getPlatformMBeanServer();
    MBeanServerNotificationFilter filter = new MBeanServerNotificationFilter();
    filter.enableAllObjectNames();
    server.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, new MBeanEventListener(), filter, null);

Ваша реализация слушателя будет получать обратный вызов каждый раз, когда MBean зарегистрирован или незарегистрирован.

3 голосов
/ 29 марта 2011

Звучит так, как будто вы хотели бы видеть все MBean-компоненты, которые существуют где угодно, но вы не можете, поскольку код не создает их все сразу.

Я предлагаю использовать генератор кода, который создает «просмотр» MBean для всех реальных MBean. Например, используйте интерфейс класса или маркера, чтобы найти MBeans. Все компоненты вида должны быть созданы при запуске.

Теперь, когда появится настоящий MBean, он должен взглянуть на него и подключиться.

Таким образом, все MBean-компоненты всегда будут видны, запуск не сильно пострадает (поскольку представление MBean-компонентов будет действительно дешевым), а представление MBeans может сообщить вам состояние реальных MBean-компонентов.

[EDIT] Если вам действительно нужно знать только, когда зарегистрирован новый MBean, расширьте существующий MBeanServer и переопределите registerMBean(Object, ObjectName). Установите новый MBeanServer, установив системное свойство javax.management.builder.initial.

Теперь определите MBean, который предоставляет эту информацию.

...