Existem diferenças sutis no modo como o que fileNamevocê está passando é interpretado. Basicamente, você tem 2 métodos diferentes: ClassLoader.getResourceAsStream()eClass.getResourceAsStream() . Esses dois métodos localizarão o recurso de maneira diferente.
Em Class.getResourceAsStream(path), o caminho é interpretado como um caminho local para o pacote da classe da qual você está chamando. Por exemplo chamada, String.getResourceAsStream("myfile.txt")irá procurar um arquivo no seu classpath, no seguinte local: "java/lang/myfile.txt". Se o seu caminho começar com a /, será considerado um caminho absoluto e começará a pesquisar a partir da raiz do caminho de classe. Assim, a chamada String.getResourceAsStream("/myfile.txt")examinará o seguinte local no caminho da sua classe ./myfile.txt.
ClassLoader.getResourceAsStream(path)considerará todos os caminhos como absolutos. Então, chamando String.getClassLoader().getResourceAsStream("myfile.txt")e String.getClassLoader().getResourceAsStream("/myfile.txt")ambos procurarão um arquivo no seu caminho de classe no seguinte local:./myfile.txt .
Toda vez que eu menciono um local neste post, ele pode ser um local no seu próprio sistema de arquivos ou dentro do arquivo jar correspondente, dependendo da Class e / ou ClassLoader da qual você está carregando o recurso.
No seu caso, você está carregando a classe de um servidor de aplicativos, portanto, você deve usar em Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)vez de this.getClass().getClassLoader().getResourceAsStream(fileName). this.getClass().getResourceAsStream()também irá funcionar.
Leia este artigo para obter informações mais detalhadas sobre esse problema específico.
Aviso para usuários do Tomcat 7 e abaixo
Uma das respostas a esta pergunta afirma que minha explicação parece incorreta para o Tomcat 7. Tentei procurar ao redor para ver por que esse seria o caso.
Então, eu olhei o código fonte do Tomcat WebAppClassLoaderpara várias versões do Tomcat. A implementação de findResource(String name)(que é totalmente responsável por produzir a URL para o recurso solicitado) é praticamente idêntica no Tomcat 6 e no Tomcat 7, mas é diferente no Tomcat 8.
Nas versões 6 e 7, a implementação não tenta normalizar o nome do recurso. Isso significa que nessas versões, classLoader.getResourceAsStream("/resource.txt")pode não produzir o mesmo resultado que o classLoader.getResourceAsStream("resource.txt")evento que deveria (desde que o Javadoc especifique). [Código fonte]
Na versão 8, porém, o nome do recurso é normalizado para garantir que a versão absoluta do nome do recurso seja a usada. Portanto, no Tomcat 8, as duas chamadas descritas acima sempre devem retornar o mesmo resultado. [Código fonte]
Como resultado, você deve ter um cuidado extra ao usar ClassLoader.getResourceAsStream()ou Class.getResourceAsStream()nas versões do Tomcat anteriores a 8. E você também deve ter em mente que, class.getResourceAsStream("/resource.txt")na verdade, chama classLoader.getResourceAsStream("resource.txt")(o líder /é removido).
getClass().getResourceAsStream("/myfile.txt")se comporta de maneira diferentegetClassLoader().getResourceAsStream("/myfile.txt").