Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Many times I have been in a situation where an application is apparently broken, only to find that an external configuration file has been at fault. Typically this is because the wrong file is there, or that it contains incorrect data.

Is there a better way to allow an external user/process to modify the runtime characteristics of an application, or is this the best known solution to the problem?

I'd like to see discussion on the general case rather than focusing on, say, Unix /etc or Java JNDI and so on.

share|improve this question
2  
how else can you configure test/dev/live/different live environments ? My point is its the only option - there will always be an external dependcy. –  NimChimpsky May 23 '12 at 11:32
    
Open a socket and poke the process directly? Should the app pull its configuration - or should it have it injected? –  Gary Rowe May 23 '12 at 11:33
5  
Whatever you have will be external. The problem you are having is not that the configuration is external, but that it is badly managed and understood. –  Oded May 23 '12 at 11:36
2  
But that's the thing - config files tend to be badly managed or understood. –  Telastyn May 23 '12 at 12:01
4  
As for the "wrong file" - there is a nice Unixish technique: use a script wrapper to start your binary, setting all the configuration environment variables locally. This way it is always crystal clear which configuration you've picked up. –  SK-logic May 23 '12 at 12:53

6 Answers 6

up vote 13 down vote accepted

Most applications will require some external configuration; you can hide this by making it dependent on magic variables, or by saving it to some internal location, but that won't remove the need. The goal is to recognize what should be external, and what can be internal. Only the internal parts can be tested.

An application should not trust an external configuration file to be correct. It should check the correctness, and report errors. If it is not possible for the application to check the configuration file, you are probably doing too much with it. If the configuration file changes the behavior of the application, it shouldn't be external in my opinion.

For example, a database username/password can be easily verified by the application by trying to connect to the database. If this fails, it can report it, and it is obviously not a bug in the application code. Similarly, for a file path the existence and access rights can be checked.

Now, if you were to put SQL queries in the configuration file, then the application cannot easily check the correctness of those queries. The same goes for a full dependency-injection specification (a la Java-Spring XML) file. Those should not be in external configuration files.

But if the specified configuration describes something external, and you can quickly check its correctness, I don't think there is anything wrong with external configuration files.

Edit: also make sure your error reports show which configuration file is used. Nothing is more frustrating than finding out you were looking at the wrong file after hours of trying to find out what's wrong with it.

share|improve this answer
3  
+1 for the internal validation recommendation - definitely a must to complete the pattern –  Gary Rowe May 23 '12 at 12:40

I would classify them more as a "known problem area" than an antipattern. Unless you are going to deploy a fixed configuration, you'll have to store configuration information somewhere. I usually like to store most of my configuration information in the database, but you still have to store the database connection information somewhere. I do prefer the Java/Spring approach of storing the configuration information in the application structure itself, rather than (say) in the user's home directory or the Windows registry, but that's just personal preference.

share|improve this answer

External configuration files are NOT an anti-pattern. Like everything else they can be used well or poorly depending on the system in question.

You seem to have run into some apps where the external config can break the app without telling the user what's going on. That's bad, but it's not the fault of the config files, it's the fault of whoever decided which parts are in the config files and which parts are in the app, and how to handle errors among them.

share|improve this answer

On my opinion: NO, external configuration files are not an antipattern.

It is just a technique an architectual pattern to manage software complexity.

In the age of SOLID design principles you have moved software complexity from Monolithic_application to more independent modules that have to be plugged together.

the alternative to "external configuration files" would be to configure modules directly by code.

share|improve this answer
    
Patterns are not confined to code - an external configuration file is an architectural pattern rather than merely a technique. –  Gary Rowe May 23 '12 at 12:42

If anything, moving configuration from logic to data is preferred. It allows you to make the application more flexible without the need to rework your code. Missing data files is more a case of too little documentation or sloppy work when installing than a bad practice in terms of coding IMHO.

share|improve this answer
    
I agree that declarative statements are a more direct, easier to understand way of specifying properties and (to an extent) behavior. +1. –  William Payne May 23 '12 at 16:45

Make your favorite SCM tool do double-duty as a CM tool: Put your config files in the repository. To change the config, commit the changes and let your automated deployment tools push them out to production (after running a range of automated tests, of course!)

Et Voila! you have a record of all configuration changes, plus the additional safety net of an automated CI/test system!

As has been pointed out before, architecture & design patterns are not limited to the product-system itself, but also extend to the team/process/systems that help to produce it.

share|improve this answer
1  
+1 for a useful implementation strategy - pretty much how Heroku does it with GitHub projects. –  Gary Rowe May 23 '12 at 17:07
    
You have to make sure your configs are not in the same repo as your code because of the effects on branching and tagging for releases. –  dietbuddha May 23 '12 at 20:46
1  
I disagree. The configs really should be in the same repo as the code. I believe that a production change to a config file is a valid reason to make a commit to (for example) a Svn tag branch. The key benefit is that you can look in one place (the repository) to see everything (as much as is possible) that could be affecting production. Much easier to chase down gremlins and bugs if you know where to find everything. (Particularly if you are using something like Graphite to chart commits against performance metrics & alerts) –  William Payne May 23 '12 at 21:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.