Charger la ressource de n’importe où dans classpath

J’ai une application Java simple qui charge un fichier de propriétés à partir du package actuel.

this.getClass().getResourceAsStream("props.properties"); 

Cela fonctionne correctement lorsque le fichier de propriétés souhaité se trouve dans le package en cours. Toutefois, je souhaite créer un package de cette application en tant que JAR, définir et remplacer un nouveau fichier de propriétés dans lequel je l’utilise. Existe-t-il un moyen de charger la première ressource nommée “props.properties” située sur le chemin de classe?

Je veux qu’il soit aussi facile de remplacer le fichier de propriétés via la ligne de commande:

 java.exe -classpath props.properties;myJar.jar com.test.MyApp 

Je ne veux pas avoir à décompresser le fichier JAR et modifier le fichier de propriétés pour changer quelque chose. J’ai l’impression qu’il me manque quelque chose d’évident …

Si tout échoue, vous pouvez utiliser deux noms de fichier différents, par exemple props-default.properties dans myJar.jar et props.properties pour remplacer la ligne de commande. Dans votre code, essayez de charger le fichier props.properties en premier, puis de props-default.properties sur props-default.properties s’il n’a pas été trouvé.

Le javadoc de Class.getResourceAsStream() documente la logique de recherche:

Si le nom commence par un '/' ( '\u002f' ), le nom absolu de la ressource est la partie du nom qui suit le ‘/’.

Sinon, le nom absolu est de la forme suivante:
modified_package_name/name

modified_package_name est le nom de package de cet object avec ‘/’ substitué à '.' ( '\u002e' ).

En d’autres termes, le nom de la ressource transmis à la méthode devrait alors ressembler à /com/package/p2/props.properties si props.properties est stocké dans le package com.package.p2 au lieu de celui de la classe actuelle.

Je suis sûr que c’est trop tard pour la réponse, mais cela pourrait être intéressant pour les googleurs, ce petit code d’aide permettant de charger un fichier de propriétés à partir de n’importe où dans le classpath.

 ClassLoader cl = ClassLoader.getSystemClassLoader(); if (cl != null) { URL url = cl.getResource(CONF_PROPERTIES); if (url == null) { url = cl.getResource("/" + CONF_PROPERTIES); } if (url != null) { try { InputStream in = url.openStream(); props = new Properties(); props.load(in); } catch (IOException e) { // Log the exception } finally { // close opened resources } } } 

Je ne suis pas sûr, mais peut-être: ClassLoader.getResourceAsStream()

MODIFIER:

Je ne pense pas que cela soit significativement différent de this.getClass().getResourceAsStream() de la question, car, comme cela a été mentionné, vous devez toujours obtenir le ClassLoader que vous souhaitez utiliser pour charger la ressource.

Puisque vous fournissez la ressource dans le -classpath dans votre exemple, elle devrait être disponible à partir du même chargeur de classe que votre classe “main” (dans la machine sun.misc.Launcher$AppClassLoader SUN, il s’agit de sun.misc.Launcher$AppClassLoader , ne sun.misc.Launcher$AppClassLoader pas si cela peut / peut le faire. varie pour les autres implémentations JVM).