JMX - Technologie pour le monitoring d'applications Java par Baptiste DERRÉ

Qu'est-ce qu'un MBean?

MBean signifie Managed Bean. Il s'agit d'un objet Java et plus précisément d'une interface, permettant de définir les opérations qui seront disponibles pour une ressource. Ces opérations seront lues par le serveur de MBean de l'agent JMX de façon à ce que les applications de gestion puissent utiliser ces opérations et ainsi contrôler les ressources. Il existe deux types de MBeans : le MBean standard et le MBean dynamique.

Le MBean standard

Le MBean standard a l'avantage d'être simple à implémenter. En effet, il suffit pour une classe nommée MaClasse.java de créer une interface nommée MaClasseMBean.java puis de définir dans cette dernière les opérations intéressantes pour notre supervision. Voici un diagramme de classe expliquant une implémentation simple d'un MBean Standard :

MBean standard

Ce schéma présente une classe appelée MaClasse possédant un simple attribut entier "value". L'interface MaClasseMBean est le MBean de cette classe. Il va définir les méthodes getValue() et setValue(int value) de façon à ce que le client JMX puisse voir et modifier la valeur de l'attribut "value" alors même que l'application de la ressource possédant la classe MaClasse est en cours d'exécution.

Le MBean dynamique

Le MBean dynamique est, quant à lui, plus difficile à mettre en œuvre. Dans ce dernier, il n'est plus nécessaire de créer une interface pour une classe. Il suffit d'implémenter l'interface déjà existante dans le package javax.management nommée DynamicMBean. Contrairement au MBean standard, celui-ci est plus performant pour le serveur de MBean de l'agent JMX. En effet, au lieu de lire les opérations disponibles pour les ressources par réflexion, ce dernier se contentera de faire un simple appel de méthode pour récupérer les informations du MBean et invoquer les opérations. Le schéma ci-dessous vous présente une implémentation du MBean dynamique.

MBean dynamique

Sur ce diagramme, nous pouvons remarquer que la classe MaClasse implémente l'interface DynamicMBean. Elle devra, par conséquent, redéfinir les méthodes de cette interface. Prenons un exemple concret :

Nous allons définir une HashMap<String, Method> en attribut de la classe MaClasse qui, dans le constructeur de ma classe, va ajouter toutes ses méthodes :

	private HashMap<String, Object> attributes = new HashMap<String, Object>();
	private HashMap<String, Method> methods = new HashMap<String, Method>();
			
	public MaClasse(int value) {
		attributes.put("value", value);
	
		for(Method method: getClass().getMethods())
			methods.put(method.getName(), method);
	}

Voici un exemple de redéfinition de la méthode invoke :

	@Override
	public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
		if (methods.containsKey(actionName))
			try {
				return methods.get(actionName).invoke(this, params);
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				System.err.println("Erreur lors de l'invocation : " + e.getMessage());
			}
		return null;
	}

Supposons que ma classe possède une opération appelée setValue(int value). Pour invoquer cette opération, l'agent JMX qui connaîtra les différentes méthodes et attributs disponibles grâce à la méthode getMBeanInfo(), va faire appel à la méthode invoke de cette façon :

	invoke("setValue", new Object[]{ 42 });

C'est ainsi que la valeur sera mise à jour dans la ressource. La nouvelle valeur de l'attribut value aura désormais la valeur 42.