The Quality busters series looks at common influences on application quality from the operational environment and non-functional requirements points of view. Addressing these influences involves making tradeoffs between many solutions -- none of which solves all the issues in an ideal fashion.
The SHEEP application architect learned that the newly released WebSphere Application Server 5.x supported the EJB 2.0 specification. Excited about the performance improvements they'd gain by migrating from remote interfaces to the new local interfaces, the architect decided to upgrade from WebSphere 4.x to 5.1. The first step is a clean migration with no code changes. Later, they plan to change the code to use the new local interfaces.
As the lead developer worked on the migration plan, she discovered that the xerces.jar file that provided the application's XML parser was missing from the new version of WebSphere. They could not find it anywhere in the WebSphere product's directory structure. A plug-in subdirectory included a xercesImpl.jar file, but it was unclear if this was a new file or a replacement.
Getting the architect involved, the team later discovered a section of the Getting Started document that noted that WebSphere 5.x was now using the JAXP (Java API for XML Processing) standard instead of directly supporting vendor-specific XML parser implementations.
The team had a choice -- they could either add an old copy of the xerces.jar file to their application's CLASSPATH, or they could modify their code to use the standard interface. The architect decided to modify the code.
The environment keeps changing
What the SHEEP Web team discovered is that the environment in which an application runs is always changing. Environment changes can be caused by:
- System software: Upgrading the operating system
- Program products: Upgrading program products (such as WebSphere)
- Hardware: Changing device drivers, adapters, attachments, peripherals, and so on
- Libraries and JARs: Changing shared component interfaces or behaviors
- Other applications: Changing interconnections, message formats, interfaces, and so on
Many factors, including these, often motivate changes:
- Support: Vendors dropping support for older versions, thus encouraging customers to upgrade in order to retain vendor maintenance services.
- Repairs: Vendors providing fixes for disruptive bugs or security holes.
- Improvement: Developers wanting improved functionality and users wanting improved performance or usability.
- Policy: Corporate environments moving toward standardized platforms.
- Aging: Hardware becoming obsolete or broken, thus needing replacement by newer models.
- Standards: International, national, or industry standards evolving, such as the movement from HTML to XHTML or EJB 1.0 to EJB 2.0.
- Political: Individuals with the authority to drive decisions wanting to use the latest versions, following the latest hyped solution, increasing their control territory, or meeting other desires.
- Legal: Government regulations requiring additional audits, security, and reporting.
The rate of change can complicate matters further. Even the smallest Web application has pieces of the execution framework changing weekly -- new security patches for the operating system, new versions of the HTTP server, new versions of the Java language environment, new versions of and patches to WebSphere components, new versions of browsers, and more. In a corporate environment, it could take a whole team of people just to keep up with the component changes.
So, how do you minimize the chaos of this changing environment?
The key word here is minimize. It is not possible to eliminate the risks and possible application changes associated with upgrading the environment. Even the smallest program patch (or fix) can cause unexpected side effects in your application.
As Figure 1 illustrates, tradeoffs are involved in minimizing the chaos. At one extreme, you can build an application that is tightly tied to the environment. While this reduces development time, it greatly increases maintenance time whenever an upgrade occurs. At the other extreme, you can build an application that is loosely tied to the environment by being very generic. While this increases development time, it reduces maintenance time. Or, you can search for a middle ground that balances development time and maintenance time.
Figure 1. The development versus maintenance continuum
When upgrading the environment, I usually recommend a two-phase approach to minimize the risk and take advantage of the new features in the environment. During phase one, minimal changes -- only those necessary to make the application run in the new environment -- are made to the application. The goal of phase one is to get the new environment installed and operational. Then, during phase two, the application is refactored to take advantage of the latest standards implemented in the upgraded environment. In this manner, the work of upgrading is spread over two smaller, more manageable efforts.
I believe that you should follow portability practices when designing an application. For more on management approaches to minimizing the disruption, read some of the books listed in Resources.
When most developers think about portability practices, I guess that they think about coding so the application can be moved to another platform -- for example, from Windows to UNIX -- with minimal changes. In a way, you can think of a move from one platform to another as an extreme example of an environment change. So, if you follow these same portability practices, then your application might survive environment upgrades with minimal changes.
I group portability practices into three major categories: safe coding, following standards, and isolating assumptions.
Different programming languages provide various levels of support for writing portable programs. For example, the Java language was designed to be "write once, run anywhere." C and C++ can to a lesser extent be used for portable programming, but you must take care while doing so, since those languages expose platform-specific data representations.
Even if the language assists with writing portable applications, it is still possible to write platform-dependent programs. For example, using JNI (Java Native Interface) to extend a Java application can bind the application to a specific platform.
The first category of portability practices involves safe coding. Examples of safe coding include:
- Being explicit and not relying upon the defaults of the programming language.
- Not relying upon the internal representation of the value of data objects, especially primitive data types.
- Passing source though static code analysis and checkers. Many open source and commercial tools are available for this purpose.
- Using proper memory and thread management; ensuring that objects are freed when no longer needed.
You can locate numerous books and articles about safe coding techniques. I recommend that you find a couple of these books for the language you use and follow their guidelines.
As recently as ten years ago, one rarely found APIs for accessing system services or infrastructure components. Various international (such as ISO) and national (such as ANSI) standards bodies had released standards for programming languages (for example, C and SQL), data representations (for example, the ASCII character set and the IEEE floating point number format), and operating systems (for example, the POSIX and X/Open standardization of UNIX APIs). The standards touched on the low-level aspects of programming.
Today, numerous infrastructure-level and even industry-specific standards are available. The infrastructure standards in the Java framework include JDBC for database access, JMS for message service access, JAXP for XML parser access, JAAS for authorization verification, JCE for encryption support, and so many more. The industry-level standards include ebXML for business processes, EDI for order processing and invoicing, ACORD XML standards for insurance documents, and others.
The availability of platform-independent infrastructure APIs means that it is possible to write applications that are isolated from the details of the underlying environment. As Figure 2 illustrates, the standardized APIs provide a separation level. Therefore, if the environment is upgraded or replaced, then your application should need only minimal changes as long as the standard interface is supported.
Figure 2. Separate the application from the environment
With the fast rate of change and evolution in the infrastructure APIs, this is not a guarantee, but it is better than writing directly to the vendor-supplied APIs.
Also, in order for writing to the standard APIs to work, it is vital that you code to the published contract of an API's behavior. Avoid relying upon observed side-effect behavior, since these side effects may change or disappear in a future release.
Finally, you might easily make assumptions about the environment. The closer you work with the environment, the easier it is to take certain services and functions provided by the environment for granted. you need to recognize and identify these assumptions, because usually these default behaviors are the ones that change with upgrades.
Several approaches exist for isolating assumptions about the environment. One is to place values -- such as directory paths, connection attributes, and user information -- into a configuration object. Another is to create a wrapper object that contains all accesses to a specific environment or external component. Figure 2 also illustrates how environment assumptions can be separated from the application.
Isolation of assumptions is not enough. It is also helpful to consolidate those assumptions into the smallest number of modules possible. The fewer places that environment assumptions exist, the easier it will be to find and change them if the environment changes.
When considering an upgrade to the application environment, an architect should ask these questions (among others).
- Who else is affected by the upgrade?
- What other applications that use the component being upgraded?
- Is the upgrade necessary?
- Is the upgrade being driven by needs (such as support, repairs, end-user improvements, replacement, or legal) or by desires (such as policy, political, or career)?
- Has the upgrade been tested?
- Have the developers reviewed all the release notes about the upgrade?
- Is a clear list of functionality lost, added, or changed between the old technology and the new being prepared and reviewed by the affected stakeholders in the application?
- Is it possible to revert to the old technology if the upgrade fails?
- Are portability practices being used in developing the application?
- Are safe coding techniques for the programming language being used?
- Are source code analysis and checking tools available and being used?
- Are international, national, and industry standards being followed?
- Are vendor-specific extensions being avoided or restricted to a small number of modules within the application?
- Are programmers following the published interfaces by avoiding coding per observed side effect behavior?
- Are assumptions within the application isolated to a small number of modules?
- Is it possible to update the application to use the latest standards with each release?
Building applications with portability in mind, even when you know of no plans to move to another platform, minimizes the disruptions caused by environment upgrades.
- A key technique to achieve portable code is coding to established standards and published APIs.
- Another technique is to avoid reliance upon observed side effects of functions or components, because those side effects may change in future releases.
- Finally, isolate assumptions about the operational environment as much as possible into a small set of modules.
- Read the author's other articles in the Quality busters series on developerWorks.
- Find information about the change in the XML support within WebSphere Application Server Version 5.1 in the Getting Started document available with the release notes. Download this document in PDF format.
- Check out these excellent articles on portability, standards, and assumptions on the IBM developerWorks site:
- "Diagnosing Java code: The future of software development," Eric Allen (July 2003)
- "Portability and interoperability," James Snell and Tom Glover (March 2003)
- "Using java:comp to locate EJBs and increase application portability," Mike Cox (July 2002)
- "XHTML: The power of two languages," Sathyan Munirathinam (July 2002)
- Review the developerWorks libraries containing a variety of different standards:
- Discover a good guide for managers and architects who are evaluating the business aspects of the technology life cycle and tools to optimize technlogy change in Managing Systems Migrations & Upgrades, Charles Breakfield and Roxanne Burkey (Digital Press, 2002).
- In Building Systems from Commercial Components, Kurt Wallnau et al (Addison-Wesley, 2002), get guidelines on managing applications built using off-the-shelf components.
- Explore the steps to incrementally migrate from rigid legacy systems into more flexible application environments as described in Migrating Legacy Systems, Michael Brodie and Michael Stonebraker (Morgan Kaufmann, 1995).
- Read Anticipating Change, Gerald Weinberg (Dorset House, 1997) as it illustrates how to create a supportive environment for handling the chaos of change.
- Peruse this early reference on migrating from legacy to Web-based applications that addresses portability issues: Application (Re)Engineering, Amjad Umar (Prentice-Hall, 1997).
- Explore desciptions of antipatterns, such as Continuous Obsolescence and Wolf Ticket, and learn how they can be barriers to effective application management in the classic book, Antipatterns: Refactoring Software, Architectures, and Projects in Crisis, William Brown et al (Wiley, 1998).
- Delve into this compilation of IT best practices for dealing with a changing environment, The Adaptive Enterprise: IT Infrastructure Strategies to Manage Change and Enable Growth, Bruce Robertson and Valentin Sribar (Addison-Wesley, 2002).

Michael Russell has a bachelor's degree in physics and a master's degree in computer science. He was a logistics engineer, a technical services manager, and a certified IT architect at IBM for nearly 14 years. He is currently a Web application architect for a resort company in Orlando. He has experience in Windows, UNIX, and OS/400 environments. He uses Web technology for entertainment through his own company, Vicki Fox Productions (http://www.VickiFox.com).




