A Systematic Approach for Structuring Exception Handling in Robust Component-Based Software
This article addresses the systematic incorporation of exception handling into component-based systems. By "component-based", one can infer "object-oriented" since the use of libraries of classes, such ast STL and JCL, can be seen as the use of components, building blocks, while constructing large-scale software systems. Read this article in its entirety to get a sense of how to put exception handling to good use.
1. Introduction
Component-based development (CBD) is employed today to build large software systems, such as commercial and financial information systems with high dependability requirements. The central tenet of CBD is that software systems should be built by integrating preexisting reusable software components, which may be developed by different organizations. A direct implication of this notion is the separation in time and space between component development and system integration. On the one hand, developers of reusable software components do not have full knowledge of the different contexts in which the components will be used. On the other hand, system integrators usually have limited access to the internal design and source code of these components. The construction/integration dichotomy leads to mismatches between assumptions made by different components of an assembled system. Techniques for dealing with mismatches related to the functional properties of a system, such as wrappers and mediators, are in widespread use. However, mismatches related to conflicting assumptions regarding the behaviour of components when they deviate from their specifications (exceptional or abnormal behaviour) are not well understood. Failure to take the exceptional behaviour of components into account when building a componentbased system compromises the analysability of the assembled system and its overall dependability.
Exception handling is a well-known mechanism for introducing forward error recovery in software systems. Many important object-oriented programming languages, such as Java, C++, and C# have incorporated this mechanism. In traditional software development, a large part of the code of a reliable software system is dedicated to detection and handling of exceptions. However, this redundant part of the code is usually the least understood, tested, and documented. In component-based development, a similar phenomenon can be observed. Developers of large systems based on the J2EE platform, one of the de facto standards in the industry for CBD, have habits concerning the use of exception handling that make applications more vulnerable to faults and harder to maintain.
The lack of systematic approaches for structuring the exceptional behaviour of component-based applications is an important factor that contributes to this situation. Existing component-based development processes, such as Catalysis[10] and UML Components, focus almost exclusively on the system's normal behaviour.There are some proposals in the literature for extending such processes with activities for designing the exceptional behaviour of component-based systems. However, these proposals do not address the translation of the obtained design down to the implementation level of a componentbased system. Also, the most popular component models, such as EJB and .NET rely almost entirely on the exception handling system (EHS) of the target programming language, providing little guidance about how to better incorporate exception handling into their component-based applications.
The proper use of an EHS requires a consistent strategy for defining exception types and allocating responsibilities to exception handlers. Structuring exception handling is even more difficult for developers of component-based systems, due to the construction/integration dichotomy as discussed earlier.
When integrating software components to build dependable systems, it is of critical importance to resolve conflicts between the exceptional behaviour of the reusable components and the intended exceptional behaviour of the assembled system. When these conflicts are not solved, they may result in undesirable situations, such as: (i) the context and/or semantics of an exception raised by a component are lost, making it difficult for other components to handle it; or (ii) an exception may simply be ignored, leading to the propagation of errors throughout the system. Our practical experience in component-based mentoring for various Brazilian companies has shown us that, in practice, this is a recurring problem and motivated us to devise a general exception handling approach for component-based software systems.
In this paper, we propose a strategy for structuring exception handling in dependable component-based software systems. The proposed strategy is based on an abstract exception type hierarchy and the definition of different kinds of handlers with clearly pre-defined responsibilities. Component developers use the abstract exception type hierarchy to derive concrete exception types that preserve the semantics of a small set of generic exception types. These generic types are used by the system integrator to define an exception handling strategy for the integrated system that is not dependent of any particular implementation of its components. The different kinds of handlers promote separation of concerns between local (component-specific) and global (architectural) exception handling policies. The proposed strategy is based on two different and complementary views on exception handling. The first view is that presented by Flaviu Cristian in a classic article formally describing the termination model of exception handling in sequential programs. The second is Bertrand Meyer's view, presented as part of the Designby-Contract methodology.
Our approach could be integrated within a typical component-based development process. The main requirement for this integration is the a priori execution of activities for defining the failure hypotheses of the system and designing the exceptional behaviour to be implemented. The execution of these tasks is not considered to be trivial and, in the literature, there are several works that address them. We consider these works complementary to ours.
Our ultimate goal is to provide component developers and system integrators with a set of design and implementation guidelines that allows them to better structure the exceptional behaviour of the systems they build. In this manner, the impact of exceptional behaviour on the overall system complexity is reduced and the resulting system is both more reliable and easier to maintain. Furthermore, these guidelines should be easy enough to be applied to systems that do not have strict dependability requirements, and flexible enough to be used in conjunction with more sophisticated software fault tolerance mechanisms, such as design diversity.
The rest of this paper is organized as follows. Section 2 presents some related work, while Section 3 provides some background on exception handling, software architecture, and component-based development processes. Section 4 presents the strategy for exception handling from the perspective of both system integrators and component developers. In Section 5 we describe some of the lessons learned from a real-world case study. Section 6 presents concluding remarks and ideas for future work.