Charger le fichier de propriétés dans JAR?

J’ai des problèmes lorsque l’un des jars dont mon application Web dépend dépend de charger un fichier de propriétés depuis le fichier jar. Voici le code dans le pot.

static { Properties props = new Properties(); try { props.load(ClassLoader.getSystemResourceAsStream("someProps.properties")); } catch (IOException e) { e.printStackTrace(); } someProperty = props.getProperty("someKey"); } 

Le fichier de propriétés se trouve dans le répertoire “src / main / resources” du projet Maven. Lorsque je lance ce code depuis mon test de junit dans Eclipse, il s’exécute correctement. Lorsque le projet est créé avec Maven dans un fichier jar et inclus en tant que dépendance dans mon application Web, il ne parvient pas à localiser le fichier de propriétés. Je sais que le fichier de propriétés est dans le répertoire de base du jar dépendant, je ne sais pas comment résoudre ce problème.

Le problème est que vous utilisez getSystemResourceAsStream . Utilisez simplement getResourceAsStream . Les ressources système se chargent depuis le classloader du système, ce qui n’est certainement pas le chargeur de classe dans lequel votre fichier jar est chargé lorsqu’il est exécuté en tant qu’application Web.

Il fonctionne dans Eclipse car lors du lancement d’une application, le classloader du système est configuré avec votre jar dans le cadre de son classpath. (Par exemple, java -jar my.jar chargera my.jar dans le chargeur de classe système.) Ce n’est pas le cas avec les applications Web – les serveurs d’applications utilisent un chargement de classe complexe pour isoler les applications Web les unes des autres et des composants internes du serveur d’applications. Par exemple, consultez le tutoriel sur le chargeur de classe tomcat et le diagramme de la hiérarchie du chargeur de classes utilisé.

EDIT: Normalement, vous appelez getClass().getResourceAsStream() pour récupérer une ressource dans le classpath, mais comme vous récupérez la ressource dans un initialiseur statique, vous devez explicitement nommer une classe qui se trouve dans le chargeur de classes que vous voulez charger à partir de. L’approche la plus simple consiste à utiliser la classe contenant l’initialiseur statique, par exemple

 [public] class MyClass { static { ... props.load(MyClass.class.getResourceAsStream("/someProps.properties")); } } 

Pour mémoire, ceci est documenté dans Comment append des ressources à mon JAR? (illustré pour les tests unitaires mais il en va de même pour une ressource “régulière”):

Pour append des ressources au classpath pour vos tests unitaires, vous suivez le même schéma que pour l’ajout de ressources au JAR, à l’exception du répertoire dans ${basedir}/src/test/resources vous placez les ressources: ${basedir}/src/test/resources . À ce stade, vous auriez une structure de répertoire de projet qui ressemblerait à ceci:

 my-app |-- pom.xml `-- src |-- main | |-- java | | `-- com | | `-- mycompany | | `-- app | | `-- App.java | `-- resources | `-- META-INF | |-- application.properties `-- test |-- java | `-- com | `-- mycompany | `-- app | `-- AppTest.java `-- resources `-- test.properties 

Dans un test unitaire, vous pouvez utiliser un simple extrait de code comme celui-ci pour accéder à la ressource requirejse pour le test:

 ... // Resortingeve resource InputStream is = getClass().getResourceAsStream("/test.properties" ); // Do something with the resource ...