我有一个包含多个模块的项目。在一个模块(A)中,我试图访问另一个模块(B)的资源。模块B被定义为模块A中的依赖项。
我写了一些测试,检查我是否可以访问这些文件。当我在IntelliJ中运行测试时,一切都过去了。当我运行mvn test
时,一切正常。当我运行mvn install
或mvn package
时,相同的测试无法通过,并且构建失败。
在模块A中,我尝试按如下方式访问资源:
ClassOfModuleB.class.getResource("/fileOfModuleB").getFile()
我在此处列出了一些问题:Java: How to read file from different module? 在这里:How to really read text file from classpath in Java
我尝试了所有组合,但是,每次测试通过IntelliJ / mvn测试并且它不会通过mvn install / mvn包。
答案 0 :(得分:0)
正如khmarbaise已经指出的那样,这个应用程序的设计完全搞砸了。我找到了一个丑陋的解决方法,但它使事情有效并且经过了充分的测试。
主要问题是,不同的模块需要访问相同的文件。不幸的是,由于第三方库需要实际的文件句柄,所以文件不能作为流处理(这会使事情变得容易很多)。收到这个(.getFile()
)是Tunaki所说的问题。它在mvn test
中工作的原因是,这些测试在应用程序打包之前运行。通过观察.getResource()
的路径,当它被打包时显示对jar://
的更改,这使得无法获得实际的文件句柄,因为不再有文件。但是,可以接收InputStreams。
解决方法很简单: 接收文件作为输入流,在应用程序启动后将它们写入临时目录。
private File copyResourceIntoTempFile(String resource, File target) throws IOException {
InputStream input = getClass().getResourceAsStream(resource);
OutputStream out = new FileOutputStream(target);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
//target.deleteOnExit();
if (!target.exists()) {
throw new FileNotFoundException("Error: File " + target + " not found!");
}
return target;
}
也可以迭代目录的文件:
InputStream in = this.getClass().getResourceAsStream(resource);
BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = rdr.readLine()) != null) {
this.copyResourceIntoTempFile(resource+"/"+line, new File(dir, line));
}
rdr.close();
我知道这是迄今为止最好的解决方案。但是,启动该项目的人的解决方案是确保某些文件在应用程序运行的任何地方(手动)都在目录中。经过一些繁琐的部署应用程序的工作后,它被重构为下载所需的文件并解压缩它们,这是永远的。