Cargar archivo de propiedades en JAR?

Tengo problemas cuando una de las jarras de la que depende mi aplicación web intenta cargar un archivo de propiedades desde el contenedor. Aquí está el código en el contenedor.

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

El archivo de propiedades está en mi directorio “src / main / resources” del proyecto Maven. Cuando ejecuto este código desde mi prueba junit en Eclipse, se ejecuta muy bien. Cuando el proyecto se construye con Maven en un jar, y se incluye como una dependencia en mi aplicación web, no puede encontrar el archivo de propiedades. Sé que el archivo de propiedades está en el directorio base del jar dependido, no sé cómo solucionarlo.

El problema es que estás usando getSystemResourceAsStream . Use simplemente getResourceAsStream . Los recursos del sistema se cargan desde el cargador de clases del sistema, que es casi seguro que no es el cargador de clases en el que se carga su jar cuando se ejecuta como una aplicación web.

Funciona en Eclipse porque al iniciar una aplicación, el cargador de clases del sistema se configura con su jar como parte de su classpath. (Por ejemplo, java -jar my.jar cargará my.jar en el cargador de clases del sistema). Este no es el caso con las aplicaciones web: los servidores de aplicaciones usan una carga de clase compleja para aislar las aplicaciones de aplicaciones entre sí y desde el interno del servidor de aplicaciones. Por ejemplo, vea el tutorial de tomcat classloader , y el diagtwig de la jerarquía del cargador de clases utilizado.

EDITAR: Normalmente, debe llamar a getClass().getResourceAsStream() para recuperar un recurso en la ruta de clases, pero como va a buscar el recurso en un inicializador estático, tendrá que nombrar explícitamente una clase que esté en el cargador de clases que desea cargar desde. El enfoque más simple es usar la clase que contiene el inicializador estático, por ej.

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

Para el registro, esto está documentado en ¿Cómo agrego recursos a mi JAR? (ilustrado para pruebas unitarias pero lo mismo aplica para un recurso “regular”):

Para agregar recursos al classpath para las pruebas de su unidad, siga el mismo patrón que para agregar recursos al JAR, excepto que el directorio en el que coloca los recursos es ${basedir}/src/test/resources . En este punto, usted tendría una estructura de directorio de proyecto que se vería así:

 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 

En una prueba unitaria, puede usar un fragmento de código simple como el siguiente para acceder al recurso requerido para la prueba:

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