我对我的 Spring Boot 应用程序进行了 docker 化。有一段代码加载 bin 文件(例如 my-bin-file.bin)并从中构建模型。每当我运行独立应用程序(通过在 IntelliJ 上运行)时,它都可以找到该文件并构建模型。但是,当我通过 Dockerfile 运行它时,它找不到它并失败。
Dockerfile
WORKDIR /app
COPY target/services-*.war /app/services.war
CMD ["java", "-jar", "services.war"]
文件资源
root
|-- src
|-- java
|-- packages and java files
|-- resource
|-- binFolder
|-- my-bin-file.bin
装箱机
public class BinLoader {
public static String[] loadBinFile() throws IOException {
String folder = BinLoader.class.getClassLoader().getResource("binFolder").getFile();
try (InputStream inputStream = new FileInputStream(folder + "my-bin-file.bin")) {
// build model
...
}
}
}
我检查了war文件,它被打包在预期的路径中。就在里面
/WEB-INF/classes/binFolder/my-bin-file.bin
InputStream 失败,并显示
NullException
。
我想知道我做错了什么。任何指示将不胜感激。谢谢。
问题在于
FileInputStream
的使用。它将使用 java.io.File
尝试读取引用的资源,但是 java.io.File
期望引用的资源是文件系统上的实际文件。当您从 Intellij 运行时会出现这种情况,但当您从 jar 或 war 运行时则不会。
要修复此问题,请使用 Spring 从类路径加载资源并获取
InputStream
。为了方便起见,您可以使用 ClassPathResource
直接访问它。这在两种情况下都有效,从 Intellij 运行并作为 jar/war 运行。
public static String[] loadBinFile() throws IOException {
String resource = "/binFolder/my-bin-file.bin";
try (InputStream inputStream = new ClassPathResource(resource).getInputStream()) {
// build model
...
}
}