Related Topics: Apache Web Server Journal, Java Developer Magazine, Open Web Magazine

Apache Web Server: Article

Benefiting From Open Source Development

The goal: cross-platform Java development

3.  Create Ant filter token definitions that use the environment-specific properties:

<filterset id="project.filter.tokens">
<!-- DB Service(s) -->
<filter token="JDBC.DRIVER.CLASSNAME" value="${jdbc.driver.classname}"/>
<filter token="JDBC.DRIVER.TYPE" value="${jdbc.driver.type}"/>
<filter token="JDBC.SERVER.TYPE" value="${jdbc.server.type}"/>
<filter token="JDBC.SERVER.HOST" value="${jdbc.server.host}"/>
<filter token="JDBC.SERVER.PORT" value="${jdbc.server.port}"/>
<filter token="JDBC.USERNAME" value="${jdbc.username}"/>
<filter token="JDBC.PASSWORD" value="${jdbc.password}"/>
</filterset>

4.  Create a properties file containing the filter tokens.
Ant will substitute actual values for the tokens:

jdbc.driverClassName = @JDBC.DRIVER.CLASSNAME@
jdbc.url =
jdbc:@JDBC.DRIVER.TYPE@:@JDBC.SERVER.TYPE@://@JDBC.SERVER.HOST@:@JDBC.SERVER.PORT@
jdbc.username = @JDBC.USERNAME@
jdbc.password = @JDBC.PASSWORD@

5.  Place a copy task in some target that invokes the filter token substitution (<filterset>):

<target name="copy-files" depends="">
<!-- Copy, with overwrite, properties and xml files
- so that configuration changes via Ant build properties
- will always be picked up.
-->
<copy todir="${web.build.dir}" overwrite="yes">
<fileset dir="${web.src.dir}">
<include name="**/*.properties" />
<include name="**/*.xml" />
</fileset>
<filterset refid="project.filter.tokens" />
</copy>
</target>

When the application is packaged, it looks in (among other places) ${web.build.dir} for files to include in the Web application archive (WAR). There, it will find the generated runtime resources with environment-specific values.

Spring
The Spring Framework was very useful in allowing us to develop our application in a container-agnostic fashion. We took advantage of several of the many features of Spring.

1.  Service Location
We used Spring application contexts for the integration with Struts, for deployments to Tomcat and WebSphere, in standalone utility applications, and even in JUnit tests. Spring allowed us to standardize how our service objects were found and initialized across all uses of those objects in a compelling way.

2.  Bean Life Cycle and Dependency Management
By using Spring's application contexts, we successfully avoided stateless session beans that would have caused deployment issues across containers (not to mention the fact that Tomcat would not have readily supported EJBs).

3.  JDBC Template Code
The Spring JDBC APIs allowed for facile database coding - much cleaner code and standardization along the lines of connection management and exception handling.

4.  Flexible Data Sources
The Spring model of using beans to wire together dependent objects allowed us to use extra-container data sources. This came with the benefit of standardized usage of data sources across our runtime scenarios - no fiddling around with container-specific data source configuration.

jakarta Commons Logging API
We used the Jakarta Commons Logging API from the beginning. It provides a very useful abstraction of typical logging needs while supplying useful hooks for plugging in various logging services such as Log4j, the Java Logging API, etc. WebSphere even provides a gateway to its own tracing facility. The ws-commons-logging.jar in the lib directory off the WebSphere installation root directory allows for logging of classes to be controlled via the WebSphere Administrative Console - as long as those classes were coded to use the Jakarta Commons Logging API.

Commons Logging allowed us to configure which plugin to use (e.g., Log4J in a Tomcat environment, WebSphere logging in that environment) and - via its default implementation that simply writes to the console - to trace unit test code without the need to configure or enable a logging service. In addition, we were able to completely turn off logging via configuration files. (This is done by placing a file called commons-logging.properties on the classpath with the line org.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog in it). In fact, this was the standard configuration for running our unit tests, which were run as part of every build. Of course, if a unit test failed, logging could be turned on again as a diagnostic tactic by setting org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog.

What About the Risks?
After a year of real-life experience of developing several applications and performing multiple production deployments with this configuration, we feel that developing on Tomcat and deploying to WebSphere is a low-risk strategy. Once the environments were set up and the deployment process automated, there were very few problems. Spring provided the necessary container capabilities that we needed in a portable way. We were able to take advantage of Spring's bean management, service locator, data source, and JDBC abstractions.

Differences in the security infrastructure were overcome by using Tomcat's built-in features and by providing stub code in the service layer of the development envi-ronment that simulated the presence of TAM. We were able to use the same LDAP server in development (with Tomcat security) and in QA (with Tivoli Access Manager security).

Over time, the cost-saving aspect of cross-platform development became less important in favor of other advantages that were initially not anticipated. The lightweight development environment turned out to be a great advantage, and being forced to layer the application architecture to achieve isolation from the container produced cleaner and better maintainable application code - something that reduced the overall project risks, not increased them.

More Stories By Christian Donner

Christian Donner has 20 years of experience in project delivery and consulting. His professional focus includes EAI, BI, CRM, supporting business strategy through the development, implementation, and maintenance of mission critical systems. He is a senior technical architect at Molecular, a Web consulting firm located in the Boston area, and has written for both Java Developer's Journal and .NET Developer's Journal. He can be reached at pubs2005@cdonner.com.

More Stories By Sumitra Chary

Sumitra Chary is a senior software engineer at Molecular. Her career has spanned both academic and commercial worlds. These have included software systems for X-ray observatory missions, network management, marketing automation, and enterprise Web applications.

More Stories By Jim Lamoureaux

Jim Lamoureaux is a senior consultant and software architect at Molecular. His interests include object-oriented design and implementation, programming languages, and software process. Jim is a Sun Certified Programmer for the Java 2 Platform. He currently lives in Southern New Hampshire.

More Stories By Ilia Papas

Ilia Papas is a software engineer at Molecular. He has been working with web applications for five years and has interests in the design and implementation of enterprise applications using a variety of technologies. He currently lives in the Boston area.

More Stories By Dita Vyslouzil

Dita Vyslouzil is a Consultant and Technical Architect in the Engineering group at Molecular in Watertown. She has been in software development for 7 years, concentrating in transactional web applications.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.