I have a method where I need to read a resource file and pass it to another method as an InputStream. The obvious approach
InputStream is = classLoader.getResourceAsStream("filename.pem");
works fine when actually running the application, but in testing it returns an empty InputStream (filled with zeros). I don't think its a problem with the resource path or anything, because when I use a nonsense path like "filex"
(filex does not exist), I get an actual null pointer exception and not an empty stream. Also in debugger the complete file path of the empty Stream points to the correct path, where the file actually is stored (default class root).
Furthermore, with the following workaround it works:
File file = new File(classLoader.getResource("filename.pem").getFile());
String fileS= new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
InputStream is = classLoader.getResourceAsStream("filename.pem");
InputStream is2 = new ByteArrayInputStream(fileS.getBytes(StandardCharsets.UTF_8));
In this example is2
has the actual content of the file in the InputStream, while is
has an Stream filled with zeros. I can't quite explain that behaviour. I double checked with 'getClass().getClassLoader().getClass()' if we use some modified ClassLoader in the Application, but it is the original one from sun.misc.Launcher$AppClassLoader
.
So my questions are:
- Why does the workaround work but not the classic approach?
- Why does it fail only in test class?
- Is there a way to make it work? The workaround is more lines of code and also need to catch IOException because of the
Files.readAllBytes()
call.
The only idea I had left: the encoding or charset has something to do with it. But to my knowledge there is no parameter in getResourceAsStream()
like Charset
or StandardCharsets
.