Est-ce une mauvaise pratique d'inclure des fichiers de propriétés / configuration dans des fichiers JAR?

StackOverflow https://stackoverflow.com/questions/1208848

Question

Par exemple:

MyApp est une application Web contenant un fichier de propriétés (server.properties) décrivant les données de configuration (noms de serveur, par exemple) de l'application. Dans la phase de développement, server.properties se trouve dans son propre dossier de projet IDE (un emplacement logique pour celui-ci).

Il est maintenant temps de déployer MyApp. L'IDE rend assez facile de copier les fichiers de classe ainsi que les fichiers de configuration correspondants. Maintenant, nous venons de déposer le pot dans le conteneur Web approprié et nous partons ...

Une semaine plus tard, les données de configuration du serveur utilisées par MyApp doivent être modifiées. Ce qui a plus de sens?

A. Modifiez le fichier server.properties dans l'IDE et générez un tout nouveau fichier jar. Redéployer. (ce qui signifie que l'application rebondit pour un simple changement de configuration).

B. Ouvrez le fichier Jar déjà déployé et modifiez le fichier server.properties? (il peut être nécessaire d'appeler une fonction d'actualisation dans MyApp si server.properties est mis en cache ... mais ne nécessite pas de rebond complet de l'application. Vous devez également vous rappeler de modifier le fichier source server.properties afin que les déploiements futurs n'annulent pas le processus server.properties. aux anciens noms de serveur).

C. Faites en sorte que server.properties soit externe au fichier jar. Très similaire au processus de B, avec la différence mineure de garder les données de configuration externes au jar (introduit des chemins différents entre les déploiements de développement et de production)

D. Autre:

Merci!

Était-ce utile?

La solution

J'irais avec D.

Essayez de charger les fichiers de propriétés en dehors du .jar, puis, en cas d'échec, chargez les propriétés intégrées au jar.

Ceci vous permet de sortir un "prêt à l'emploi". configuration avec chaque construction (réduit également la complexité d'un déploiement, ne serait-ce que d'un seul fichier), tout en rendant les configurations prioritaires possibles et relativement simples.

Autres conseils

Si vous utilisez Spring, vous pouvez utiliser l'espace réservé de propriété pour effectuer le travail.

<!-- try and resolve the config from the filesystem first and then fallback to the classpath -->
<context:property-placeholder location="file:config.properties, classpath:config.properties"
                              ignore-resource-not-found="true"/>

Vous pouvez spécifier une ressource sur le système de fichiers et également sur le chemin de classe. Spring essaiera d'abord de résoudre toutes les propriétés du système de fichiers puis de se replier sur le chemin de classe. En spécifiant l'option "ignore-resource-not-found" attribuer comme " vrai " cela empêchera Spring de lancer une exception si le fichier n'est pas présent sur le système de fichiers et lui permettra de résoudre les propriétés à partir du chemin d'accès aux classes.

Cette combinaison vous permet également de scinder les propriétés en deux fichiers. Par exemple, vous ne voudrez peut-être jamais spécifier de mots de passe dans le fichier sur le chemin d'accès aux classes et vous attendez à ce qu'ils soient spécifiés en externe sur le système de fichiers. Toute propriété manquante du système de fichiers sera résolue à partir du chemin de classe.

Dans un dossier contenant:

application.jar
config.properties

Vous devriez pouvoir utiliser:

java -jar application.jar

Ceci est un exemple de config.properties pour référence:

# This file contains properties that are used to configure the application
database.url=127.0.0.1
database.port=3306
database.user=root
database.pass=p4ssw0rd

Cela dépend. Si le fichier de propriétés contient des données destinées à être modifiées par l'utilisateur de votre application ou de votre bibliothèque, celles-ci doivent résider à l'extérieur.

S'il contient des données statiques et que vous avez créé les fichiers de propriétés pour éviter de coder les valeurs dans le code source ou si les fichiers sont des chaînes localisées, vous les laisseriez dans le fichier jar. Du moins parce qu’un fichier de propriétés invite les gens à changer de valeur;)

D.

Chargez les propriétés dans le jar. Créez ensuite une nouvelle propriété en utilisant les propriétés par défaut comme propriétés par défaut. Puis chargez de l'extérieur du pot. Cela permet de sélectionner la personnalisation des propriétés.

N'oubliez pas qu'en J2EE, il n'est PAS garanti que vous serez en mesure d'accéder aux fichiers en dehors de l'environnement J2EE (pas d'accès direct aux fichiers).

Vous devrez utiliser JNDI pour désigner une source de données contenant vos données ou un fichier de propriétés dans vos artefacts de déploiement.

Websphere, par exemple, n'autorise pas l'accès direct aux fichiers par défaut.

