Over and over I see projects struggling with the problem of parameters in property files that change in different environments; after all that’s pretty much the idea with the property files anyway – to make it easy to reconfigure the system.
PropertyPlaceholderConfigurer lets us externalize configuration parameters from the XML configuration to property files, and that’s excellent, but I’ve seen (and implemented myself) so many different cumbersome attempts on environment configuration it’s not even funny.
The problem is this: We’ll want to have one test-environment version of the property file bundled with the application source code to simplify starting the app in test mode from inside the IDE. So how do we reconfigure the application for production? Extract the war file, replace the property file with the production version, and re-pack the war? No, we really want to avoid this. Another, even worse solution is to have a number of different versions of the property files and then using different build profiles including the “correct” versions.
As it turns out there’s a perfectly simple, obvious, but surprisingly hard-to-google solution to this problem: You probably know that it’s possible to specify several property files when configuring the
PropertyPlaceholderConfigurer; well it turns out that a property redefined in a later file will override a setting from a previous file. This allows us to do the following:
ignore-resource-not-found attribute, which is needed to so that not all files need to be in place. Now consider that the bundled property file,
WEB-INF/myApp.properties has the following contents:
db.url=dbc:jtds:sqlserver://testdb.example.com/mydb db.user=testuser db.password=testpass
and that there is no file at
/etc/myApp/myApp.properties on your development machine. When we start the application in the IDE, it will load and run with the test settings.
If we now place an environment-specific property file at
/etc/myApp/myApp.properties with the following contents:
db.url=dbc:jtds:sqlserver://proddb.example.com/mydb db.user=produser db.password=somethingreallysecret
these are the settings that will be used when the application is started on that machine. This is what we’ll do on the production machine. And what’s even better: it won’t even be your responsibility – you just need to document where the property file should be placed and which properties that can be specified and then leave it for operations to actually make it so.
Simple as that.