简体   繁体   English

读取依赖 JAR 中的资源会产生 NullPointerException

[英]Reading resources inside dependency JAR gives NullPointerException

I have the following situation:我有以下情况:

  • JAR A has JAR B as dependency JAR A 有 JAR B 作为依赖
  • 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) JAR B 包含一些资源,这些资源在 JAR A 调用 JAR B 的特定方法时加载(在 JAR B 调用的整个生命周期内加载一次)
  • I am using Java SE 11 with IntelliJ 2021.1.3我在 IntelliJ 2021.1.3 中使用 Java SE 11

JAR B resources tree is something like the following: JAR B 资源树类似于以下内容:

 - 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 .然后通过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.使用 JAR B 项目运行mvn test (或应用程序测试)或在 Unix 环境中从 JAR A 使用 JAR B 时,一切正常。 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 :在 Windows 10 环境中从 JAR A 使用 JAR B 时, getPath方法返回一个空的InpuStream对象,因此来自BufferedReaderNullPointerException

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.我试图在方法中将File.separator更改为硬编码的“/”,似乎一切都在 Windows 上工作,但在其他地方(资源管理的地方)失败,因为我认为路径需要手动修复。

I tried to change the loader to: this.getClass().getResourcesAsStream(...) and other workaround with no luck.我试图将加载器更改为: this.getClass().getResourcesAsStream(...)和其他解决方法,但没有运气。

My question is: is there a way to make the program work as expected also on Windows without changing the above code?我的问题是:有没有办法让程序在 Windows 上也按预期工作,而无需更改上述代码? Are there any settings I am missing?有没有我遗漏的设置?

Thank you, Alberto谢谢你,阿尔贝托

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.事实是(现在也是)在 Windows 环境中使用File.separator来访问 JAR 中的资源。

This is because (as pointed here ) inside a JAR file paths are resolved UNIX-style.这是因为(指着这里)一个JAR文件路径都解决了UNIX风格里面。

The only way, then, to consume resources that are packed within a JAR file used as dependency is to specify resources paths UNIX-style.然后,使用打包在用作依赖项的 JAR 文件中的资源的唯一方法是指定 UNIX 样式的资源路径。

In my case, this mean replacing the File.separator (and all occurrences) with a "/".就我而言,这意味着用“/”替换File.separator (以及所有出现的)。

The other issues that were arising by this replacement were due to an incomplete replace-all of the File.separator directive across the code.此替换引起的其他问题是由于整个代码中File.separator指令的不完整替换。

java -classpath A.jar;B.jar x.y.z.Main

Would be what your command to run would look like on Windows.将是您要运行的命令在 Windows 上的样子。 Possibly better to use the absolute path to those jars for fail-proof ops使用这些罐子的绝对路径进行防故障操作可能更好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM