After working on RoR for close to an year I can’t stop applying many of the learnings I gathered while I was in that camp.
On my current codebase I decided to solve the issue of configuring things differently in different environments with some inspiration from Rails.

One insightful way of look at Rails itself is to view it as a domain model of a web application. If you just look at “Web Applications” or even “Applications” itself as the domain some of the entities that can be found in this domain would be Models, Views, Controllers, Scripts, Style sheets, Web Services, Databases and last but not the least Environments. Rails quite elegantly weaves these different entities into a neat “Web Application”.

But in this blog let me talk about the much less discussed about “Environment” object. Since the notion of an Environment and seamless collaboration with the rest of the components is built into Rails it often escapes any discussion.

All of us who have created web apps know that they are deployed in many different physical environs. Apart from the basic dev,test,production environs we sometimes created specialized performance or sometimes even a simple showcase/demo environment etc. More often than not each of these atleast have a different database schema at the very least. And sometimes depending on the complexity may deal stubbed/mocked services, queues, different logging requirements and so on.
With this increased set of dependencies comes the issue of configuring each of them differently while keeping the application code agnostic to the env sometimes primarily to improve testability.
When I saw this issue come up in my codebase I decided to adapt the idea from Rails by creating an SystemEnvironment interface. It has different concrete flavors such as ProductionEnvironment and TestEnvironment (just two in my case) and primarily exposes getters for different configurable properties.
With this in place the next thing is to inject a concrete Environment instance into my services. Here again I resorted to a simple constructor based dependency injection with my tests injecting a TestEnvironment instance and the default constructor injecting a ProductionEnvironment instance.

So lets assume you have an attribute that for some reason has to be obtained through a JNDI lookup when running in a container. Now with the indirection of an Environment we have made the client agnostic to how the attribute it depends on is resolved in different environs. And this leads to a significantly better design with the added benefit of simplifying testability.
The test/dev env might just return a hard code value or read it off a file while only the production env actually makes the JNDI lookup.

Apart from making your system more loosely coupled this approach also centralizes configuration and prepares the ground for a more elaborate configuration management implementation such as using the jakarta commons-configuration library.
Another side benefit I realized was by further aggregating different sets of attributes based on what they controlled.
For example a set of attributes were related to my email environment, some influenced what kind of external services I accessed etc.
Such a refactoring would help greatly just to get a clarity on the external dependencies (aka points of failure) a system might have.

With this mechanism in place, one of the problems I am yet to solve is create a simple mechanism to inject the right environment like the way Rails does it, i.e out of a single configuration file. The other thing is to instruct tomcat to look into the approapriate file and init the env. I understand a dependency injector such as Spring would help but my currrent codebase is not using spring so any other “lighter” ideas are welcome.