我有以下情况:
- JAR A有JAR B作为依赖
- JAR B包含一些资源,这些资源是在JAR A调用JAR B的特定方法时加载的(在JAR B调用的整个生命周期中加载一次)
- 我使用Java SE 11与IntelliJ 2021.1.3
JAR B的资源树如下:
- resources
- data
- file.txt
- tariffs
- folder1
- file.xslx
资源通过以下方式加载:
private InputStream getPath(String nomeFile) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return classLoader.getResourceAsStream(DATA_FOLDER_NAME.concat(File.separator).concat(nomeFile));
}
然后通过BufferedReader
管理。
在JAR B项目中运行mvn test
(或应用程序测试)或在Unix环境中从JAR A消费JAR B时,一切都工作正常。当在Windows 10环境中从JAR A中消费JAR B时,getPath
方法返回一个空的InpuStream
对象,因此从BufferedReader
中返回一个NullPointerException
:
java.lang.NullPointerException: null
at java.base/java.io.Reader.<init>(Reader.java:167)
at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:72)
...
我试图将File.separator
更改为硬编码"/"在方法中,似乎一切都适用于Windows,但在其他地方(资源管理的地方)失败,因为我认为路径需要手工修复。
我试图将加载器更改为:this.getClass().getResourcesAsStream(...)
和其他解决方案,但没有运气。
我的问题是:有没有一种方法,使程序工作如预期也在Windows上不改变上述代码?我是否缺少任何设置?
谢谢你,阿尔贝托。
刚刚讨论过这个问题。事实是(现在也是)在Windows环境中使用File.separator
访问JAR中的资源。
这是因为(正如这里所指出的)在JAR文件中路径是用unix方式解析的。
那么,使用作为依赖项的JAR文件中打包的资源的唯一方法是以unix风格指定资源路径。
在我的例子中,这意味着用"/"替换File.separator
(和所有出现的)。
这个替换引起的其他问题是由于一个不完整的替换——整个代码中的所有File.separator
指令。
java -classpath A.jar;B.jar x.y.z.Main
将是你的命令在Windows上运行的样子。可能最好使用这些jar的绝对路径来防止故障