News: Maven Config Processor 1.6 released
This project aims to solve the problem of application configuration for heterogeneous environments. Usually, the configuration files have development time values only and the process of building for other environments generally involves some kind of configuration adjusts like, for example, using actual services instead of mocks. With this plugin, the configurations for heterogeneous environments are kept separated and only what is different is kept. You don't need to duplicate files all over your project. You can add, modify, remove, comment and uncomment configuration values of .properties and .xml files keeping your original comments. This plugin aims to do the same things that XConf does but it is fully integrated with Maven and supports standard technologies (XPath instead of a custom language for XML processing). Version 1.6 has just been uploaded to the maven central repo. Read more about the project at: http://code.google.com/p/maven-config-processor-plugin/ Suggestions, bug reports and bug fixes are welcome!
- Posted by: Leandro Aparecido
- Posted on: July 13 2009 10:22 EDT
- Not the cleanest way to get this effect.... by Rex Hoffman on July 13 2009 13:00 EDT
- Not the cleanest way to get this effect.... by Leandro Aparecido on July 13 2009 13:16 EDT
- Re: Not the cleanest way to get this effect.... by Marcel Ammerlaan on July 14 2009 02:59 EDT
In general I'd recommend using spring's property support to handle this.... have your app read a system property, which tells it the location of a property file, verify it has all the tuples your app demands of it -- and the use the PropertyPlaceHolderConfigurer to use the property configuration file to replace values in your spring configurations at runtime. This works very well with multiple jar, and war files -- making this ideal for maven2 and/or OSGi Quick search turns this up: http://blog.arendsen.net/index.php/2005/03/12/configuration-management-with-spring/ Guice2 has similar support. Basically I'm saying use a dependency injection container for this rather than baking files for individual environments. By the way, the resources plugin already supports this -- again not that I would recommend using it. You'll either have an explosion of war files (and you'll be testing a different one in different environments) or you wont know which environment a app was built for without cracking it open. Just my .02$
The PropertyPlaceholderConfigurer is useful for .properties file loading and this plugin does not try to replace it. I myself use it heavily and I still need the maven config processor for some things. There are cases when loading properties files is not enough, for example, your development environment uses a set of beans but the production environment uses another entirely different set of beans for a number of reasons: deployment speed, runtime performance, the software stacks simply aren't the same and so on. It can be time consuming and error prone to setup mechanisms to discover what config to use at runtime. Even if you can determine at runtime what configuration to use, you will end up duplicating the same configurations in many files which is even more problematic and you will have to deploy development time artifacts in production. With this plugin you can centralize only what is different for each environment and merge them at build time.
"...have your app read a system property..." I see this time and time again and leads to problems quickly in more complex environments. To name a few issues with this: - System properties are per JVM, having multiple apps on a single JVM: poof (unless naming conventions are used) - The above with multiple installations of the same application (poof) - Application distribution: how do you convey to a tool that you need this setting? What is so difficult about using JNDI for getting the location: the mapping can be done on application or cluster level and no need to have funky system properties.
I agree that system properties are not the ideal solution and I should add that it is not always that you will have an application server to lookup config values via JDNI. The ideal solution IMHO is one that leaves only what is very specific and confidential in the hands of sysadmins and that must be very clear so we don't confuse people looking at the installed application. For instance, there should not be empty files, uncommented config values or multiple copies of the same file with different names (xx-des.txt, xx-qa.txt, etc) in an environment that doesn't need them.
Marcel: So yes, if people scatter the reading of system property files all over the place then this gets ugly quick, I suggested only one property, something like -config-location. That points to a property file. JNDI is not part of the Servlet spec, and ties development to full JEE servers, instead of maven runnable jetty. Generally full JEE is unneeded and a pain, and would require all dev machines to be setup with an app server and configured with all needed JNDI config params, etc. I'd rather have the mvn jetty plugin configured to use a project resource (not jarred into the app) property file. Generally bad idea to run multiple apps on the same jvm/app server. I tend to prefer having them separate, in case of failure conditions, the (un)expected memory exception, etc... so that one app does not take the others down. VM are an even better jail. Not sure what Servlet container you're running your apps on, but in general you can cluster apps, properties and all, through an app server manager.