I would like Spring Boot to take the servlet context path into consideration when determining the externalized configuration location in web applications.
Applicability (failure scenario)
I haven't yet made a demo project, but I am extremely confident that externalized configuration may not work well in the following scenario.
If the Spring Boot application is deployed on the same web server (e.g. Tomcat, WebSphere) in WAR format along with other Spring Boot-based applications, or multiple instances of the same application, the -Dspring.config.location
property can define a single location where all applications will fetch their application.yml
(.properties
) files.
Not all people run Spring Boot applications on dedicated application servers, or using the embedded web server on a container instance. Multiple organizations (despite bad) run multiple environments of the same application in multiple context paths, e.g. https://host/myapp-dev
, https://host/myapp-stage
, https://host/myapp
(prod).
Or there are likely cases where the same server hosts /appA
and /appB
where both are Spring Boot-based but do things completely different.
The sysadmin is likely to configure a single -Dspring.config.location
for the whole server, but indeed two applications instances need different configuration each other. They are uniquely identified by the context path.
Past experience
In my former company, all our applications were Spring-based (not Boot) and we had the very same problem of deploying different apps to the same server, even in production. So back in 2014 we invented -Dour.config.location
that thanks to the ServletContextInitializer
basically created a property source ${our.config.location}/${context.path}/*.properties
.
To be particularly clear, once we set -Dour.config.location=/opt/acme
on web server, directories /opt/acme/appA
served externalized configuration to appA
only.
Of course, this doesn't apply to stand-alone (e.g. started with java -jar
command) applications. And applications that don't run in a shared web server
Creating a POC project
I don't have enough free time according to my existing contributions, but I'll be glad to create a demo project by June 2021 if you are interested.
Basically it is making a simple MVC controller that displays a value stored as property in externalized application.properties
(or yaml). By using Gradle and Docker, we can create a Tomcat server deploying the very same war file to two different context. The Docker container can be start using the environment variable SPRING_CONFIG_LOCATION
.
The objective is that when I enquire the controller on each application, I get a different "Hello
Involving spring.application.name
I couldn't see if this is already implemented or not, but to my record spring.application.name
always equals application
, so application.properties
is loaded. By overriding spring.application.name
one can load a different myapplication.properties
and this can solve the issue.
But the idea is making some convention about it. So, attempting to load contextPath.properties
along with other files could be a cool enhancement to Boot.
Thanks for the attention. I am open to discussion.
Comment From: wilkinsona
Thanks for the proposal. This is a duplicate of https://github.com/spring-projects/spring-boot/issues/15233. Our recommended approach is shown in this comment. This isn't something that we want to configure out of the box as deploying multiple applications to the same container generally isn't something that we want to encourage and those that want to do it are likely to want to configure things in various different ways.