Hay diferencias sutiles en cuanto a cómo fileName
se interpreta lo que está pasando. Básicamente, tiene 2 métodos diferentes: ClassLoader.getResourceAsStream()
y Class.getResourceAsStream()
. Estos dos métodos ubicarán el recurso de manera diferente.
En Class.getResourceAsStream(path)
, la ruta se interpreta como una ruta local al paquete de la clase desde la que lo está llamando. Por ejemplo vocación, String.getResourceAsStream("myfile.txt")
buscará un archivo en la ruta de clases en la siguiente dirección: "java/lang/myfile.txt"
. Si su ruta comienza con a /
, se considerará una ruta absoluta y comenzará a buscar desde la raíz de la ruta de clase. Por lo tanto, al llamar String.getResourceAsStream("/myfile.txt")
verá la siguiente ubicación en su ruta de clase ./myfile.txt
.
ClassLoader.getResourceAsStream(path)
considerará todas las rutas como rutas absolutas. Así que llamar String.getClassLoader().getResourceAsStream("myfile.txt")
y String.getClassLoader().getResourceAsStream("/myfile.txt")
lo hará tanto buscar un archivo en la ruta de clases en la siguiente dirección: ./myfile.txt
.
Cada vez que menciono una ubicación en esta publicación, podría ser una ubicación en su propio sistema de archivos, o dentro del archivo jar correspondiente, dependiendo de la Clase y / o el Cargador de clases desde el que está cargando el recurso.
En su caso, está cargando la clase desde un Servidor de aplicaciones, por lo que debe usarla en Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)
lugar de this.getClass().getClassLoader().getResourceAsStream(fileName)
. this.getClass().getResourceAsStream()
También funcionará.
Lea este artículo para obtener información más detallada sobre ese problema en particular.
Advertencia para usuarios de Tomcat 7 y versiones inferiores
Una de las respuestas a esta pregunta dice que mi explicación parece ser incorrecta para Tomcat 7. He intentado mirar a mi alrededor para ver por qué ese sería el caso.
Así que he visto el código fuente de Tomcat WebAppClassLoader
para varias versiones de Tomcat. La implementación de findResource(String name)
(que es totalmente responsable de producir la URL del recurso solicitado) es prácticamente idéntica en Tomcat 6 y Tomcat 7, pero es diferente en Tomcat 8.
En las versiones 6 y 7, la implementación no intenta normalizar el nombre del recurso. Esto significa que en estas versiones, classLoader.getResourceAsStream("/resource.txt")
puede que no produzca el mismo resultado que el classLoader.getResourceAsStream("resource.txt")
evento aunque debería (ya que eso es lo que especifica el Javadoc). [código fuente]
Sin embargo, en la versión 8, el nombre del recurso se normaliza para garantizar que la versión absoluta del nombre del recurso es la que se utiliza. Por lo tanto, en Tomcat 8, las dos llamadas descritas anteriormente siempre deben devolver el mismo resultado. [código fuente]
Como resultado, debe tener mucho cuidado al usar ClassLoader.getResourceAsStream()
o Class.getResourceAsStream()
en versiones de Tomcat anteriores a 8. Y también debe tener en cuenta que class.getResourceAsStream("/resource.txt")
realmente llama classLoader.getResourceAsStream("resource.txt")
( /
se despoja el inicio).
getClass().getResourceAsStream("/myfile.txt")
comporta de manera diferentegetClassLoader().getResourceAsStream("/myfile.txt")
.