November 1, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Enterprise Deployment Environment Configuration with Java Spring

  • March 25, 2009
  • By Vlad Kofman
  • Send Email »
  • More Articles »

The projects in large enterprises usually span multiple development teams and environments. Lately, they even span continents. Many large projects often follow specific development methodologies such as RUP or Agile in order to help development managers and teams deal with the scope and keep the projects on track. Traditional software development life cycle (SDLC) involved several environments such as development, test/QA, and production; however, globalization and new development methodologies necessitate more environments such as staging, AUT (user acceptance testing), system integration, etc.


Figure 1: Traditional SDLC environments


Figure 2: SDLC environments following Agile or RUP methodologies

In this article you will learn about the deployment environment configurations with Java Spring, which maintains integrity of the build process among various environments. The approach can be applied in any project using Java and is one of the development best practices. The concept behind deployment environment configuration should fulfill two objectives. First, the project/code base should use specific settings depending on the environment. Second, after the code is build into initial environment, it should not be rebuild based on the environments where its being deployed.

For example, a Java project in a development environment should use a development database and a set of development Web services. The same code promoted to QA should use another (test) database and test Web services. Obviously when the project is moved to production, all data sources in the environment should be production strength.

One of the best practices of software development — which transcends platforms and languages — is to have environment specific settings as properties loaded during runtime. Developers must not hardwire any connection strings, Web service endpoint URLs, JNDI context locations, FTP location, logging severity levels, or other items in the code itself. This approach eliminates the need to recompile and often rebuild entire code base and hunt down locations that need to be updated when plumbing changes or servers get moved.

Assuming that the project does follow the runtime properties best practices and maintains global location with all the environment settings, this presents a new challenge when the code-base needs to be moved or promoted to a new environment. The code no longer needs to be recompiled, but because environment settings should be different among the environments, project still needs to be rebuild or repackaged to include correct properties. For instance, a Java WAR or EAR file that contains properties for various Web services server URL endpoints and logging configuration.


Figure 3: Same war file deployed to dev and test will use only one set of data sources, which is not correct. So repackaging is required to fix this scenario.

This presents a problem from QA perspective as newly packaged software is moved to System Integration, UAT or production, and not the one QA verified. QA can no longer vouch for the integrity, as new code could be slipped into the build. This also creates more work for the build master as not only different properties need to be maintained and put in for each new build per environment, but also actual build needs to be done every time there is a code move.

So what is the solution to these challenges?

The solution is fairly elegant and simple, and evolves making code-base "aware" of the environment in which it runs, and load appropriate properties. This will ensure there is only one packaged deployment, such as EAR or WAR file which can be moved from environment to environment without any changes.

Java Spring based configuration

To achieve this "environment aware logic" you can use the Spring framework’s PropertyPlaceholderConfigurer bean and a simple environment variable passed to the JVM (ex -Denv=qa). Given the fact the Java Spring framework is highly modular, if you are not familiar with it you won't have to incur a high learning curve to start using a few of its modules right away in any Java project. If you are familiar or if you are already using it, than you have even more reasons to take advantage of this feature.

I have covered various aspects of Spring in several of my pervious articles, and will concentrate on project configuration here. The PropertyPlaceholderConfigurer bean offers convenient way to load properties at a runtime. You can combine it with other property loading mechanisms, but this one is specifically designed to load files.

To begin, you will need to include the Spring Jar files in your project and initialize the Spring bean container at the start up. The Spring configuration XML file needs to be created and loaded. This can be done in several ways. The simplest is to include applicationContext.xml in your J2EE web application WEB-INF folder. You can also add ContextLoaderListener, to a web.xml file:

<listener>
   <listener-class>
      org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>

If your project is not Web based, you can use ClassPathResource to load Spring configuration XML and initialize context. For example:

Resource spring = new ClassPathResource("applicationContext.xml");

To access Spring beans (in this case a particular bean PropertyPlaceholderConfigurer) you will need to get a reference for the BeanFactory interface. For example, to get an instance of XmlBeanFactory and assign it to a reference of BeanFactory, the statement will be:

BeanFactory factory=new XmlBeanFactory(spring);

The Spring beans configuration for the PropertyPlaceholderConfigurer from the Spring config file (applicationContext.xml) can look like this:

<bean id="ApplicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
           <property name="locations">
                  <list>
                        <value>classpath:app.${env}.properties</value>
                        <value>classpath:ldap.${env}.properties</value>
                        <value>classpath:some.properties</value>
                        <value>classpath:hibernate.properties</value>
                  </list>
            </property>
     </bean> 

Notice that the embedded expression ${env} for the environment variable mentioned earlier, it's very important aspect of the configuration and must be set in each environments at a JVM level. Spring framework will resolve it automatically.

For example, pass this as JAVA OPTION -Denv=qa for your application server or stand alone application.

This variable ${env} will be read and substituted in the Spring config resulting in the correct property loaded per environment. So if the variable value is "qa", app.qa.properties file will be loaded and used by the application. This way you can bundle several properties files in the same WAR or EAR and reuse it among the environments without repackaging or rebuilding. The code integrity will be preserved from QA to release builds, and build masters will not have to do unnecessary builds.

I should also mention that this approach will work for the property files that are in the Java classpath. If you want to maintain these files outside or your application war or ear file, which will give you ability to change them after the deployment, you can use the same PropertyPlaceholderConfigurer with:

<property name="location" value="file:///conf/app.${env}.properties " />

If you only need to load one file, use the property "location" instead of "locations".

What is amazing about Spring's ability to work with embedded expressions, is the fact that you can start using the contents of the configuration files immediately after they are loaded by Spring in the same config file. For example, if one of the properties was data source with name "DS_CONN" specified in the app.qa.properties you can use the following in applicationContext.xml and it will work:

<property name="jndiName" value="jdbc/${DS_CONN}" /> 

Conclusion

In this article I have discussed a very elegant way to streamline build and configuration process for enterprise Java projects that are following SDLC methodologies. There are other ways to accomplish this task, but using what is offered by popular frameworks, such as Spring has many advantages. This approach would save a lot of time and I would encourage exploring this further to any enterprise architect and application developer.

About the Author

Vlad Kofman is working on the enterprise-scale projects for the major Wall Street firms. He has also worked on the defense contracts for the U.S. government. His main interests are object oriented programming methodologies, UI and the design patterns.

References

Spring: http://www.springsource.org






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel