I'm trying to run a java8 app using spring boot version 2.2.4. The app is then packed in a docker image.
The way I run my app as specified in a Dockerfile which ends liek this:
FROM openjdk:8
.....
CMD /usr/local/openjdk-8/bin/java -jar -Dspring.config.location=/opt/$APP/ /opt/$APP/$APP.jar
The problem I encounter is the loading of external properties files. For example I have application.properties file similar to this, which is packaed inside the JAR :
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=db1
application.queue.sqs.queue_name=somesqs
In addition, I also inject the docker image an addition application.properties
file located at /opt/myapp/
. This external file is similar to this:
spring.data.mongodb.uri=mongodb://username:password@MONGO_URL:27017/db_name
application.queue.sqs.queue_name=another_sqs
Expected Behavior : the app will load both new another_sqs
location, and external mongo connection.
However, Actual Behavior : when reading the logs I can see that t the new sqs url (ie another_sqs) is loaded properly, although the new value for mongo connection is discarded and is therefore using the local embedded mongo engine.
I consulted the following post on stackoverflow to try and understand what I am experiencing:
But for my understanding, when using spring 2.X and above, the -Dspring.config.location should override all other properties file.
Here is where I started debugging:
TRY 1: I attached into the docker container, cd into /opt/$APP/
where both my app.jar
and application.properties
are located, executed the following command java -jar app.jar
and viola - it works . A connection to the external mongo source is established. This may be explained by the priority of spring loading properties files as specified in spring's docs .
TRY 2: Attach the container, cd into $HOME/
, execute java -jar /opt/$APP/app.jar -Dspring.config.location=/opt/$APP/
- Do not connect to external mongo, however does connects to the another_sqs
. Strange thing - only part of the application.properties
values are loaded? Isn't it the way spring 1.X works by adding value from multiple files?
TRY 3: Attach the container, cd into $HOME/
, execute java -jar /opt/$APP/app.jar -Dspring.config.location=file:/opt/$APP/applicartion.properties
- same behavior.
Try 4: Edited Dockerfile to include the following execution:
CMD usr/local/openjdk-8/bin/java -jar -Dspring.config.location=classpath:/application.properties,file:/opt/$APP/application.properties /opt/$APP/$APP-$VER.jar
And it works again . Both another_sqs
and external mongo are loaded properly on "Try 4".
My question is therefore:
Why should I explicitly specify the classpath:/application.proeprties
? Isn't -Dspring.config.location=/opt/$APP/
or -Dspring.config.location=file:/opt/$APP/application.properties
should be enough?
When you specify -Dspring.config.location=file:/opt/$APP/application.properties
you're overriding the default value of config.location with your application.properties. If you want to use another application.properties, but still using the default properties without declaring them you should use
-Dspring.config.additional-location=file:/opt/$APP/application.properties
In this way, config.location will still have the default value and you will load the external properties as an additional-location.
From the Spring Documentation :
You can also refer to an explicit location by using the
spring.config.location
environment property (which is a comma-separated list of directory locations or file paths). When custom config locations are configured byusing spring.config.location
, they replace the default locationsAlternatively, when custom config locations are configured by using
spring.config.additional-location
, they are used in addition to the default locations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.