views:

92

answers:

5

Inspired by this question:

http://stackoverflow.com/questions/19355/how-to-manage-configuration-settings-for-each-developer

How can I manage application configuration settings that are must be set for each developer without checking them into source control on the Java platform?

For example, this is the kind of thing we are doing now:

  • Datasource configuration is stored in a Spring configuration xml file.

  • Currently, each developer edits the file and tries his best not to commit that file into source control. Several of us have patches (diff files) that are applied to the code before performing testing against our local database and remove the patch before checking code in. Other developers edit and revert the configuration files by hand.

  • Sadly, patches get out of date. People sometimes forget to revert their local configuration before commit.

My question, however, is not limited to database connection settings. I would like to find a solution where each developer can override application configuration settings without having to alter source controlled files.

If we must change the way in which we are storing configuration settings, then I think we should do it (perhaps JNDI?, external configuration files in a well known path?, I don't know)

What would you do/have you done?

+1  A: 

Best place to have these configuration is a database. And add a few lines to your production code just to read these configurations. It means no harm as long the purpose is solved and everything is consistent and coherent. Put on a small framework which reads these configurations and overrides the default ones that appear in production.

Fortunately some of the frameworks like Rails do provide these and I am pretty sure its flexible in Java as well.

Bragboy
... and how will the code know which database to use?
meriton
Yeah, I'm afraid that the database way is not what I like the most. It is the only approach I have tried and I found 2 downsides: 1) You tend to use table-like configuration structures that are not always the best kind of structure or xml-field blobs that are not easy to edit; 2) you have to solve the problem again for the database connection setting somehow outside the database.
Sergio Acosta
+1  A: 

One thing we have done here is have a property loader which first checks for system properties.

e.g. you have a property named datasource.url which gets loaded in to your Spring file.

We extended the ResourceLoader to first check the system properties to see if there was a property with that name, and if so it would load it up rather than using the value from the properties file. (Actually I think Spring's ResourceBundleMessageSource does this out of the box if you configure it, but we wanted some custom behaviour which I won't go into).

So, if we start our application with a few additional command line parameters:

-Ddatasource.url=[local-datasource-url]

Then it overrides the value from the properties file.

Obviously this is easier to do for a Swing application (which ours was) than a web app, but still a possibility.

Phill Sacre
I will try this. Thanks.
Sergio Acosta
+1  A: 

Place the configuration file in an external directory. If it is not present, read a default config file. The external directory can be configurable, and can have a default value, say c:\workspace\config.

Optionally, during the build, you can copy the external properties into the build artifact.

Bozho
I also thought of doing this. Maven uses a similar approach: it looks for a $MAVEN_HOME/settings.xml file. If there is none, it uses configuration defaults. The only problem is how to solve the cross-platform issue of paths in Windows and *nix. Perhaps the environment variable approach of using $MY_SYSTEM_HOME should be enough. thanks!
Sergio Acosta
+2  A: 

We make the build completely self contained, including things like local H2/Hipersonic/JavaDB databases and Ruby mail servers. That means the local build has no developer specific config and everything just points to the pre-packaged components. It also means that apart from basics (JVM, Ruby, Editors) there is zero time to configure a developer box.

The drawback is that your code checkout is somewhat bigger.

leonm
This sounds very nice. I'm afraid we are not at that level of automation with our build and configuration management yet, but is a great answer. thank you.
Sergio Acosta
+2  A: 

Check a template file (like sample.context.xml) into source control. Each developer copies that file to context.xml and does any modifications he likes. If the real configuration file lives in a source controlled dirctory, add it to svn:ignore to prevent accidental checkins.

==> No accidental commits, and persistent local configuration settings.

If the local configuration file is missing, the application doesn't start. This makes it obvious to new team members that settings can be configured. Obviously, the continuos integration server will need a local settings file, too.

As for where to put that configuration: It makes build and deployment easier if the instance-specific configuration is not part of the .war file. We use JNDI entries, which are easy to look up from spring configuration files using <j2ee:jndiLookup>.

meriton
It makes a lot of sense and this would be the easies (closer) solution in my case, because am already using source controlled files. We only have to add them to the ignore list. thanks
Sergio Acosta