Mon précédent article portant sur la présentation générale de JMX a permis de poser les bases quant aux concepts fondamentaux. Cette seconde partie ainsi que les suivantes consistent en une descente plus en profondeur dans les entrailles des spécifications en reprenant les différentes notions vues précédemment.
Ainsi, cette partie traitera des différents MBeans et du concept notification.
Table des matières
- JMX, qu’est ce que c’est?
- Spécifications
MBean
Un MBean est une classe java concrète qui :
- doit implémenter sa propre interface MBean ou implémenter l’interface
DynamicMBean
, - peut implémenter l’interface
NotificationBroacaster
Une classe qui implémente sa propre interface de MBean
est un MBean Standard. Cette manière de procéder est la plus simple. Dans ce cas, les opérations et attributs accessibles sont déterminés statiquement grâce à l’introspection de l’interface du MBean.
Pour un Dynamic MBean (et donc une classe implémentant l’interface DynamicMBean
), les opérations et les attributs sont exposés de manière indirecte à l’agent JMX qui invoque alors des méthodes pour déterminer le nom et la nature des opérations et attributs.
Un MBean n’est pas obligatoirement une classe publique Java. Cependant, elle doit implémenter une interface publique (que ce soit ses propres opérations pour un MBean standard ou l’interface DynamicMBean
pour un MBean dynamique).
En outre, le MBean peut avoir plusieurs constructeurs qui doivent être publiques s’il doit être instancié par un agent.
MBean Standard
Comme il a été vu précédemment que, pour être gérable via un agent JMX, un MBean Standard doit explicitement définir son interface de gestion et doit être conforme à certaines règles de nommage qui sont inspirées du modèle des JavaBean.
Ainsi, l’interface de gestion d’un MBean Standard peut être composée de :
- ses constructeurs : seuls les constructeurs publics sont exposés,
- ses attributs : les propriétés qui sont exposées le sont au travers des getter et setter,
- ses opérations : les méthodes qui sont exposées sont toutes les méthodes qui ne sont pas des getter ou des setter,
- ses notifications.
En outre, l’interface qui est implémenté par le MBean doit porter le même nom que ce dernier mais avec le suffixe MBean
(par exemple, si la classe à gérer se nomme MyClass
, alors l’interface devra se nommer MyClassMBean
).
Une classe peut aussi être administrable par son héritage si elle respecte un des modèles suivants :
Modèles | Commentaires |
---|---|
Les opérations exposées sont a1 et a2. | |
Si B étend A sans implémenter sa propre interface, alors B hérite de l’interface de management AMBean et les opérations exposées sont a1 et a2. | |
B hérite de A et implémente sa propre interface de management BMBean. L’opération exposée est b2. | |
B hérite de A et implémente son interface de management qui hérite de celle de A. Les opérations exposées sont a1, a2 et b2. A noter que si B n’étendait pas A, les opérations exposées seraient similaires. | |
B implémente son interface de management qui hérite de l’interface AMBean. Les opérations exposées sont a1, a2 et b2. |
Les attributs sont les champs ou les propriétés des MBean implémentés (ou étendus). Ils sont déterminés par leurs noms (la méthode Character.isJavaIdentifierStart
(resp. Character.isJavaIdentifierPart
) doit renvoyer vrai pour sa première lettre (resp. ses autres lettres)) et par leurs types et sont accédés au travers de leurs accesseurs. Aussi, si un attribut n’a pas d’accesseurs, il ne sera pas visible puisque, pour rappel, ses accesseurs permettent également de déterminer son niveau d’accessibilité (lecture seule, écriture seule ou lecture-écriture). Cependant, il est à noter qu’un attribut ne doit avoir qu’un seul getter et/ou setter et peut être de n’importe quel type Java (cela inclus également les tableaux).
Les opérations JMX peuvent avoir différentes fonctions (comme effectuer une opération interne sur la ressource managée ou renvoyer une valeur) et sont des méthodes Java qui doivent être spécifiées dans l’interface de management (MBean). Ainsi, toute opération qui ne répond pas au design pattern défini par la définition d’attribut JMX est vue comme une opération.
Dynamic MBean
Alors que les MBean Standard permettent de gérer des ressources bien définies, les Dynamics MBean offrent une solution plus flexible. En effet, les Dynamics MBean sont des ressources qui sont instrumentés au travers d’une interface prédéfinie qui n’expose les attributs et les opérations qu’à l’exécution. En effet, au lieu d’exposer ses opérations et attributs au travers de méthodes déterminées à l’avance, les Dynamics MBean implémentent une méthode qui retourne tous ses attributs ainsi que la signature de toutes ses méthodes, permettant ainsi de rendre l’exposition dynamique.
En fait, un MBean qui implémente l’interface DynamicMBean
ne fonctionne pas par introspection comme les MBean Standard mais appelle des méthodes qui lui renvoient les attributs et opérations gérables.
Ainsi, un MBean Dynamic est une classe Java qui implémente directement ou indirectement (ie. par héritage) l’interface publique DynamicMBean
.
En fait, cette interface définie les méthodes suivantes :
getMBeanInfo
qui retourne une instance d’un MBeanInfo et qui contient la définition de l’interface de management du MBean, c’est-à-dire la liste des ses attributs associés à leurs types et leurs propriétés (lecture-seule, écriture, lecture-écriture), de ses opérations associées à leurs signatures, la liste des notifications ainsi que la description des constructeurs offerts par le MBean.
getAttribute
etgetAttributes
qui retournent le ou les attributs demandés.setAttribute
etsetAttributes
qui permettent de renseigner les attributs.invoke
qui permet d’invoquer toutes les opérations offertes par le MBean.
En outre, tout comme pour les MBean Standard, les Dynamic MBean peuvent hériter leur instrumentation d’une superclasse, mais il est à noter que l’interface de management ne peut être composée d’un arbre d’héritage puisque l’interface de management est fournie par le MBeanInfo
.
Ainsi, dans l’exemple suivant, si la classe D étend la classe C sans redéfinir la méthode getMBeanInfo
, alors D aura la même interface de management que C. Cependant, D pourra, en redéfinissant les accesseurs redéfinir l’implémentation de ses attributs.
Le serveur MBean ne teste ni ne valide la description du Dynamic MBean : c’est au développeur de vérifier si l’interface de management est conforme à l’implémentation interne. |
Notification
Les interfaces de gestion des MBean permettent à un agent de récupérer ou de modifier la valeur des attributs des ressources ainsi que d’invoquer des opérations sur ces dernières. Cependant, JMX permet également de notifier les applications de gestion en cas de changement d’état du système (et plus particulièrement des ressources).
Ainsi, JMX propose un modèle pour émettre des événements (appelés Notification) fonctionnant sur le principe d’écouteurs : les applications de managements et les autres objets enregistrés peuvent s’enregistrer comme des écouteurs (NotificationListener
) du MBean émetteur de notifications (Notification
). Il est cependant à noter qu’il ne leur est possible de ne s’enregistrer qu’une seule fois auprès de l’émetteur.
Les notifications sont encapsulées dans une implémentation de l’interface Notification
qui est composée :
- du type de notification (de type
String
) qui est formatée à la façon des propriétés java (ie. une chaine de caractère utilisant des points. Par exemple :vendorName.resourceA.eventA1
). Il est à noter que les types de notification préfixés par JMX. sont réservées aux notifications émises par l’infrastructure JMX (par exemple,JMX.mbean.registered
). - d’un numéro de séquence qui permet d’identifier une instance particulière de notification dans un contexte de broadcast.
- du timestamp qui permet de savoir quand la notification a été générée.
- du message émis (de type
String
) qui peut permettre d’expliciter la notification à l’utilisateur. - d’information utilisateur (de type
Object
) qui peut contenir d’autres types d’information.
Du coté de l’émetteur, il doit implémenter soit l’interface NotificationBroadcaster
, soit l’interface NotificationEmitter
.
En outre, il est également possible de filtrer les notifications reçues en implémentant l’interface NotificationFilter
.
Open MBean
Les Open MBean sont un-sous type des Dynamic MBean. En fait, il s’agit de Dynamic MBean mais dont le type des attributs et des signatures des opérations a été normalisé afin de permettre une meilleure interopérabilité entre le MBean et l’interface de management. Ainsi, l’application de management et les Open MBean peuvent partager et utiliser les données de management (attribut) et invoquer les opérations sans nécessiter une recompilation, un ré-assemblement ou un linkage dynamique, opérations qui nécessiteraient que l’application de management ait accès aux classes Java de l’agent si les types n’étaient pas normalisés.
Cependant, les Open MBean ne sont que des Dynamic MBean, c’est-à-dire que c’est à la charge du développeur de vérifier qu’ils n’utilisent que les types définis supportés par les Open MBean.
Aussi, la méthode getMBeanInfo()
doit retourner une instance d’un OpenMBeanInfoSupport
plutôt qu’une instance d’un MBeanInfo
(pour rappel, un Dynamic MBean doit implémenter l’interface DynamicMBean
qui possède la méthode getMBeanInfo()
et qui renvoie un objet de type MBeanInfo
).
Les types supportés par les Open MBean sont :
Type de données sypportées par les Open MBean | |
---|---|
java.lang.Boolean | java.lang.Float |
java.lang.Byte | java.lang.Integer |
java.lang.Character | java.lang.Long |
java.lang.Double | java.lang.Short |
boolean[] | float[] |
byte [] | int[] |
char[] | long[] |
double[] | short[] |
java.lang.String | java.lang.Void (retour d’opérations seulement) |
java.math.BigDecimal | java.math.BigInteger |
java.util.Date | javax.management.ObjectName |
javax.management.openmbean.CompositeData (interface) | javax.management.openmbean.TabularData (interface) |
Les types CompositeData
et TabularData
sont utilisés pour agréger les données basiques (tels que les String ou les tableaux de int) et fournissent un mécanisme pour fournir des structures de données complexes. Bien que ces types soient des types simples (au sens JMX du terme), elles peuvent contenir d’autres CompositeData
ou TabularData
.
En fait, une implémentation d’un CompositeData
est équivalente à une Map
, alors qu’une instance d’un TabularData
est équivalente à un tableau de CompositeData
.
Il est à noter qu’un CompositeData
est une structure immuable. Ainsi dès qu’il est instancié, il n’est pas possible de le modifier. Le TabularData
peut, quant à lui, être modifié.
JMX fournit une implémentation de ces interfaces qu’il est possible d’utiliser. Pour le CompositeData
, il s’agit de CompositeDataSupport
et, pour le TabularData
, TabularDataSupport
(classe qui définie une structure de tableau contenant des CompositeData qui doivent avoir le même CompositeType
).
Cependant, le fait d’utiliser des types de données complexes nécessite que l’Open MBean doit décrire la structure des données. Pour cela, les Open MBean proposent une classe abstraite OpenType
qui décrit aussi bien ses types basiques que ses types complexes. Cette classe abstraite est donc étendue par des classes qui décrivent chacun de ses types cités ci-dessus en spécifiant le nom du type, sa description ainsi que la classe qui la spécifie. Cela permet, pour les types complexes, de fournir une description et un nom de chaque élément qui le compose.
De plus, comme indiqué précédemment, un Open MBean étant un Dynamic MBean, il doit s’auto décrire via l’interface MBeanInfo. Pour cela, JMX propose, par défaut, des sous-classes des classes permettant de décrire un Dynamic MBean (MBeanInfo
, MBeanAttributeInfo
, MBeanOperationInfo
, MBeanParameterInfo
, MBeanConstructorInfo
) et dont le nom est préfixé par Open et postfixé par Support (OpenMBeanInfoSupport
, OpenMBeanAttributeInfoSupport
, OpenMBeanOperationInfoSupport
, OpenMBeanParameterInfoSupport
, OpenMBeanConstructorInfoSupport
).
Les notifications sont, quant à elle, standard.
Model MBean
Un Model MBean est un MBean générique configurable ayant pour objectif de fournir un patron de MBean pouvant être utilisé simplement par n’importe quelles ressources. Il s’agit, en fait, d’un MBean Dynamic particulier dont l’interface définie une structure qui, lorsqu’elle est implémentée, fournie un MBean avec un comportement par défaut. Ces Model MBean devant être supportés par les agents JMX, ils peuvent être utilisés par n’importe quels applications, ressources et services pour créer un objet gérable à l’exécution : les utilisateurs n’ont qu’a instancier un Model MBean, configurer son comportement par défaut et l’enregistrer au sein de l’agent JMX.
En fait un Model MBean est constitué d’un ensemble d’interfaces et de classes concrètes fournit par l’agent JMX (qui doit fournir une implémentation de la classe RequiredModelMBean
et qui a pour objectif de fournir un comportement par défaut).
Un MBean Server est donc un repository et factory de Model MBean qui peuvent être obtenus au travers de l’agent JMX afin de rendre une ressource gérable : le développeur n’a pas besoin de fournir une implémentation de cette classe mais juste la configurer à l’exécution afin d’exposer l’interface d’administration et de supervision nécessaire à la ressource.
La ressource à administrer et à superviser ajoute ses attributs, ses opérations et ses notifications à l’objet basique Model MBean en s’interfaçant avec l’agent JMX et à son ou ses Model MBean.
Comme précisé précédemment, un Model MBean est un Dynamic MBean et doit donc implémenter l’interface DynamicMBean
.
Il est également à noter que l’implémentation du RequiredModelMBean
est dépendante de l’environnement et plus précisément de la JVM : elle peut fournir des mécanismes de persistance, de transaction, de cache, de scalabilité ou de fonctionnement distant en fonction des besoins. Ainsi, le développeur n’a pas à se soucier de problématiques comme celles de persistance en se fiant à l’implémentation de la JVM sur lequel fonctionne son application (par exemple, un environnement J2ME n’a pas besoin d’offrir des propriétés de persistance ou d’accès distant) : il peut le déléguer au Model MBean exposé.
Une implémentation d’un Model MBean doit implémenter l’interface ModelMBean
qui étend les interfaces DynamicMBean
, PersistentMBean
et ModelMBeanNotificationBroadcaster
.
En outre, le Model MBean doit exposer ses méta-données dans un objet de type ModelMBeanInfoSupport
qui étend la classe MBeanInfo
et qui implémente l’interface ModelMBeanInfo
.
De plus, une instance d’un Model MBean peut émettre des notifications lors de changements de la valeur de ses attributs et possède un constructeur par défaut et un constructeur qui prend en paramètre une instance d’un ModelMBeanInfo
. Il est à noter que chaque attribut, constructeur, opération et notification peut fournir sa description. Ces descriptions peuvent être de différentes natures comme la politique de connexion, la politique de notifications, …
Enfin, les descriptions d’un Model MBean fournissent un mapping entre les attributs et les opérations de l’interface de gestion et les méthodes utilisées par la ressource à gérer (méthodes set, get et invoke). Il est à noter que ces ressources peuvent être indifféremment sur une autre JVM si le Model MBean a été configuré.
Concrètement, une ressource managée donc doit utiliser l’interface ModelMBeanInfo
pour exposer son interface d’administration et de supervision. A l’initialisation, la ressource managée créée ou trouve via le MBean Server une ou des instances d’un ModelMBean qui peuvent alors être configurées avec son interface de management (via une implémentation de l’interface ModelMBeanInfo
).
De la même manière, l’application de management (l’application cliente des ressources à administrer et superviser) via le serveur MBean peut accéder aux descriptions, aux opérations et aux notifications du ModelMBean afin de pouvoir les exposer à l’administrateur en lui fournissant le maximum d’information.
Afin de permettre au Model MBean de fournir la description de ses différentes opérations, notifications et attributs, JMX propose, par défaut, des sous-classes des classes permettant de décrire un ModelMBean : ModelMBeanInfoSupport
, ModelMBeanAttributeInfo
, ModelMBeanOperationInfo
, ModelMBeanNotificationInfo
, ModelMBeanConstructorInfo
).
Ces classes implémentent l’interface DescriptorAccess
qui permet de remplacer l’interface Descriptor
pour chaque attribut, constructeur, opération et notification dans l’interface de management. La description est alors accédée au travers des méta-données de chaque composant.
L’interface NotificationBroadcaster
, qui permet lorsqu’elle est implémentée par une MBean d’émettre des notifications génériques ou spécifiques et/ou lorsqu’un changement de valeur d’un attribut se produit à des MBean déclarés comme écouteur, est implémentée pour les Model MBean par l’interface ModelMBeanNotificationBroadcaster
.
L’interface Descriptor
fournit les descriptions des opérations, attributs et notifications du Model MBean qui ne sont pas accédées directement mais au travers de l’interface DescriptorAccess
qui définit comment récupérer et positionner la valeur des différents champs qui constituent la description.
Par défaut, JMX fournit deux implémentations de l’interface Descriptor
: ImmutableDescriptor
et DescriptorSupport
.
En fait, l’interface ModelMBeanInfo
publie des méta-données sur les attributs, les opérations et les notifications déclarés dans l’interface d’administration et de supervision. Les descripteurs du Model MBean fournissent, quant à eux, le comportement et les règles de ces attributs, opérations et notifications. Un descripteur se présente sous forme d’un ensemble de clé/valeur où la clé est de type String et la valeur est de type Object qui peut être modifié (ajout, modification et suppression des champs) par la ressource managée ou par l’application de gestion. Il est à noter que certains noms sont réservés pour des propriétés prédéfinies telles que la gestion du cache ou de la persistance. Les descripteurs contiennent également le nom des opérations des getter et setter utilisées pour lire et écrire la valeur des attributs.
Comme indiqué précédemment, les descripteurs sont des objets qui implémentent l’interface Descriptor
et qui sont accessibles au travers des méthodes définies par l’interface DescriptorAccess
dont les méthodes doivent être définies par les implémentations concrètes des interfaces ModelMBeanAttributeInfo
, ModelMBeanOperationInfo
, ModelMBeanConstructorInfo
et ModelMBeanNotificationInfo
(qui sont accessibles via l’instance de ModelMBeanInfo
).
Une liste exhaustive des champs prédéfinis des descripteurs peut être trouvée dans la version agrégée de la spécification JMX au chapitre 4.5 Predefined Descriptor Fields. |
Le mot de la fin de cette partie
Ainsi s’achève cette partie qui a permis de voir les notions de MBeans (en particulier les différences entre les différents MBeans) et de Notification.