Home » Java » Enterprise Java » Overriding a packaged Spring application properties file via an external file

About Daniel Bryant

Daniel Bryant spends his day working as a software development consultant, specialising in designing and deploying JVM and NoSQL-based business solutions to the cloud for Small-to-Medium Enterprises. By night he works on several open-source projects, primarily with the goal to contribute back to the community, but also to learn about exciting new technologies. Daniel is an active member of the London Java Community and as part of this role he is currently working on the 'Adopt OpenJDK' Betterrev project. This project strives to make contributions to the OpenJDK source code much simpler, with the ultimate goal of promoting community engagement in the Reference Implementation for Java. During any remaining spare time Daniel also keeps an eye on academic developments within Artificial Intelligence and defeasible reasoning, having gained a PhD in this topic during his misspent youth as an academic.

Overriding a packaged Spring application properties file via an external file

Quite a common use case when developing a Spring application is that you want to have multiple versions of configuration properties depending on where you are deploying to, for example, database URLs or feature flag may be environment specific on dev, qa, production etc.

Like most Spring development tasks, there are several way to solve the problem. My preference is based on the following assumptions and preferences:

  • We create a default configuration properties file (e.g. ‘appConfig.properties’) and package this within the deployable artifact (JAR or WAR etc)
    • This file will contain a sensible set of default ‘baseline’ properties that the application requires to run successfully
    • This default configuration file will typically be used for development purposes i.e. the  appConfig.properties included within the application code will allow the application to work ‘out of the box’ on a well configured local development box
    • We are using Maven to package our application, and therefore we place the appConfig.properties file in the root level of the src/main/resources directory – this doesn’t mean you have to use Maven, but you will have to ensure that your application packaging process includes the properties files in a location that is on the classpath
  • We want to override properties in the baseline appConfig.properties file via an external file located in the deployed application’s working directory
    • We typically name this file appConfigOverride.properties
    • We may not override all of the default properties, and therefore we want any properties not present in the override file to default to the values in the baseline appConfig.properties file
  • It is possible to override application properties by passing parameters on the Command Line when executing the application, or setting system variables, but this is a separate topic

The Solution

We use the following structure for our application-context.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="file:appConfigOverride.properties" order="-1"
                                  ignore-unresolvable="true" ignore-resource-not-found="true" />
    <context:property-placeholder location="classpath:appConfig.properties" />

    ....

</beans>

The key things here, are the ‘order’ attribute, which forces properties found in the appConfigOverride.properties to be used when a property is also found in another file (effectively overriding values from the other file), and the ‘ignore-unresolvable=”true” ignore-resource-not-found=”true”‘ which allows Spring to continue loading the context if it can’t find the external file (or it doesn’t contain override all of the default properties from the appConfig file)
 

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

4 comments

  1. Nice tip, Daniel.

    One more option that we might want to consider, when instead of static loading, we want to consider runtime configuration, we can use JMX as well to change the values.

    Thanks Neo,
    http://javawithneo.blogspot.com

  2. Thanks for the tip, very useful! I was doing something similar, but whithout the order property.

  3. Good article. We used this approach very successfully on a project which launched this year in the UK. Passing command line arguments when starting the application is too error-prone and should be avoided IMHO.

  4. Excellent! This is exactly what I was looking for today.

    Thanks!
    -Stephen

Leave a Reply

Your email address will not be published. Required fields are marked *

*


six − = 1

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Do you want to know how to develop your skillset and become a ...

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!
Get ready to Rock!
To download the books, please verify your email address by following the instructions found on the email we just sent you.

THANK YOU!

Close