Option D. Dans différents environnements, vous devrez peut-être spécifier vouloir spécifier des propriétés environnementales telles que la connexion à la base de données ou à un proxy, etc.

.

Une autre chose à noter est qu’en production, vous souhaiterez peut-être modifier rapidement une propriété sans avoir à pré-emballer un fichier jar ou à remplacer le fichier de propriétés dans le fichier.

E.g. Le serveur de base de données est tombé et vous devez pointer vers un autre serveur (si vous n'utilisez pas un équilibreur de charge des bases de données). Il vous suffit donc de remplacer les propriétés de la base de données et de redémarrer. Vous gagnez beaucoup de temps là-bas.

Il est fréquent que le code soit migré UNCHANGED du test à la production. Cela implique que vous ne pouvez pas éditer les fichiers de configuration incorporés. Vous pouvez également vous retrouver dans une situation où vous devez modifier une configuration déployée, ce qui est souvent très fastidieux. Par conséquent, nous laissons la configuration à l’extérieur des pots.

Pour les applications Java EE, utilisez JNDI ou un fichier de propriétés dans le chemin d'accès aux classes.

J'ai une application Web dans laquelle la configuration est extraite d'une application Web voisine simplement pour séparer les deux. Cela s'est avéré être beaucoup plus facile.

J'utilise des fichiers de propriétés dans les applications Web (WAR), mais principalement pour les valeurs par défaut et les éléments plus ou moins immuables (car les applications Web ne doivent pas mettre à jour leurs fichiers WAR même lorsqu'ils le peuvent).

Pour des choses comme ce dont vous parlez, j’utilise JNDI. Vous pouvez définir les propriétés en tant que ressources dans votre fichier web.xml. Dans le pire des cas, vous mettez à jour web.xml et non l'application elle-même.

Pour certains serveurs, il existe des moyens de remplacer ces valeurs de ressource sans toucher au fichier WAR. Par exemple, dans Tomcat.

Normalement, je crée un fichier WAR à des fins de test, de Q / A et de production, et je remplace les ressources sensibles à l'environnement exactement de la même manière, à l'aide des fichiers XML Context de Tomcat. Je considère cela beaucoup mieux que de devoir créer plusieurs WAR ou modifier WARS, car l'application que je teste est presque identique à l'application en production.

Je pense que la réponse dépend de si vous pensez avoir besoin d'un contrôle de version pour les configs. (Il peut s'agir de configurations de production ou de configuration pour les tests de régression, etc.)

  • Si vous n'avez pas besoin de contrôle de version, l'option D avec un fichier de propriété externe qui remplace un fichier de propriété est un bon choix. Les options B et C sont plus ouvertes aux problèmes, mais si vous en teniez vraiment à vous, vous utiliseriez le contrôle de version: -)
  • Si vous avez besoin d'un contrôle de version, l'option A vous donne davantage de contrôle, mais si vous avez la possibilité de déployer plusieurs déploiements, vous voudrez peut-être / aurez besoin de contrôler les versions pour chaque déploiement. Un exemple en est des déploiements séparés sur des plates-formes de test et de production.

Voici comment procéder à l'aide de modules Maven et du fichier WAR Maven "overlays".

  1. Nous avons plusieurs modules pour les composants de code Java. Ce sont des modules JAR.
  2. Nous avons " base webapp " module pour le contenu statique, les JSP et les données de configuration de base (câblage Spring, propriétés par défaut). Il s’agit d’un module WAR. Le résultat de la construction est donc un fichier WAR qui contient ce qui précède + tous les fichiers JAR.
  3. Chaque "configuration de site" " distincte est un module WAR qui contient des substitutions spécifiques au site pour les propriétés, les fichiers de câblage et le contenu. Le remplacement est décrit à l'aide de Maven WAR "overlay". mécanisme, et résulte en un nouveau WAR assemblé à partir de la "base" WAR et les substitutions.

Tout cela est vérifié dans le contrôle de version, et vous devez effectuer une construction Maven et un déploiement WAR pour apporter des modifications à la configuration.

J'ai posé une question similaire. Nous n'avons pas encore tout compris. Mais nous examinons les ressources URL. Où le fichier de propriétés est lu directement à partir de SVN. Pas besoin de mettre à jour autre chose que le fichier de propriétés.

Je développe des applications J2EE à l’aide de Spring. Je parcourais le même problème assez longtemps avant de trouver une solution.  Mon problème était de spécifier les propriétés de la base de données dans un fichier de propriétés en dehors du fichier war que je déploie. La solution que j’ai trouvée consiste à utiliser le PropertyPlaceholderConfigurer et à spécifier la propriété d’emplacement pour localiser l’emplacement de votre système,

    

C’était assez simple et cela a bien fonctionné!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top