Détails :
Dans les tutoriels Créer un service de configuration avec Spring 1,2 et 3, nous avons créé un service qui permet d'initialiser des propriétés de configuration à partir d'un fichier .properties. Ces propriétés peuvent alors être utilisées dans toutes les servlets.
Si une des propriétés du fichier .properties est changée, il faut redémarrer le serveur pour qu'elle soit prise en compte, ce qui est un gros inconvénient dans un environnement de production.
Pour palier à ce problème, nous allons créer un bean de management : MBean et l'enregistrer sur le serveur. La console JConsole, fournie avec la jdk 1.5, va nous permettre d'accéder à ce MBean et d'en exécuter certaines méthodes et entre autre la méthode permettant de réinitialiser le service de configuration, sans redémarrer le serveur.

Définition JMX : Java Management eXtension ou JMX est une API java permettant de surveiller une application java existante. Cette technologie permet également d’intéragir sur l’application en cours d’exécution.

Projet réalisé avec :
Eclipse Europa 3.3.1.1
Apache Tomcat 5.5.26
Plugin Maven pour Eclipse http://m2eclipse.codehaus.org/
Java JDK 1.5
Spring 2.5.5


(Les sources du projet sont disponibles en annexe)

1- Création du MBean et de son interface
Nous souhaitons créer un bean de management dont le seul rôle est de permettre la réinitialisation du service de configuration ConfigurationService. Nous créons donc une interface très simple :

public interface ConfigurationServiceMBean {
 
	/**
	 * Ré-initialise le service de configuration.
	 */
	void reInitConfigurationService();
}

Puis nous créons une implémentation de ce service :

public class ConfigurationServiceMBeanImpl implements ConfigurationServiceMBean {
 
	private static Log logger = LogFactory.getLog(ConfigurationServiceMBeanImpl.class);
 
	private ConfigurationService configurationService;
 
	public void reInitConfigurationService() {
		logger.info("Debut de la re-initialisation du service de configuration");
		configurationService.init();
		logger.info("Fin de la re-initialisation du service de configuration");
	}
 
	/**
	 * @param configurationService the configurationService to set
	 */
	public void setConfigurationService(ConfigurationService configurationService) {
		this.configurationService = configurationService;
	}
 
}



2- Configuration du fichier applicationContext.xml pour exposer notre MBean

Déclaration du MBean avec injection du service de configuration :

<bean id="configurationServiceMBean" class="fr.minimarmotte.projects.mbean.impl.ConfigurationServiceMBeanImpl">
	<property name="configurationService" ref="configurationService" />
</bean>

La configuration suivante permet de localiser un serveur existant et de s'y connecter (ici on utilise un serveur tomcat) :

<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
     	<property name="locateExistingServerIfPossible" value="true"/>
</bean>

Enfin notre MBean va devoir signaler sa présence au MBeanServer. On utilise pour cela un MBeanExporter, pour lequel on spécifie la liste des MBean à exposer sur un MBeanServer en particulier :

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"
  	lazy-init="false">
  	<property name="beans">
  		<map>
  			<entry key="bean:name=configurationServiceMBean" value-ref="configurationServiceMBean" />
  		</map>
  	</property>
  	<property name="server" ref="mbeanServer"/>
</bean>


Pour plus de détails, se référer à Spring 2.5 reference chapter 20 JMX.

3- Configuration de la JVM et démarrage du serveur
Afin de pouvoir utiliser la JConsole, nous devons tout d'abord ouvrir le connecteur JMX de la JVM. On va donc passer quelques options à la JVM. Dans Eclipse, on fait un clique droit sur le serveur tomcat, Open. Puis on clique sur le lien Open Launch Configuration : Eclipse overview serveur

On clique sur l'onglet Arguments et dans la partie VM arguments, on rajoute l'option suivante : -Dcom.sun.management.jmxremote Eclipse launch configuration properties

En local (JConsole et serveur sur la même machine), cette option suffit. Mais il est possible d'administrer un serveur à distance. Dans ce cas d'autres paramètres doivent être ajoutés. Pour plus d'informations, voir la doc de sun. Remote Monitoring and Management.

Il nous reste à démarrer le serveur et constater dans les logs que notre MBean a bien été enregistré :

21 juil. 2008 12:09:30 org.springframework.jmx.export.MBeanExporter afterPropertiesSet
INFO: Registering beans for JMX exposure on startup
21 juil. 2008 12:09:30 org.springframework.jmx.export.MBeanExporter registerBeanInstance
INFO: Located managed bean 'bean:name=configurationServiceMBean': registering with JMX server as MBean [bean:name=configurationServiceMBean]


4- Accès au MBean dans la JConsole
Sous windows, dans le dossier d'installation de la jdk, aller dans le dossier bin et lancer jconsole.exe. JConsole connexion On clique sur connect.

Un certains nombres d'onglets sont disponibles. Ils offrent diverses fonctionnalités de supervision et d'administration. Pour plus de détails, voir l'article de Sun : Using JConsole to Monitor Applications.

Aller sur l'onglet MBeans, puis rechercher le MBean que nous avons enregistré : bean/congigurationServiceMBean. JConsole mbean configuration service 1

Dans les logs on peut voir l'erreur suivante :

21 juil. 2008 13:45:30 RequiredModelMBean getAttributes(String[])
GRAVE: Failed to get "ConfigurationService": javax.management.AttributeNotFoundException: getAttribute failed: ConfigurationService is not readable 

Ne pas en tenir compte pour le moment...

Pour ré-initialiser le service de configuration, aller dans l'onglet Operations et cliquer sur le bouton reInitConfigurationService. Un message de succès apparaît. Et on peut voir dans les logs :

21 juil. 2008 13:52:11 fr.minimarmotte.projects.mbean.impl.ConfigurationServiceMBeanImpl reInitConfigurationService
INFO: Debut de la re-initialisation du service de configuration
21 juil. 2008 13:52:11 fr.minimarmotte.projects.mbean.impl.ConfigurationServiceMBeanImpl reInitConfigurationService
INFO: Fin de la re-initialisation du service de configuration

indiquant que notre manipulation a bien eu un impact sur l'application en cours, sans pour autant redémarrer le serveur.

Pour vérifier que la ré-initialisation fonctionne correctement, aller sur la page http://127.0.0.1:8080/mp-spring-jmx-1/afficher_messages
La valeur correspond à la clé "cle.test.resource" est affichée.
Nous allons changer cette propriété dans le fichier C:/temp/configurationService.properties :
Avant : cle.test.resource = il y a bien une resource
Après : cle.test.resource = clé changée
Si on ré-affiche la page http://127.0.0.1:8080/mp-spring-jmx-1/afficher_messages, on voit qu'aucun changement n'a été pris en compte. Pour que les changements soient pris en compte, soit on redémarre le serveur, soit on réinitialise le service de configuration grâce à la JConsole. On re-clique donc sur le bouton reInitConfigurationService.
Et on ré-affiche la page http://127.0.0.1:8080/mp-spring-jmx-1/afficher_messages On s'aperçoit alors que la valeur correspondant à la clé "cle.test.resource" a bien été modifiée !!!