37 votes

Comment puis-je stocker les paramètres de configuration de Java EE en dehors d'un EAR ou d'un WAR ?

Je veux stocker la configuration d'un projet web en dehors du projet web (fichier ear/war). L'application ne doit pas savoir dans quel conteneur elle s'exécute (WebSphere/JBoss, etc.).

Quelle est la meilleure façon de gérer cette situation ?

JNDI est-il un moyen propre ? Si JNDI peut résoudre mes problèmes, comment dois-je le configurer ? (Objets personnalisés ?)

Dans mon cas, il n'y a que de simples paires Clé=>Valeur (String,String) pour les points de terminaison SOAP/WS.

27voto

kgiannakakis Points 62727

Voir ceci question pour lire le fichier de propriétés en dehors du fichier WAR.

Voir ceci question pour lire les valeurs des variables à partir de JNDI. Je pense que c'est la meilleure solution. Vous pouvez lire une variable String avec ce code :

Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("java:comp/env/myvar");

Le code ci-dessus fonctionnera sur tous les conteneurs. Dans Tomcat vous déclarez ce qui suit dans conf/server.xml :

<GlobalNamingResources ...>
  <Environment name="myvar" value="..."
         type="java.lang.String" override="false"/>
</GlobalNamingResources>

Ce qui précède créera une ressource globale. Il est également possible de définir une ressource dans le contexte de l'application. Dans la plupart des conteneurs, les ressources JNDI sont disponibles par le biais d'une console de gestion MBeans. Certains d'entre eux offrent une interface graphique pour les éditer. Au maximum, un redémarrage de l'application est nécessaire, lorsqu'un changement est effectué.

La façon dont les ressources JNDI sont définies et éditées est spécifique au conteneur. C'est le rôle du configurateur/administrateur d'appliquer les paramètres appropriés.

Ce sont les avantages offerts par JNDI :

  • Vous pouvez définir les valeurs par défaut des paramètres dans le fichier WAR/EAR.
  • Les paramètres sont facilement configurables au niveau du conteneur.
  • Il n'est pas nécessaire de redémarrer le conteneur lorsque vous modifiez la valeur d'un paramètre.

11voto

Jason Thrasher Points 398

Nous avions un besoin de configuration similaire lors du déploiement d'une application web pour différents développeurs, et sur l'EC2 d'Amazon : comment séparer la configuration du code binaire ? D'après mon expérience, JNDI est trop complexe et varie trop entre les conteneurs pour être utilisé. En outre, l'édition manuelle de XML est très sensible aux erreurs de syntaxe, et l'idée a donc été rejetée. Nous avons résolu ce problème avec une conception basée sur quelques règles :

1) seules les entrées simples de type nom=valeur doivent être utilisées

2) les nouvelles configurations doivent pouvoir être chargées en changeant un seul paramètre.

3) notre binaire WAR doit être reconfigurable sans avoir à le reconditionner.

4) les paramètres sensibles (mots de passe) ne seront jamais emballés dans le binaire

L'utilisation de fichiers .properties pour toute la configuration, et l'utilisation de System.getPropert("domain"); pour charger les fichiers de propriétés appropriés, nous avons pu répondre aux exigences. Cependant, la propriété du système ne pointe pas vers une URL de fichier, à la place nous avons créé un concept que nous appelons "domaine" pour spécifier la configuration à utiliser. L'emplacement de la configuration est toujours :
$HOME/appName/config/$DOMAIN.properties .

Ainsi, si je veux exécuter mon application en utilisant ma propre configuration, je démarre l'application en définissant le domaine à mon nom :
-Ddomain=jason
au démarrage, et l'application charge le fichier :
/home/jason/appName/config/jason.properties
Cela permet aux développeurs de partager les configurations afin de recréer le même état de l'application pour les tests et le déploiement sans recompilation ou reconditionnement. La valeur du domaine est ensuite utilisée pour charger les propriétés .properties à partir d'un emplacement standard, en dehors du WAR groupé.

Je peux recréer complètement l'environnement de production sur mon poste de travail en utilisant la configuration de production comme :
-Ddomain=ec2 qui se chargerait :
/home/jason/appName/config/ec2.properties

Cette configuration nous permet d'effectuer des cycles de développement, d'assurance qualité et de publication avec un seul ensemble de binaires compilés, en utilisant différentes configurations dans chaque environnement. Il n'y a pas de risque d'avoir des mots de passe/etc inclus dans les binaires, et les gens peuvent partager leurs configurations pour recréer les problèmes que nous rencontrons.

10voto

Jared Points 7800

J'utilise une variable d'environnement pour pointer vers une URL (qui est probablement une URL file://) qui contient ma configuration. C'est très simple à mettre en place et ne nécessite pas l'infrastructure JNDI.

Voici un exemple de code (tapé de mémoire - je ne l'ai pas compilé/testé) :

public void loadConfiguration() {
   String configUrlStr = System.getenv("CONFIG_URL"); // You'd want to use a more
                                                      // Specific variable name.
   if(configUrlStr == null || configUrlStr.equals("") {
       // You would probably want better exception handling, too.
       throw new RuntimeException("CONFIG_URL is not set in the environment."); 
   }

   try {
       URI uri = new URI(configUrlStr);
       File configFile = new File(uri);
       if(!configFile.exists()) {
          throw new RuntimeException("CONFIG_URL points to non-existant file");
       }
       if(!configFile.canRead()) {
          throw new RuntimeException("CONFIG_URL points to a file that cannot be read.");
       }
       this.readConfiguration(configFile);
   } catch (URISyntaxException e) {
       throw new RuntimeException("Malformed URL/URI in CONFIG_URL");
   }

}

9voto

Aaron Saunders Points 20454

Vous pouvez juste stocker un fichier normal de propriétés java qui est sur le chemin de la classe et juste charger les propriétés ?

c'est direct et assez simple à moins que je ne manque quelque chose

4voto

peacefulfire Points 722

Mes endroits préférés sont : Variables d'environnement et fichiers de propriétés (comme suggéré par Jared et kgiannakakis ci-dessus).

Table de base de données stockant les propriétés de l'environnement

Cependant, une autre solution plus simple consiste à disposer d'une table de base de données stockant les propriétés de l'environnement.

Si votre application utilise une base de données

  • c'est relativement facile à mettre en place
  • Permet de contrôler/modifier les valeurs très facilement.
  • On peut l'intégrer au processus en l'intégrant aux scripts de la BD.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X