getResourceAsStream () siempre devuelve nulo

Tengo la siguiente estructura en una aplicación web Java:

TheProject -- [Web Pages] -- -- [WEB-INF] -- -- -- abc.txt -- -- index.jsp -- [Source Packages] -- -- [wservices] -- -- -- WS.java 

En WS.java , estoy usando el siguiente código en un método web:

 InputStream fstream = this.getClass().getResourceAsStream("abc.txt"); 

Pero siempre devuelve un nulo. Necesito leer de ese archivo, y leí que si coloca los archivos en WEB-INF , puede acceder a ellos con getResourceAsStream , pero el método siempre devuelve un null .

¿Alguna idea de lo que puedo estar haciendo mal?

Por cierto, lo extraño es que esto estaba funcionando, pero después de realizar un Clean and Build en el proyecto, de repente dejó de funcionar: /

Que yo sepa, el archivo debe estar en la carpeta donde reside la clase 'this' , es decir, no en WEB-INF/classes pero nested aún más profundamente (a menos que escriba en un paquete predeterminado):

 net/domain/pkg1/MyClass.java net/domain/pkg1/abc.txt 

Poner el archivo en sus fonts Java debería funcionar, el comstackdor copia ese archivo junto con los archivos de clase.

Una llamada a Class#getResourceAsStream(String) delega en el cargador de clases y el recurso se busca en la ruta de la clase. En otras palabras, su código actual no funcionará y deberá colocar abc.txt en WEB-INF/classes , o en WEB-INF/lib si está empaquetado en un archivo jar.

O use ServletContext.getResourceAsStream(String) que permite que los contenedores de servlets hagan que un recurso esté disponible para un servlet desde cualquier ubicación, sin usar un cargador de clases . Entonces usa esto desde un Servlet:

 this.getServletContext().getResourceAsStream("/WEB-INF/abc.txt") ; 

Pero, ¿hay alguna manera de llamar a getServletContext desde mi servicio web?

Si está utilizando JAX-WS, puede obtener un WebServiceContext inyectado:

 @Resource private WebServiceContext wsContext; 

Y luego obtenga el ServletContext de él:

 ServletContext sContext= wsContext.getMessageContext() .get(MessageContext.SERVLET_CONTEXT)); 

En lugar de

 InputStream fstream = this.getClass().getResourceAsStream("abc.txt"); 

utilizar

 InputStream fstream = this.getClass().getClassLoader().getResourceAsStream("abc.txt"); 

De esta forma, mirará desde la raíz, no desde la ruta de la clase invocadora actual.

Creo que de esta manera puede obtener el archivo desde “cualquier lugar” (incluidas las ubicaciones de los servidores) y no necesita preocuparse por dónde ubicarlo.

Por lo general, es una mala práctica tener que preocuparse por tales cosas.

 Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties"); 

No sé si esto se aplica a JAX-WS, pero para JAX-RS pude acceder a un archivo inyectando un ServletContext y luego llamando a getResourceAsStream () sobre él:

 @Context ServletContext servletContext; ... InputStream is = servletContext.getResourceAsStream("/WEB-INF/test_model.js"); 

Tenga en cuenta que, al menos en GlassFish 3.1, la ruta debe ser absoluta, es decir, comenzar con barra inclinada. Más aquí: ¿Cómo uso un archivo de propiedades con jax-rs?

Tuve el mismo problema cuando cambié de Websphere 8.5 a WebSphere Liberty.

Utilicé FileInputStream lugar de getResourceAsStream() , porque por alguna razón WebSphere Liberty no puede ubicar el archivo en la carpeta WEB-INF .

El guión fue:

 FileInputStream fis = new FileInputStream(getServletContext().getRealPath("/") + "\WEBINF\properties\myProperties.properties") 

Nota: utilicé este script solo para el desarrollo.

Tuve un problema similar y busqué la solución por bastante tiempo: parece que el parámetro de cadena distingue entre mayúsculas y minúsculas. Entonces, si su nombre de archivo es abc.TXT pero busca abc.txt, eclipse lo encontrará; el archivo ejecutable JAR no lo hará.