Dirk Riehle and Kai-Uwe Mätzel
Ubilab, UBS. Bahnhofstrasse 45, CH-8021 Zurich.
E-mail: {riehle, maetzel}@acm.org
Abstract
In this position paper, we explore the use of reflection to
support interface adaptation in the evolution of component-based
systems. Reflection provides an appropriate means to intercept
component interactions and to bridge gaps between different evolving
interface and implementation versions. We use a simple client/service
scenario to illustrate the arising issues.
1 Reflection
We shortly describe the terms reflection, metalevel architecture,
and metalevel interception. Readers familiar with these concepts
can safely jump to section 2.
Reflection is the capability of a system to reflect upon
itself, that is to inspect and change its own state and behavior.
An object's reflection on its own state first requires the system
aspect under consideration to be explicitly represented and then
to be causally connected with the running implementation [KRB92].
The standard technique for explicitly representing system aspects
is to turn them into objects, so a reflective system might have
class objects, operation invocation objects,
and schema objects. These objects are usually called
metaobjects, in contrast to regular application objects, which
are called baseobjects. Metaobjects control the operation of baseobjects,
for example how operations are invoked, how concurrency is handled,
etc. [McA95].
The standard object-oriented technique for causally connecting
this representation with the system itself is through the use
of a metalevel architecture. Such an architecture provides access
to the aforementioned metaobjects and makes sure that changes
to these metaobjects lead to the intended changes of the system
aspect represented by the metaobject.
Implementation-wise, metaobjects use so-called metalevel interceptions
to control a baselevel object: every operation invocation can
be intercepted by the metalevel and turned into a request object,
so that the metaobject can explicitly handle the operation invocation,
for example for logging or security purposes.
Systems which define such a metalevel architecture, are for
example, IBM's SOM [FCDR95], Apertos [Yok92], CLOS [KRB92], and
Geo [BGR96], our own system.
Now that possibly every operation invocation can be handled
explicitly (rather than being hidden by compiler generated code),
the doors are open to introduce any kind of facility that adds
something to the operation invocation.
2 Using Reflection to Support Evolution
We assume that on a coarse-grained level, a system can be described
using a component metamodel, for example COM or [SG96]. Every
component has one or more interfaces. We sketch the simple evolution
scenario of a service and several clients to explore the use of
reflection to help ease evolution.
A service component used by several clients may evolve in two
primary ways: (a) changes to the interface and (b) non-hidden
changes to the implementation, that is changes in runtime behavior
which do not affect the interfaces on a syntactically level but
do affect clients.
Not all clients can be updated at the same time, so the required
service interface the clients see and the actual provided interface
of the service may diverge over time and must be tagged with a
version number. A client's call of a service operation then must
not only encompass all operation invocation information but also
the expected version of the interface. The version number in turn
must refer to both an interface and implementation version to
be complete.
This information and its handling can be managed well at the
metalevel. A client's metaobject maintains information about interface
versions of collaborating objects, for example the required service
interface in terms of its version number. The service's metaobject,
upon receiving a (request object, interface version) pair from
the client's metaobject, will then be able to handle the request.
If required version and provided versions diverge, it will usually
look up some adapter object which bridges the gap. Techniques
for retrieving the proper adapter have been described in [Rie95,
MS97].
Thus, a metalevel architecture helps to transparently introduce
adapters into operation invocations on components with evolving
interfaces. This buys the time to update clients one after another
to keep up with an evolving service.
In a similar fashion as discussed here, database schemas can
be evolved. Precondition is that they can be coherently embedded
into an architecture which provides the discussed metalevel facilities.
This might be done by hiding the schema behind a wrapping access
component which is under control of the metalevel architecture.
3 Open Problems
Of course, reflection is only one means to support evolution,
and the problem addressed above is only one particular (though
important) problem. More general problems which influence the
design and implementation of a metalevel architecture to support
evolution are:
- The used component model. How do we define the concept
of component?
COM has been shown to have many problems [SM97], and the concept
of component is not yet well-defined, probably in a state as
objects were 10 to 15 years ago. Yet, objects seem to be too
fine-grained for large-scale software development.
- Granularity of evolution.
Rarely do single components evolve alone, but usually in conjunction
with other components. How can we make use of this? How do we
ensure consistent change to the different involved components,
possibly using some kind of component space transaction?
- Process of evolution.
How do we ensure that we reach stable bases, that is major releases
which represent (as far as possible) a coherent whole rather
than a wild set of diverging components and a sea of adapters?
4 Workshop Interests
At Ubilab, the information technology research lab of UBS (Union
Bank of Switzerland), we are exploring the use of metalevel architectures
in the design, implementation, and evolution of distributed systems.
Moreover, we are consulting to another UBS project the intent
of which is to provide UBS with a global distributed software
architecture based on a metalevel architecture using, among other
issues, the evolution scenario described above.
Thus, we are interested
- in finding out about related approaches, drawbacks and pitfalls;
- discussing component models and their suitability wrt to
evolution;
- having a good time.
References
[BGR96] Walter Bischofberger, Michael Guttman and Dirk Riehle.
"Global Business Objects: Requirements and Solutions."
Proceedings of the Ubilab Conference '96, Zürich. Edited
by Kai-Uwe Mätzel and Hans-Peter Frei. Konstanz, Germany:
Universitätsverlag, 1996. Page 79-98.
[FCDR95] Ira R. Forman, Michael H. Conner, Scott H. Danforth,
and Larry K. Raper. Release-to-Release Binary Compatibility
in SOM. In Proceedings of the 1995 Conference on Object-Oriented
Programming Systems, Languages, and Applications (OOPSLA '95).
ACM Press, 1995. Page 426-438.
[KRB92] Gregor Kiczales, Jim des Riverieres, and Daniel G.
Bobrow. The Art of the Metaobject Protocol. Cambridge, MA: The
MIT Press, 1992.
[McA95] Jeff McAffer. Meta-level Programming with CodA.
In Proceedings of the 1995 European Conference on Object-Oriented
Programming (ECOOP '95). LNCS-952. Springer-Verlag, 1995. Page
190-214.
[MS97] K.U. Mätzel and P. Schnorf. Dynamic Component Adaptation.
Ubilab Technical Report, 1997.
[Rie96] D. Riehle. How and Why to Encapsulate Class Trees.
OOPSLA 95, Conference Proceedings. ACM Press, 1995.
[SG96] M. Shaw and D. Garlan. Software Architecture. Prentice-Hall,
1996.
[SM97] K. Sullivan and M. Marchukov. Interface Negotiation
and Efficient Reuse. CS Dept, University of Virginia, Technical
Report, 1997.
[Yok92] Yasuhiko Yokote. The Apertos Reflective Operating
System: The Concept and its Implementation. In Proceedings
of the 1992 Conference on Object-Oriented Programming Systems,
Languages, and Applications. ACM Press, 1992. Page 414-434.
|