web-dev-qa-db-fra.com

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

Je rencontre des difficultés lorsque l'un des fichiers jar dont dépend mon application Web tente de charger un fichier de propriétés à partir de ce fichier. 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 mon répertoire "src/main/resources" du projet Maven. Lorsque j'exécute ce code à partir de mon test Junit dans Eclipse, il s'exécute parfaitement. 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 se trouve dans le répertoire de base de jar, cela dépend, je ne sais pas comment résoudre ce problème.

58
Andy

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

Cela fonctionne dans Eclipse car lors du lancement d'une application, le chargeur de classes système est configuré avec votre fichier jar dans le cadre de son chemin d'accès aux classes. (Par exemple, Java -jar, my.jar chargera my.jar dans le chargeur de classes du système.) Ce n'est pas le cas des applications Web: les serveurs d'applications utilisent un chargement de classe complexe pour isoler les applications Web les unes des autres. et à partir des composants internes du serveur d’application, par exemple, How-to du chargeur de classe Tomcat , ainsi que le diagramme de la hiérarchie du chargeur de classe utilisée.

EDIT: Normalement, vous appelez getClass().getResourceAsStream() pour récupérer une ressource dans le chemin de classe, mais lorsque vous extrayez la ressource dans un initialiseur statique, vous devez nommer explicitement une classe figurant dans le chargeur de classe que vous souhaitez utiliser. charge 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"));
  }
}
74
mdma

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

Pour ajouter des ressources au chemin de classe pour vos tests unitaires, vous suivez le même schéma que pour ajouter des ressources au fichier JAR, à l'exception du répertoire dans lequel vous placez les ressources est ${basedir}/src/test/resources. À ce stade, vous disposerez d'une structure de répertoire de projet ressemblant à 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 extrait de code simple, comme le suivant, pour accéder à la ressource requise pour le test:

...

// Retrieve resource
InputStream is = getClass().getResourceAsStream("/test.properties" );

// Do something with the resource

...
14
Pascal Thivent