Java – How to maintain and configure properties files for different environments in Java maven project

configurationdeploymentjavamavenproperties

A Java project with maven as build tool needs to be deployed to different environments, such as ci, dev, test, prod etc. Each environment has a properties file with the same set of properties such as:

  • service.host
  • environment.suffix
  • user
  • password

The values of these properties are environment-specific. Currently the properties file have a template called management_template.properties in the directory src/main/resources, and the content looks like the following:

service.host=${host}
environment.suffix=${suffix}
user=${user}
password=${password}

In the configuration above,

  • when deploying the project to production, the system property config.dir is needed for telling the directory of the properties file
  • when deploying the project to test for executing tests, the system properties config.dir.test is needed for telling the directory of the properties file.

The properties file in each of the environment is generated by means of shell script on base of the aforementioned template file, meaning the placeholders ${user},${host} etc. are replaced by some system-specific values.

Problem with the current solution: the process of generating the properties files and giving the system properties config.dir or config.dir.test seems to complicate the work. Extra Shell scripting is needed, also I doubt about the necessity of the system properties config.dir or config.dir.test

Question: is there any better solution for configuring and deploying the system-specific properties files?

Best Answer

As you indicate, the property values belong to the environment, not the application. So the best solution is for Maven to be totally unaware of the property values for the various environments. The basic idea is that Maven should create a binary that will run in any environment without modification, with the environment supplying the various property values at application start.

Also, I have worked on systems where developers had no access to the production database, so saving production credentials in properties saved to source control was simply not allowed.

This means that when the application starts, the environment must supply the property values. There are several ways that this can be done.

  • Pass the properties using the Java -Dproperty=value options on the command line.
  • Pass the property values using environment variables. Both Windows and Linux support this.
  • If there are lots of properties, then pass the path to the properties file using one of the above options.

Whatever approach you use, the application should check at startup that the required properties have been supplied, and die with an appropriate error message if one is missing. You will also need to liaise with your production staff when an application change requires a new property to be defined.

Related Topic