I have a Spring Boot backend application which has following part in the application.properties:
token.json_file_url=${TOKEN_JSON_FILE_URL:file:src/main/resources/localdev/user-claims.json}
${TOKEN_JSON_FILE_URL} env variable is not set, so the default file:src/main/… is in effect.
In a bundled library it’s used like this when a REST call is made:
@Value("${token.json_file_url}")
private String userClaimsTokenJsonFileUrl;
...
ObjectMapper objectMapper = new ObjectMapper(); //Jackson
Map<String, Object> map =
objectMapper.readValue(new URL(this.userClaimsTokenJsonFileUrl), new TypeReference<Map<String, Object>>() {});
Now executing the fat-jar generated by spring-boot-maven plugin runs perfectly fine in console via java -jar the-app.jar.
But copying the same jar into a docker container and firing a REST call against that yields a
java.io.FileNotFoundException: src/main/resources/localdev/user-claims.json.
How can that be?
To be complete, here’s the Dockerfile:
FROM amazoncorretto:17-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app/the-app.jar
WORKDIR /app
EXPOSE 8080
CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "the-app.jar"]
I also extracted the jar inside the container and the structure is:
BOOT-INF/classes/localdev/user-claims.json
It’s there. It just can’t be found running in a Docker container as opposed to running my jar locally.
Any ideas?
2
Answers
OK so actually the problem was much more stupid than I realised...
I was executing the JAR from my root project directory. Like java -jar target/the-app.jar.
What I didn't realize was that the path root/src/main/resources/localdev/... was available to the code running in the jar... It was not using the packed resources INSIDE the jar, but the external files...
That's why the
worked for the jar, while of course in the Docker container, this path wasn't there.
Again, my mistake was that I thought the JAR used the resources packed inside the JAR, which it did not!
Fixed it by copying the files also into the Docker container.
Project Tree
Test JSON
token-001.json
token-002.json
token-003.json
pom.xml
application.properties
logback.xml
DemoApplication.java
HelloController.java
Dockerfile
Build and Run
Build
Run
Terminal-1
Test-1
Terminal-2
check Terminal-1 console output
App read jar file’s token-001.json success.(Read file from classpath resource)
In Terminal-1 , Ctrl + C , Stop App.
Test-2 Set Environment
Terminal-1
Terminal-2
check Terminal-1 console output
App read token-002.json success.(Read file from Environment Config)
In Terminal-1 , Ctrl + C , Stop App.
Build Docker Container
Docker Test-1
Terminal-1
Terminal-2
check Terminal-1 console output
App read jar file’s token-001.json success.(Read file from classpath resource)
In Terminal-1 , Ctrl + C , Stop App.
Docker Test-2 Set Environment
Terminal-1
Terminal-2
check Terminal-1 console output
App read token-003.json success.(Read file from Environment Config)
In Terminal-1 , Ctrl + C , Stop App.
Another Solution About Read File
I did not use the following writing method. The following writing method may be what you want:
application.properties