I dockerized my Spring Boot App. There is a piece of code that loads a bin file (eg, my-bin-file.bin) and build a model out of it. Whenever I run the standalone app (through run on IntelliJ) it can find the file and build the model. However, when I run it through the Dockerfile, it can't find it and fails.
Dockerfile
WORKDIR /app
COPY target/services-*.war /app/services.war
CMD ["java", "-jar", "services.war"]
File Resource
root
|-- src
|-- java
|-- packages and java files
|-- resource
|-- binFolder
|-- my-bin-file.bin
Bin Loader
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
...
}
}
}
I checked the war file, and it's packaged in there in the expected path. It's inside /WEB-INF/classes/binFolder/my-bin-file.bin
The InputStream fails with NullException.
I wonder what I'm doing wrong. Any pointers would be much appreciated. Thanks.
The problem is the use of the
FileInputStream. It will use ajava.io.Fileto try to read the referenced resource, however ajava.io.Fileexpects the referenced resource to be an actual file on a file system. This is the case when you are running from Intellij but not when you are running from a jar or war.To fix utilize Spring to load the resource from you from the classpath and obtain the
InputStream. To make it easier you can use theClassPathResourceto directly access it. This will work in both cases, running from Intellij and as jar/war.