Skip to content
Advertisement

Reading resources inside dependency JAR gives NullPointerException

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.

Advertisement