Fiches Pratiques www.demos.fr/informatique JAVA SE – Ressources Ressources et Fichiers de Configuration Le déploiement d'une application Java contient certes du code (des fichiers .class dans des packages) mais aussi des fichiers contenant des données de ressource. Notre application peut, par exemple, avoir besoin d'images ou de fichiers de configuration en format texte. Il existe même en standard des formats de fichier texte de configuration : voir la documentation de la classe java.util.Properties méthodes load et loadFromXML. Prenons le cas de tels fichiers de configuration et posons nous la question : où se trouvent ces fichiers au déploiement? On ne peut pas imaginer un code qui travaillerait sur la base de règles comme : si on est sous un système Windows alors la ressource se trouve sous C:\Program Files\MonApplicatif\config\fichier_config.properties si on est sous UNIX ce sera : /opt/MonApplicatif/config/fichier_config.properties etc. Un tel fonctionnement serait une insulte aux principes de la portabilité en Java ! Les questions auxquelles il faut savoir répondre : A quoi sont liées les données de configuration? Une application utilise un ensemble de composants logiciels. Dans la plupart des cas la configuration concerne donc un sous-ensemble de l'application et est donc liée à une classe ou à un ensemble de classes d'un package. Où se trouvent les données de configuration d'un package? Avec l'application ! Pour comprendre cela prenons le cas où l'application s'exécute sur un poste client en chargeant des codes qui sont déployés sur un serveur distant … Où se trouve la configuration? Sur la machine client ou sur la machine serveur? Bien entendu les configurations applicatives se trouvent sur la machine serveur! Quel mécanisme va me permettre de retrouver les données associées au code d'une application? Le mécanisme qui a permis de "charger" le code de l'application saura naturellement retrouver les données associées. Il s'agit du ClassLoader qui aura su charger la classe qui a besoin de ces données de configuration. L'ouverture d'un Stream de lecture aura donc l'aspect suivant : InputStream is = ClasseCourante.class.getResourceAsStream( "config/fichier.properties") ; Ce code appelle de nombreux commentaires : ClasseCourante.class nous permet d'obtenir un objet de type java.lang.Class qui représente la classe courante. (Petit jeu de piste : pourquoi ne faut-il pas écrire this.getClass() qui aurait aussi pour effet d'obtenir la classe de l'objet? Nous vous laissons donner libre cours à votre sagacité…) La méthode getResourceAsStream va permettre d'ouvrir cette ressource et de rendre un canal de lecture dessus. (Noter qu'en anglais ressource ne prend qu'un "s"!). Attention: tester le résultat! La méthode rend null si la ressource n'est pas trouvée. Quel est la nature de l'argument à passer à cette méthode? Dans l'exemple ci dessus nous avons fait exprès de spécifier un pseudo-package de nom config et donc le nom passé en paramètre est "config/fichier.properties". Pourquoi faire ça et quelles sont donc les bonnes pratiques de déploiement? Où se trouve le fichier de configuration? Dans "l'espace" géré par le ClassLoader qui a chargé le package correspondant à la classe. Notre conseil (mais ce n'est pas obligatoire) : créez une sorte de subdivision dans cet "espace" (le pseudo-package config) qui vous permettra de bien séparer codes et ressources. Où se trouve physiquement ce fichier de configuration? Le ClassLoader dispose d'une liste d'endroits (le CLASSPATH). Une bonne pratique consiste à distinguer les jars qui contiennent les codes applicatifs des jars qui contiennent codes et ressources de déploiement. Il est donc probable que la classe et le fichier qui la configure ne se trouvent pas dans la même archive jar! A l'intérieur des jars on aura donc des cheminoms qui ressembleront à ceci : Dans le jar applicatif fr |_ maboite |_ metier |_ utils |_ ClasseCourante.class Dans le jar de déploiement fr |_ maboite |_ metier |_ utils |_ config |_ fichier.properties Quel est donc la signification du caractère "/" dans la chaine passée en argument? C'est un séparateur d'éléments d'URL. Le système reconstruit en fait une URL à partir du point où il a trouvé la classe. Prenons un cas complexe pour illustrer ce comportement: les jars se trouvent sur un site distant accédé par http. On a deux jars dans le CLASSPATH : http://serveur.autreboite.fr/java/application.jar http://serveur.autreboite.fr/java/deploiement.jar L'URL de la classe sera alors : jar:http://serveur.autreboite.fr/java/application.jar!/fr/maboite/metier/utils/Clas seCourante.class L'utilisation de la chaine "config/fichier.properties" pourra générer : jar:http://serveur.autreboite.fr/java/deploiement.jar!/fr/maboite/metier/utils/con fig/fichier.properties Donc le système va essayer de trouver dans les éléments du CLASSPATH quelque chose qui lui permette de reconstituer une URL valide. D'autres cas peuvent se produire: si par exemple on passe en argument "/media/image.png" au lieu de reconstituer une URL "relative" le système va essayer de constituer un URL en "absolu" à partir d'une des bases possibles et donc on pourrait avoir : jar:http://serveur.autreboite.fr/java/application.jar!/media/image.png ou jar:http://serveur.autreboite.fr/java/deploiement.jar!/media/image.pn selon l'endroit où se trouve la ressource ! Il existe d'autres techniques de ressources : Les ressources d'internationalisation qui suivent pratiquement les mêmes principes mais qui sont gérés par des ResourceBundle permettant, par exemple, de mettre en place des dictionnaires hiérarchisés (le dictionnaire du canadien français n'étant pas une copie du dictionnaire du français mais juste une liste de différences). Les préférences utilisateur. Celles ci ne sont plus liées au ClassLoader de l'application mais bien au site d'exécution (par exemple elles seront gérées sur le poste client au lieu d'être gérées sur le serveur). Formations JAVA sur ce sujet Pour maitriser ces aspects du déploiement des applications java vous pouvez suivre les cours suivant : USL285 - Développement d'Application Java IIN44 - Java SE Techniques Professionelles Nos formations Java longues (standards ou spécifiques). Nos cours "java avancé" adaptés à la demande. Toutes les formations Développement Bernard AMADE © Demos