I have the following situation:
- JAR A has JAR B as dependency
- JAR B is packed with some resources that are loaded when JAR A calls specific methods of JAR B (loaded once and for all the lifecycle of JAR B calls)
- I am using Java SE 11 with IntelliJ 2021.1.3
JAR B resources tree is something like the following:
- resources
- data
- file.txt
- tariffs
- folder1
- file.xslx
Resources are loaded through the following method:
private InputStream getPath(String nomeFile) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return classLoader.getResourceAsStream(DATA_FOLDER_NAME.concat(File.separator).concat(nomeFile));
}
And then managed through a BufferedReader
.
Everything works fine when running mvn test
(or application tests) withing JAR B project or when consuming JAR B from JAR A in a Unix environment.
When consuming JAR B from JAR A in a Windows 10 environment the getPath
method returns a null InpuStream
object thus a NullPointerException
from the BufferedReader
:
java.lang.NullPointerException: null
at java.base/java.io.Reader.<init>(Reader.java:167)
at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:72)
I tried to change the File.separator
to hardcoded “/” in the method and seems like everything works also on Windows, but is failing in other places (where resources are managed) since I suppose Paths need to be hand-fixed.
I tried to change the loader to: this.getClass().getResourcesAsStream(...)
and other workaround with no luck.
My question is: is there a way to make the program work as expected also on Windows without changing the above code? Are there any settings I am missing?
Thank you, Alberto
Advertisement
Answer
Just came over this issue.
The fact was (and is) the usage of File.separator
in a Windows environment to access resources inside a JAR.
This is because (as pointed here) inside a JAR file paths are resolved UNIX-style.
The only way, then, to consume resources that are packed within a JAR file used as dependency is to specify resources paths UNIX-style.
In my case, this mean replacing the File.separator
(and all occurrences) with a “/”.
The other issues that were arising by this replacement were due to an incomplete replace-all of the File.separator
directive across the code.