Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common use cases.

In any real world production app, you don’t manage your configuration from within your WAR file. How do you have a configuration file deployed out to your production server beside your WAR file?

Most of the posts out there about external configuration all talk about hard coding external config locations into a variable like so:

grails.config.locations = [ "file:${userHome}/${appName}-conf.properties"]

Well, that sucks. That is assuming, again, more about production then you really can afford. The configuration of the production system, isn’t up to the developer. It’s up to the Release Manager or System Admin or a whole team of people besides you. Rather than force them into accommodating you, the programmer, you need to make it easy for them to specify WHATEVER THE FUCK THEY WANT.

So here it is, place the following in Config.groovy:

def ENV_NAME = "APPNAME_CONFIG"
if(!grails.config.location || !(grails.config.location instanceof List)) {
	grails.config.location = []
}
if(System.getenv(ENV_NAME)) {
	println "Including configuration file specified in environment: " + System.getenv(ENV_NAME);
	grails.config.location << "file:" + System.getenv(ENV_NAME)

} else if(System.getProperty(ENV_NAME)) {
	println "Including configuration file specified on command line: " + System.getProperty(ENV_NAME);
	grails.config.location << "file:" + System.getProperty(ENV_NAME)

} else {
	println "No external configuration file defined."
}

The key points in this method that are not in the docs or blogs to come before me:

  • It actually works. It appears some devs don’t bother testing their methods before posting the code. You have to initialize the grails.config.location as a list if it isn’t already. And it is grails.config.location. Not, location[s].
  • This method is flexible, it allows either the config location to be specified in the OS Environment or on the command line. You don’t know what is available to you in production!
  • Perhaps the most important: It tells the person starting up the application, what configuration the app will be using. There is nothing more frustrating than being in the heat of a deployment, already stretched to the edge of your maintenance window, and being unable to find out why your configuration changes aren’t taking affect.
  • It uses println statements instead of log statements. In my usage, logging wasn’t setup yet so println it was. I’m sure with some fiddling those could be replaced with log statements.
  • If I sound harsh, it’s because I’ve just dealt with another stupid Grails issue that should be a no brainer. And if not in the official documentation, the 3 or 4 blog posts and a Stack Overflow question about this should have provided the CORRECT FUCKING ANSWER.
About the Author:

Learned something? Need help on your dev project? Well, I'm available for hire on project work:

  • Front End Development (jQuery, ExtJS, Backbone)
  • iOS Development
  • Server Side Development (Java Stack or Rails Stack)
  • System Architecture

Contact me:

Discussion

  1. Raphael OM says:

    I can understand your anger man. Grails docs are often the only and really awful way to understand it. I’ve looked into this for _years_ but Instead of reading grails source(like a do most of the time to know wtf is going on), I’ve always bypassed grails altogether and deal straight with spring and web.xml.

    Your way is much more elegant. Thanks.

  2. Markus says:

    Great post! This is how it is supposed to be. There is only one mistake in your example: It only started working for me when I added plural ‘s’ to location:

    grails.config.locations

  3. Phil says:

    Great post! I respect your candor.

  4. Vlad says:

    As a deployer, I’d prefer to have ‘if’ order reversed — i.e. first check -D option, and only then environment. Environment is often set for a set of domains/applications, and -D is more specific and should take precedence, IMHO.

  5. ruthst00 says:

    Great post. I’ve been using this method in production now for a year with great success. I can’t guarantee where my grails app will be installed, or where its config files will live, so this gives the installer lots of flexibility (and let’s me sleep at night!).

    The one issue I’ve hit, and I’m wondering if you have any guidance for this, is that after creating a new system environment variable containing the location of my config files, the server needs to be rebooted before System.getenv() will recognize the new variable. Some operations folks get mad at me for requiring the reboot and, for busy production systems, I have to wait for several days before the reboot can be put on a maintenance schedule. Has anyone run into this issue?

    So, the install process I’ve been following is:

    1. Create a new system environment variable on app server called “MYAPP_CONFIG” with a value of “c:\myapp_config”. This is where my config.groovy and datasource.groovy files are stored.

    2. Install my app’s ear file to WebSphere

    3. Reboot app server, to pick up the new env var “MYAPP_CONFIG” (if I don’t do this, then the call to “System.getenv()” returns null)

    4. Launch my app and everything works great

    I’d like to avoid the reboot, if possible…

    Thanks in advance,
    Steve

  6. Tim says:

    This is great. Is there a way to protect the database username and password in an external file?

    Thanks.

    • mike says:

      Unfortunately, no. But what we do is that referenced property file is owned by Tomcat only and outside of the document root in some specific directory. It prevents non-root users from viewing the file. It isn’t perfect, but these servers have limited access by only the deployment team.

  7. Hayden Muhl says:

    I’ve actually decided on a hybrid approach to doing Grails config. One of the main goals with my current Grails project is to make deployment retardedly simple. Just drop the WAR in place and it will walk you through the rest of the configuration.

    I plan to default to using a hidden directory in the current home directory, but allow the admin to override that with an environment variable. All this information will be given to the user via the web interface when the app is first installed.

  8. Faz says:

    Good description – to thank you, here’s a tip : If you drop the bad language you might get more emails regarding possible work.

    • mike says:

      Faz, thanks for the comment and tip! I do appreciate it.

      Think of the language as one of many litmus tests for potential clients… At any rate, there is no shortage of work…

  9. Francesco says:

    Great post! But also for me, it works only with locationS…I’m using Grails 2.2.1

  1. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

  2. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

  3. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

  4. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

  5. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

  6. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

  7. [... Grails docs go a long way towards being the only materials you need to learn how to use Grails. Unfortunately, it can miss a few things that are common ...]

Leave a Comment