2011-04-09 16 views
5

Estoy intentando cargar un recurso que está contenido en un archivo JAR incrustado. El proyecto se despliega en realidad JBoss mediante un archivo EAR con la siguiente estructura:Cómo cargar un recurso de un archivo JAR incrustado

deploy.ear 
| 
|-> project.sar 
    | 
    |-> sub_project.jar 
    | | 
    | |-> settings.xml 
    | 
    |-> com/path/project/ 
     | 
     |-> main.class 

De main.java me gustaría obtener una InputStream para settings.xml. ¿Cuál es la forma correcta de hacer esto?

Mi comprensión actual de que el siguiente código debería funcionar, pero está volviendo null:

this.getClass().getResourceAsStream("settings.xml"); 

actualización

Después de un poco de ensayo y error, las siguientes sentencias funcionan:

getClass().getResourceAsStream("/settings.xml"); 
getClass().getResourceAsStream("/sub_project.jar/settings.xml"); 
getClass().getClassLoader().getResourceAsStream("/settings.xml"); 
getClass().getClassLoader().getResourceAsStream("settings.xml"); 
getClass().getClassLoader().getResourceAsStream("sub_project.jar/settings.xml"); 
getClass().getClassLoader().getResourceAsStream("/sub_project.jar/settings.xml"); 
+0

el cargador de clases Java no puede cargar los recursos de los frascos incrustados, por lo que su puesta en marcha no lo hará trabajo. La única solución de jar resuelve este problema, vea la respuesta de Eran. – MeBigFatGuy

+1

No estoy seguro de que /sub_project.jar/settings.xml sea una notación estándar. Podría ser la extensión JBoss. –

+0

Me sorprendió por qué "settings.xml" falló, mientras "/settings.xml" funcionó, pero luego he leído la documentación: * si el nombre del recurso comienza con "/", no se modifica; de lo contrario, el nombre del paquete se antepone al nombre del recurso después de convertir "." a "/".* Class.class hace esto, pero ClassLoader.class no lo hace. Aprendí algo nuevo hoy ... –

Respuesta

2

Esto podría ser un buen recurso: http://one-jar.sourceforge.net/version-0.95/

La idea principal es que el JAR interno no está cargado por el cargador de clases que cargó el JAR externo automáticamente, debe hacerlo manualmente, p. mediante el uso de un StreamClassLoader para cargar el frasco interno Sólo

a continuación, a partir de su propio cargador de clases se puede conseguir que el recurso mediante getResourceAsStream(...)

+0

¿Está indicando usar One-Jar, o simplemente lo usa para una referencia sobre cómo acceder al contenido interno del contenedor? – cmcginty

+0

Tenga en cuenta que el superior no es JAR, sino EAR; lo que significa que tiene un cargador de clases más complejo que el estándar. Los cargadores de clases EAR manejan los recursos de carga de JAR y WAR anidados basados ​​en contenido META-INF. –

+2

@Vladimir: la pregunta original no decía eso. El OP dejó fuera ese detalle crucial en la pregunta original. Haga clic en el enlace 'edit [time]' debajo de la pregunta para más detalles. – BalusC

Cuestiones relacionadas