A Comparison Framework for Middleware Infrastructures
Apostolos Zarras, University of Ioannina, Greece
|
 |
REFEREED
ARTICLE

PDF Version |
Abstract
Middleware is a software layer standing between the operating system
and the application, enabling the transparent integration of distributed
objects.
In this paper, we propose a framework that facilitates the comparison of middleware
infrastructures. Our approach serves for identifying similarities and differences
between middleware infrastructures and revealing their advantages and disadvantages
when facing the question of choosing one that satisfies the application’s
requirements. Based on the proposed framework, we compare CORBA with J2EE and
COM+, three of the most widely used infrastructures in both industry and academia.
1 INTRODUCTION
Middleware is a current trend in the development of open
distributed systems; it stands between the operating system and the
application
and enables the transparent integration of distributed objects [Bernstein96].
Middleware consists of reusable functionality that offers solutions
to frequently encountered problems like heterogeneity, interoperability,
security, dependability, etc. This functionality is offered either
by the core of a middleware infrastructure, or by complementary services.
The former mediates the interaction between distributed objects, while
the latter deal with issues like fault tolerance, transactions, naming,
trading, security, etc.
In the early 90s, there have been efforts to
come up with standards describing the semantics and the structure of
middleware infrastructures,
capable of supporting a wide range of applications. The CORBA (Common
Object Request Broker Architecture) specification [CORBAv3.0.2] is
among the most successful results of those efforts. Except for infrastructures
that comply with the CORBA standard (e.g., [Henning et al.98, Lo et
al.98, ORBIX, Schmidt et al.98, Puder et al.00]), there exist others,
which are also quite famous and widely used in both industry and academia.
Among the most popular, we find J2EE (Java 2 Enterprise Edition) [J2EEv1.4]
and COM+ [COM+v1.5].
Given this wide variety of solutions, what is
still missing, from a software engineering point of view, is a methodology
that facilitates
selecting the one that better tackles the particular requirements of
a distributed application. Recently, the OMG architecture board made
a statement concerning the coordinated use of existing standards towards
Model Driven Architecture development (MDA) [MDA]. The MDA development
process relies on the specification of models of the application’s
architecture. In a first step, the models are infrastructure-independent
(i.e., they abstract away technological details that do not relate
to the fundamental functionality of the application). The application’s
architecture specification may further include a description of technological
requirements, which serve for choosing among different infrastructures
that may satisfy them. The step that follows consists of refining infrastructure-independent
models into infrastructure-specific ones. The MDA development process
completes with turning infrastructure-specific models into code.
Concerning
the issues discussed above, we propose a framework for the systematic
comparison of middleware infrastructures, which facilitates
the first step of the MDA development process. The framework aims at
systematically exploring similarities, differences, revealing advantages
and disadvantages of middleware infrastructures, when facing the question
of choosing one that better satisfies the application’s requirements.
The
remainder of this paper is structured as follows. Section 2 presents
previous work and requirements related to our main objective. Section
3 details the comparison framework. Section 4 presents the framework
in action, comparing CORBA with J2EE and COM+. Finally, Section 5 summarizes
our contribution.
2 BACKGROUND & REQUIREMENTS
Most of previous approaches to the
comparison of middleware infrastructures rely on purely functional
criteria. In [Plasil et al.98], for instance,
the authors compare CORBA, Java RMI and DCOM (a predecessor of COM+)
regarding a number of basic concepts (e.g., request/response, remote
reference, interface, proxy, marshaling, etc.) and patterns (e.g.,
the broker pattern, the proxy pattern, etc.), traditionally used for
the integration of distributed objects. The overall comparison is faithful
from a technical point of view. However, the comparison framework proposed
by the authors does not establish relationships between functional
concepts, patterns and typical requirements imposed by distributed
applications. Hence, given the results from their comparison we cannot
reason about which infrastructures are capable of satisfying the requirements
of a particular application. Moreover, we cannot reason about which
specific concepts and patterns we should use to satisfy those requirements.
In [Roman et al.99] and [Gopalan98] the authors also rely on functional
comparison frameworks. Comparing middleware infrastructures strictly
from a functional point of view can be misleading as it is more than
difficult to check all the features of one infrastructure against corresponding
features of another one. In general, there is no perfect middleware
infrastructure; every one of them has its weak and strong points. Even
if a particular infrastructure has less weak points than another does,
it may not be suitable for the specific application that we implement
because its weak points may be exactly the ones we have to employ to
satisfy the application’s requirements.
In [Emmerich00], the
author follows a requirement-based approach. More specifically, the
author identifies typical requirements of distributed
applications over the middleware and examines whether or not different
types of middleware infrastructures support those requirements. However,
the comparison framework used does not establish the relationship between
the requirements and the specific middleware functional concepts we
should use to satisfy them.
Based on the issues raised above, we propose
a comparison framework which combines both the requirements-based and
the functional-based
approaches. More specifically, our framework consists of a set of key
requirements typically imposed by distributed applications over the
middleware. Satisfying the requirements depends on the particular architectural
style (i.e. the different types of elements that can be used for building
an application on top of the infrastructure and constraints on the
use of those elements) assumed by a middleware infrastructure and the
services the infrastructure provides. In the proposed framework:
- We define a generic architectural style that satisfies
the key requirements; if the particular architectural style of a
middleware infrastructure
conforms to this generic architectural style, the infrastructure
is capable of satisfying the key requirements.
- We identify fundamental services that should be offered
by a middleware infrastructure towards satisfying the key requirements.
3 COMPARISON
FRAMEWORK
Figure 1 gives the overall structure of our comparison framework,
which consists of key requirements imposed over the middleware, a
generic
architectural style for middleware infrastructures and fundamental
middleware services.
Key Requirements over the Middleware
The RM-ODP (Reference Model for
Open Distributed Processing) standard [RMODP] discusses the issue of
typical requirements on the integration
of distributed objects. Moreover, in [Emmerich00] the author further
deals with this issue. Based on these approaches, we consider the following
requirements:
-
Openness: The middleware infrastructure should enable extending
the applications built on top of it in various ways. (e.g., adding,
removing,
upgrading, composing services, etc.).
-
Scalability: The middleware infrastructure should facilitate
the effective operation of the applications at many different scales.
-
Performance: The middleware infrastructure should enable
the efficient and predictable, if needed, execution of the applications
that are
built on top of it.
-
Distribution transparency: is the property that determines
if the application is perceived by users, or developers as a whole
rather than as a collection
of independent constituent elements. The requirement for distribution
transparency is quite generic and it is usually refined into a
number of more specific transparencies including:
- Access transparency: the
infrastructure should enable accessing local and remote application
elements in the same way.
- Location transparency: the infrastructure
should enable accessing the application elements without knowledge
of their physical location.
- Concurrency transparency: the infrastructure
should allow concurrent processing on resources, without interference.
- Failure transparency: the infrastructure should
enable service provisioning despite the occurrence of failures.
- Migration transparency: the infrastructure
should provide means for changing the location of elements
of the application without compromising
the application’s correct operation, i.e. without affecting
the elements that depend on the migrated elements.
- Persistence transparency:
the infrastructure should provide means for concealing the
deactivation and reactivation of elements from other
elements that are using them.
- Transaction transparency: the infrastructure
should provide means for coordinating the execution of atomic
and isolated transactions.
A Generic Architectural Style
In general, every middleware infrastructure
assumes an architectural style that must be followed by applications
using the infrastructure.
Three basic principles must hold for this architectural style to support
the development of open and scalable applications:
- Modularity: The application should consist of a collection
of elements, each one providing services, used by the others. Modularity
enables
the identification of dependencies between the elements that make
up the system. Consequently, it allows determining, which elements
are
affected by the eventual addition, removal or upgrade of services.
-
Encapsulation: For each constituent element, there is a clear separation
between the element’s interface and implementation. The interface
is a well-defined specification of the provided services, the contract
between the element and the entities using it. The implementation is
the realization of the provided services. In general, it is safe to
change the implementation of an element as long as the element’s
interface is preserved. Changing an element’s interface without
compromising the overall application integrity requires that the
rest of the application does not depend on this particular interface,
at
the time of the change.
- Inheritance: An interface specification (resp. implementation)
may be derived from another one. The derived interface (resp. implementation)
provides at least the services of the base interface (resp. implementation).
Inheritance enables the vertical and horizontal composition of services.

Figure 1: The basic concepts of the comparison framework.
The generic architectural style we assume in the comparison framework
respects the aforementioned principles. It further relies on the
architectural style proposed in RM-ODP for open distributed systems.
More specifically, the basic elements that make up an application
are engineering objects, i.e. units of data or computation, which
we integrate transparently using functionality of a middleware infrastructure.
An engineering object can be instantiated multiple times within an
application. Instances have state and collaborate towards the accomplishment
of specific tasks. An engineering object provides one or more interfaces.
Furthermore, an engineering object may require one, or more interfaces.
Interfaces may be of the following kinds [RMODP]:
- Signal interfaces: defining asynchronous stimuli
that can be handled by instances of engineering objects, providing
these interfaces.
- Operation interfaces: defining operations that
can be invoked on instances, providing these interfaces. Invoking
an operation causes a request
message to be sent by the invoker to the invoked instance. Invoking
an operation may further result in a reply sent from the invoked
instance to the invoking instance.
- Stream interfaces: defining operations that can
be invoked on instances, providing these interfaces. The result of
invoking a
stream operation
is the continuous conveyance of information from the invoked instance
to the invoking instance.
Following RM-ODP, we assume that engineering
objects are organized into clusters for the purpose of activation,
deactivation, checkpoint,
recovery, etc. Each cluster is associated with a cluster manager, i.e.
an engineering object that coordinates the aforementioned activities.
Clusters are organized into capsules for the purpose of encapsulation
of processing, storage, and request flow. A capsule is associated with
a capsule manager, i.e. an engineering object that coordinates the
cluster managers of the constituent clusters.
Engineering objects that
belong to different capsules communicate through channels. More specifically,
two or more collaborating objects are
associated with a channel, which provides access transparency, i.e.
it masks differences in data representation and communication mechanisms
enabling the inter-operation of the associated objects. A channel is
a compound element consisting of proxies, skeletons, binders and protocol
objects.
A proxy is an engineering object that bridges the semantic
gap between local (i.e. elements belonging to the same capsule) and
remote elements
(i.e. elements belonging to different capsules). Invoking an operation,
(or sending a signal) on an object involves holding a reference to
that object. If both the invoker and the invoked object reside in the
same address space, the reference is a typical implementation-language
specific pointer (e.g. a C++ pointer). On the other hand, if the invoker
and the invoked object reside in different address spaces, the reference
is a pointer to a representative of the invoked object (i.e. a proxy)
in the invoker’s address space. Upon the invocation, the proxy
constructs and forwards a request to the remote object, through the
rest of the objects that make up the channel. Requests and replies
must be converted into a form that is suitable for transmitting over
the network. Technically, the previous is achieved through serialization
of requests and replies into a byte stream. The serialization procedure
is usually called marshalling. Several conversions may take place during
marshaling, to deal with data representation differences between the
invoker’s and the invoked object’s execution environments
(e.g., little-endian, big-endian).
A binder is an engineering object
that maintains the integrity of a channel (e.g., it monitors communication
failures and round-trip times
and sets appropriate time-outs; it multiplexes connections to multiple
remote objects to optimize resource usage). A protocol object provides
basic communication functionality (e.g., it writes a request to a TCP/IP
socket, it performs retransmissions based on time-outs set by the binders,
etc.). A skeleton is the representative of all objects requiring an
interface provided by a remote object, in the capsule of the remote
object. The skeleton accepts as input requests built by proxies and
uses information that is encapsulated in those requests to perform
local invocations on behavioral features (i.e. operations, signals)
provided by the remote object. The skeleton may further encapsulate
the result of the request into a reply, which is delivered back to
the invoker.
Fundamental Middleware Services
So far, we have seen that openness,
scalability and access transparency of an application depend on the
particular architectural style assumed
by the middleware infrastructure used for building it. Performance,
on the other hand, mainly depends on the realization of the infrastructure’s
communication channels. A basic performance criterion is the communication
overhead introduced by the use of the channels. This overhead is usually
not negligible; it is the penalty for dealing with communication in
distributed applications, executing on heterogeneous execution environments.
Achieving the rest of the requirements, identified at the beginning
of this section, relies on the use of complementary services offered
by the infrastructure. The use of the complementary services should
be transparent to the application, whenever possible. More
specifically, the infrastructure should provide means that relief the
developers
from explicitly using complex functionality of the services within
the code of the application. The ideal is that developers just setup
properties that characterize the objects of the application. Then,
the middleware used for integrating the objects implicitly combines
functionality of corresponding services to impose those properties
(e.g., the developer just sets the replication-style to be active-replication;
based on the style, appropriate functionality is used within channels,
for multicasting requests sent by clients to groups of replicated objects).
The fundamental services offered by an infrastructure can be divided
into three categories: repository, coordination, and security services
[RM-ODP].
Repository services provide functionality that allows managing
information regarding objects, interfaces, locations, etc. This category
includes
trading and naming services. A naming service defines a name
space and provides interfaces through which we associate names with
references
to objects. Client capsules may then use names to obtain the associated
object references. A trading service is a more sophisticated mechanism.
The client capsules do not need to know specific names of server objects,
they just hold a reference to a trader and use it to request for a
required service. The trader maintains a registry that contains references
to objects, providing specific services. A client request to the trader
is specified in terms of a required interface and additional quality
of service properties. The trader looks in the registry for a reference
to an object that can fulfill the client’s requirements and if
there exists one, the trader returns it to the client. Naming and trading
services can be used to provide location transparency. Moreover, we
can use the trading service to satisfy scalability requirements
as it can serve as a mechanism for load balancing.
Coordination services include services that can
be used to achieve concurrency
transparency (e.g. locking). Failure transparency regarding
accidental faults is realized using coordination services for replication,
checkpoint and recovery [Laprie85]. Replication may be employed both
at the level of engineering objects (use of groups of replicated
objects instead of simple objects) and at the level of communication
channels
(use of request retry and redirection mechanisms). Failure transparency concerning
intentional/malicious faults relies on the use of security services
for authentication, access control and encryption [Laprie85].
Migration transparency is achieved using coordination services
that allow copying or moving an object from one location to another,
without
affecting other objects that use it. Persistence transparency
relies on two key issues: (1) references to persistent objects must
remain
valid despite the deactivation and reactivation of those objects,
(2) the state of the objects must persist to their deactivation and
reactivation.
In principle, the creation and maintenance of references is a responsibility
of the infrastructure. On the other hand, persistent state involves
using a complementary checkpoint and recovery service. Transaction
transparency involves using coordination services that realize
atomic commitment protocols (e.g. two-phase commit protocol) and
concurrency
control protocols that guarantee isolation (e.g. two-phase locking).
4
THE COMPARISON FRAMEWORK IN ACTION In this section, we demonstrate
the use of the proposed framework for comparing CORBA with J2EE and
COM+.
Openness
All three platforms that we assess in this paper support the
development of open systems. More specifically, each one of them
relies on a particular architectural style, which is aligned with the
basic
principles
and
concepts of the generic architectural style we detailed in
the previous section.
CORBA forces developers to build applications
that comply with the CORBA object model [CORBAv3.0.2]. According
to that model,
the basic
engineering objects are called CORBA objects. Each CORBA
object provides a single interface; it is a conceptual entity
realized
by an implementation
language-specific entity (e.g. a C++ object, a Java object,
etc.), named servant. In principle, the servant may realize
more than
one CORBA objects. By default, CORBA interfaces are operation
interfaces, as defined in the generic architectural style.
An operation may
return
a reply or not; in the latter case it is called a one-way operation.
In order to realize a signal interface we have to use the
CORBA
Event Service [CORBAServices]. Stream interfaces are not
supported. The
specification of interfaces relies in CORBA IDL (Interface
Definition Language),
a purely declarative language that supports interface inheritance.
Implementation inheritance depends on the implementation
language used for the realization of servants.
CORBA objects
that have common properties regarding activation, deactivation,
etc. can be organized into clusters managed
by a POA element (Portable
Object Adapter). Capsules are called CORBA servers. CORBA
objects that belong to different servers communicate
using channels,
which rely
on the GIOP communication protocol. A more sophisticated
approach for clustering objects that have common properties
consists
of building CORBA components instead of typical CORBA
objects [CORBA-CCM].
Components
extend the semantics of simple objects in that they can
register to
containers, i.e. objects that implicitly manage object
activation and deactivation, transactions, security and persistence.
To achieve the
previous containers combine functionality of standard
CORBA services like PSS (Persistent State Service) and OTS (the
Object Transaction
Service) [CORBAServices]. Technically, each container
is associated with a properly configured POA. CORBA components
provide more
than one interfaces divided into two categories: (1)
external interfaces
used by other components of the application, and (2)
callback interfaces, used by the container towards managing object
activation and deactivation,
transactions, security and persistence. 
Table 1: CORBA, J2EE and COM+ regarding
openness.
J2EE imposes the use of
the Java object model [J2EEv1.4] for developing J2EE applications. According
to that model, an application comprises a collection
of Java objects, each one providing a number of Java interfaces. Java interfaces
are operation interfaces. To realize signal interfaces we have to use the
Java Message Service (JMS) [J2EEv1.4]. As with the
case of CORBA, stream interfaces
are not supported. Interfaces are specified using Java language-specific
constructs (instead of employing a separate IDL language).
Java allows both interface
and implementation inheritance. ActivationGroup objects can be used to cluster
objects with common properties regarding activation and deactivation. A capsule
in J2EE is called a server. Objects that belong to different servers communicate
through channels that rely on the Java RMI communication protocol. Alike
CORBA, J2EE further provides a more sophisticated approach
for clustering objects,
which involves building Enterprise Java Beans (EJBs) instead of typical Java
objects. EJBs extend the semantics of simple Java objects in that they can
register to EJB containers, i.e. objects that systematically manage the activation/deactivation,
transactional processing, persistence, etc. of the registered objects.
In
COM+, the basic engineering objects are called COM+
objects and provide one, or more interfaces [COM+v1.5].
COM+ objects are conceptual entities
realized by one or more implementation objects written in a conventional
programming
language like C++, Java, etc. COM+ interfaces are in principle operation
interfaces. Signal interfaces can be realized using the COM+ event service
[COM+Events].
As with the previous two infrastructures, stream interfaces are not supported.
Interfaces are specified using Microsoft IDL (MIDL), a purely declarative
language that supports inheritance. Capsules in COM+ are named processes.
COM+ objects
are organized into clusters, named contexts, regarding common properties,
having to do with the objects’ activation, deactivation, transactions,
security etc. COM+ objects interact through channels that rely on DCE RPC
[DCE-RPC].Table
1 summarizes the comparison of the three infrastructures regarding openness.
Scalability
As we detailed previously, the architectural
styles assumed by all three infrastructures we examine
here
support the development of scalable applications.
CORBA further
provides a trading service that can be used for load balancing [CORBAServices].The
CORBA Trader provides a registry of publicly known services. Clients may
query the trader for a particular service, providing the specification of
the service,
in terms of a CORBA IDL interface. Client queries may further include quality
of service requirements that must be satisfied by the service provider. The
trader answers the clients’ queries with references to objects that
can successfully offer the required service, while fulfilling the clients’ quality
requirements.
COM+ supports static load balancing [COM+v1.5]. More
specifically, a COM+ system can be configured to assign
certain clients to certain servers
that
execute
the same logic. However, the mapping between clients and servers does not
change dynamically to reflect changes in the servers’ workload. This
technique is an easy way for dealing with predictable loads. A more sophisticated
solution
involves using referral COM+ objects that assign clients to component objects
dynamically. J2EE also does not provide a standard trading service [Roman
et al.99]. However, it provides means for implementing proprietary ones.
Table
2 summarizes the comparison of CORBA, J2EE and COM+ regarding scalability.

Table 2: CORBA, J2EE and COM+ regarding
scalability.
Performance
Regarding efficiency, several performance
evaluation efforts [CORBABench, EJBBench, DCOM] show
that
the communication overhead is similar in orders
of magnitude
for COM+, J2EE and various CORBA compliant middleware infrastructures
(e.g. OmniORB [Lo et al.98], ORBacus [Henning et al.98], ORBIX
[ORBIX], TAO [Schmidt
et al.98], MICO [Puder et al.00]). In CORBA, we should expect
spending from 0.6 to 3.5 ms to send data of a basic
type (e.g. long, char,
float, double,
short etc.) from a client to a server object1.
J2EE, also seems to be expensive; we should count spending from
4 to
5 ms1. Finally, in COM+
2.5 to 3.5 ms
are needed1. The communication overhead grows for more complex
data types like
arrays, sequences, etc.
CORBA is the only one among the infrastructures
we consider here that facilitates the predictable execution
of applications. In
particular, the Real-Time
CORBA [CORBA-RT] is an extension of the standard CORBA specification,
enabling clients of an application to create priority-banded
connections to server
objects.
Clients can send prioritized requests through those connections.
Servers
may specify priorities on a per object basis, (e.g., requests
targeted to
a particular
object may have higher priorities compared to requests targeted
to other objects encapsulated by the same server). Request
processing takes place
according
to either the client, or the server priority model, depending
on specific properties set on the server-side. Clients may
further setup
timeouts
on requests and
servers can precise on the number of threads used for request
processing.
Clients and servers can also customize certain properties of
the underlying TCP/IP
communication protocol (e.g. the sizes of the communication
buffers used). Real-Time CORBA infrastructures come
along with scheduling
services, facilitating the execution of activities (i.e. sets
of requests) according
to various
scheduling policies (e.g., EDF, rate-monotonic, etc. [Schmidt
et al.98]). Table 3 summarizes
the comparison of CORBA, J2EE and COM+ considering efficiency
and predictability. 
Table 3: CORBA, J2EE and COM+ regarding performance.
Access
Transparency
CORBA, J2EE and COM+ channels provide access
transparency. More specifically, in CORBA, proxies and
skeletons are
called stubs and skeletons, respectively.
Requests are marshaled into byte streams according to the standard CDR
format (Common Data Representation), which deals with
byte ordering differences
between the machines that host the client and the server
object. CDR further deals
with the alignment of primitive CORBA data types within messages. Stubs
and skeletons are automatically generated using a CORBA
IDL compiler.
CORBA binders manage connections according
to the GIOP protocol. Connections in GIOP v1.0, v1.1 are
asymmetric;
the client can issue requests through
the connection, while the server can receive requests and send replies
but can
not issue requests. This restriction is relaxed in GIOP v1.2 and v1.3,
where connections are bidirectional. Connection shutdown can be initiated
either
by a server-side binder, or by a client-side binder. Server-side binders
can not initiate connection closure if there exist client requests
that are pending.
Client-side binders are responsible for multiplexing connections to
objects encapsulated by the same server to optimize resource
usage. If client-side
binders do not support the previous feature, a new connection is created
for every server object used by the client. CORBA protocol objects
rely on TCP/IP.
Other protocol objects may also be used within CORBA channels, as long
as they conform to certain transport protocol assumptions specified
in the CORBA
standard. 
Table
4: CORBA, J2EE and COM+ regarding access transparency.
J2EE channels rely
either on Java RMI [JavaRMI] or on GIOP. According to RMI, at the
time when a client obtains a reference, a new proxy is created.
Consequently,
multiple proxies in the address space of the client may represent the same
remote object. Marshaling is based on the Java Serialization Protocol [JavaRMI].
Proxies and skeletons are automatically generated, using the rmic compiler.
RMI binders manage the opening and closure of bidirectional connections.
Moreover, they are responsible for multiplexing connections according to
the Java Multiplexing
Protocol [JavaRMI]. RMI protocol objects are based on TCP/IP. Other kinds
of protocol objects are also supported.
COM+ channels are based on DCE RPC
[DCE-RPC]. When a client process obtains a reference to an interface for
the first time, a proxy is created. The proxy
is reference-counted to avoid creating multiple proxies, representing the
same remote object. Request and reply marshalling relies on the DCE NDR
(Normal Data Representation) format. Stubs and skeletons are automatically
generated
using the MIDL compiler. Binders manage the opening, closure and multiplexing
of bidirectional connections. Finally, the protocol objects rely on TCP/IP.
Other kinds of protocol objects may also be included in COM+ channels.
Table 4 summarizes the comparison of CORBA, J2EE and COM+ concerning
access transparency.
Location Transparency
CORBA provides both naming and trading services
that can be used to achieve location transparency [CORBAServices].
J2EE provides
two different naming
facilities: a daemon process, called RMI-Registry that realizes a flat
namespace and the
Java Naming and Directory Interface (JNDI), which is similar to the CORBA
Naming service [J2EEv1.4]. The distinctive feature of JNDI over CORBA Naming
is that
the former generates events, upon request, whenever a namespace changes
due to the addition, removal, or update of a name binding. Clients using
JNDI
can then register event listeners to receive such events. J2EE does not
provide, for the time being a trading service.

Table 5 : CORBA, J2EE and COM+ regarding location transparency.
As in the
case of J2EE, COM+ provides naming facilities, but it does not offer
any trading service. More specifically, in COM+ there exist two basic
global
name spaces. The first one contains GUIDs (globally unique identifies),
which are bound to COM+ interfaces, or to classes of COM+ objects. The
second name
space contains names of monikers, i.e. persistent COM+ objects used for
storing the state of other COM+ objects.
Using the naming and trading
services is typically not a complex task; thus, the middleware infrastructures
we assess here do not provide any
means to
further facilitate it. Table 5 summarizes the comparison of CORBA,
J2EE and COM+
concerning location transparency.
Concurrency Transparency

Table 6 : CORBA, J2EE and COM+ regarding concurrency
transparency.
CORBA enables the concurrent execution of requests.
However, the particular request processing models that can be employed
are not
precisely defined
in the standard. Following, we give typical models that may be supported
by CORBA
compliant infrastructures:
- The thread-per-request model: a new thread
is created for every request
delivered to a server.
- The thread-per-client model: a new thread is created for every
new client that requests services from a server.
- The thread-pool model: a fixed number of threads are used for
serving requests (this model should be provided by infrastructures
that comply
with the Real-Time
CORBA specification [CORBA-RT]).
Concurrency control can be achieved
using the CORBA Concurrency Control Service (CCS) - a basic locking
mechanism [CORBAServices]. The use
of CCS is not
transparent to the application; locks should be explicitly acquired
and released by the
application.
In J2EE, multiple requests may be delivered simultaneously
to a Java object. These requests are served in separate threads.
Concurrency
control is based
on standard Java synchronization mechanisms, whose employment can
be hidden under the use of the Java synchronized clause
(if we characterize operations
op1, op2 of a Java class with the synchronized keyword,
J2EE guarantees that upon the concurrent arrival of requests for
op1 and op2, op1
shall
start
after the end of op2, or the inverse).
COM+ allows the concurrent
execution of requests in the following sense. COM+ objects within
a server are organized into apartments,
depending
on the request-processing
model they use. There are two types of apartments: single-threaded,
and multi-threaded. A single-threaded apartment consists of exactly
one thread,
so requests to
COM+ objects that belong to it are served sequentially. A multi-threaded
apartment comprises more than one thread, assigned to requests
targeted to the objects
that belong to the apartment. Concurrency control in multi-threaded
apartments can be based on COM synchronization mechanisms (e.g.,
functionality that
realizes the IBlockingLock interface), whose use, however, is
not transparent to the
application. Table 6 summarizes the comparison of CORBA, J2EE
and COM+ regarding concurrency transparency.
Failure Transparency
CORBA was recently extended to support fault
tolerance. More specifically, the standard specification for Fault
Tolerant
CORBA [CORBAv3.0.2]
defines basic mechanisms and interfaces for replication,
checkpoint and recovery
of CORBA
object groups. From the client perception, the employment
of the fault tolerance mechanisms is transparent since groups
are used
as normal
CORBA objects.
Clients hold a group reference instead of an object reference
and request services
provided by the group. 
Table 7: CORBA, J2EE and COM+ regarding failure transparency.
Depending
on the particular replication style used, the CORBA infrastructure
either forwards a client request to one member (called primary object)
of the
group (passive replication), or multicasts the request to all members, while
guaranteeing totally ordered request delivery (active replication). In active
replication, whenever a member fails, the remaining replicas are used to guarantee
correct service provisioning. In passive replication the state of the primary
is either periodically stored in a log (cold-passive replication),
or loaded into one or more backup replicas (warm-passive replication).
Upon the occurrence of a failure, a backup object becomes the new primary.
CORBA further defines
mechanisms employed at the level of CORBA channels for request retry and redirection.
Fault tolerance support in J2EE and COM+ is limited; channels include mechanisms
for network/hardware fault detection and connection recovery.
Regarding intentional
faults, all three infrastructures provide security services for authorization,
authentication and encryption. The functionality provided
by those services is embedded in the communication channels. Hence, the use
of security services, in all three cases, is transparent to the application.
In CORBA, different kinds of secure channels may be employed, relying on
security protocols like SSL, GSS Kerberos and CSI-EKMA (those protocols
differ mainly
regarding the flexibility they provide in the delegation of identities and
privileges; SSL appears to be the least flexible protocol, since delegation
is not allowed). Security in J2EE and COM+ is based on SSL channels. However,
channels relying on other security protocols (e.g. Kerberos) are also supported
[Roman et al.99].
Table 7 summarizes the comparison of CORBA, J2EE and COM+
regarding failure transparency.
Migration Transparency
In CORBA there are two possible ways of migrating
an object. The primitive way is to invoke an operation on another object
that resides at the target
location and pass a copy of the object that is to be migrated as a parameter.
Then, the original copy can be destroyed. The migrated object must be passed
by value. The previous is possible in CORBA only if the migrated object is
a valuetype (i.e. a special kind of object, whose specification comprises
the definition of both the object’s interface and the object’s
state). CORBA channels can redirect requests issued by clients that hold
references
to the original copy of the migrated object. Consequently, the integrity
of the application is preserved. Passing objects by value is also possible
in
J2EE.
However, this primitive approach to object migration does not deal
with dependencies that may exist between a migrated object and other objects.
Such dependencies
may further impose the migration of the dependent objects. To deal with
these cases, CORBA provides a more sophisticated service called CORBA
LifeCycle
[CORBAServices].
Passing objects as parameters in CORBA and J2EE and using
the CORBA LifeCycle service is not transparent to the application.
Table 8 summarizes the
comparison of CORBA, J2EE and COM+ regarding migration transparency.

Table 8: CORBA, J2EE and COM+ regarding migration transparency.
Persistence
Transparency
In CORBA, references to an object may be either persistent,
or transient depending on the policies of the POA that manages the
lifecycle of the
object. Moreover,
CORBA provides the Persistent State Service (PSS) [CORBAServices], for
logging (resp. restoring) objects’ states to (resp. from) persistent
storage. Checkpoint and recovery of objects’ states is not transparent
in the sense that it is the responsibility of the application to log periodically
the state of its constituent objects. To achieve fully transparent persistence
we have to build persistent CORBA components instead of simple CORBA objects
and register them into CORBA containers. Upon registration, the containers
take over the responsibility of logging and restoring the components’ state.
 Table 9: CORBA, J2EE and COM+ regarding persistence
transparency.
In
J2EE, object references can be persistent. More specifically, if
a client tries to contact an object that can be activated, but is currently
not
active, the RMI Registry responsible for the object is contacted instead.
The daemon
shall reactivate the object and provide the client proxy with an updated
object reference. Regarding persistent storage, objects can use JDBC
or SQL/J to access
a database. The use of the previous facilities is not transparent,
unless
we built EJBs, instead of simple Java objects, and register them to
EJB containers that systematically log in database storage the state
of the
registered EJBs.
References to COM+ component objects are not persistent.
The state of component objects can be stored to a database, using
ADO or OLE-DB
interfaces. However,
the use of the aforementioned facilities is not transparent to the
application [Roman et al. 99]. Table 9 summarizes the comparison
of CORBA, J2EE and
COM+ concerning persistence transparency.
Transaction Transparency
CORBA comes along with the Object Transaction
Service (OTS) [CORBAServices], which realizes the well-known 2-phase-commit
protocol. Most implementations
of the OTS specification support the execution of both flat and
nested transactions. The use of OTS alone does not guarantee
isolation. To achieve the previous
we have to combine OTS with CCS. The use of OTS and CCS is not
transparent
to the application. More specifically, application objects that
participate in a transaction must register the resources they
use to a transaction
coordinator. Moreover, before serving transactional requests,
the participating objects
must try to acquire locks on their resources. When the transaction
completes, OTS releases all locks that have been acquired. Hence,
the first phase
of the well-known 2-phase-locking protocol is a responsibility
of the application, while OTS transparently performs the second
phase,
using
CCS functionality.
To achieve fully transparent transactional
processing we have to implement transactional CORBA components and
register them
into
CORBA containers.
Then, the containers handle client invocations appropriately
(e.g., they may implicitly
acquire locks, register resources, etc.). 
Table 10: CORBA, J2EE and COM+ regarding transaction
transparency.
J2EE
provides a service, named JTS (Java Transaction Service)
that is similar to OTS. One significant difference is that
JTS only supports the flat transaction
model. Moreover, container-managed transactions are supported for EJBs.
COM+ provides OLE transactions for the atomic and isolated
execution of invocations
on COM+ objects. Both flat and nested transaction models are supported.
Moreover, COM+ provides MTS (Microsoft Transaction Server),
a container for COM+ transactional
objects. Table 10 summarizes the comparison of CORBA, J2EE and COM+,
regarding transaction transparency.
Overall Assessment

Figure 2: Overall comparison of CORBA, J2EE and COM+,
regarding their standard specifications.
Figure 1 gives an
overall view of the results we obtained from the comparison
of CORBA, J2EE, and COM+. More specifically,
we counted one point-in-favor
of an infrastructure for every ( ) mark we gave in the detailed
comparison (for openness and access transparency we only counted
an overall
point-in-favor for each infrastructure because they all
have common features regarding
those properties). Figure 1(a) gives the points-in-favor per-requirement,
while
Figure 1(b) gives the total number of points-in-favor for each
infrastructure. From
both figures, we can come into conclusion that CORBA, in general,
provides more facilities for satisfying typical requirements
imposed by distributed
applications. To be fair with the other two infrastructures we
have to highlight that this conclusion is based on the comparison
of the standard
CORBA specification
with the specifications of J2EE and COM+. However, not all implementations
of the CORBA standard specification provide all of the CORBA services
and facilities we identified during the detailed comparison.
Based
on the previous remark, we examined a number of available
implementations of CORBA (omniORB, ORBacus, ORBIX, TAO, MICO),
regarding the availability
of the CORBA services and facilities we identified in the detailed
comparison. Then, we calculated the points-in-favor for each
implementation
and compared
them with those for J2EE and COM+. Figure 2 gives the results
from this comparison. With the exception of omniORB, all CORBA
implementations
appear better than
COM+. However, they are all quite close to J2EE.

Figure 3: Overall comparison of available
CORBA implementations, J2EE and COM+.
5 CONCLUSION
The main contribution of this paper is twofold:
(1) it proposes a comparison framework for middleware infrastructures
and (2)
presents a detailed
comparison of three widely used infrastructures in both industry and
academia: CORBA, J2EE and COM+. The comparison framework we propose
constitutes a foundation for further research we perform in the field
of MDA. More specifically, we currently work towards a developer-oriented
environment for MDA development, which relies in the approach proposed
in [Issarny et al.02]. The core element of our environment is a UML-based
representation for the specification of infrastructure independent
models of distributed applications. The comparison framework presented
here serves for specifying the applications’ technological requirements
and selecting a middleware infrastructure that provides functionality,
which can be used for satisfying those requirements. Our environment
further comprises automated procedures for: (1) refining infrastructure
independent models into infrastructure specific ones and (2) generating
code from infrastructure specific models.
Footnotes
1 These are representative
measures taken from extensive experiments performed in the
context of the CORBA comparison project [CORBABench], the EJB
comparison project [EJBBench] and [DCOM]. We consider that
these measures are sufficient to give an idea of the performance
overhead introduced by the infrastructures we examine. An extended
performance evaluation of CORBA, J2EE and COM+ is out of the
context of this paper. REFERENCES
[COM+v1.5] COM+ v1.5. Microsoft Corporation. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/htm/pgcontexts_1p0z.asp
[COM+Events]
COM+ Event Service. Microsoft Corporation. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/htm/pgservices_events_5x4j.asp
[CORBAv3.0.2]
Common Object Request Broker Architecture (CORBA/IIOP) v.3.0.2.
OMG Document, formal/2002-12-06 http://www.omg.org/technology/documents/for
mal/corba_iiop.htm
[CORBABench] CORBA Comparison Project Web site. Distributed
systems Group, Charles University. http://nenya.ms.mff.cuni.cz/projects.phtml?p=cbench&q=3
[CORBA-CCM]
CORBA Component Model (CCM). OMG Document formal/2002-06 65.
http://www.omg.org/technology/documents/formal/components.htm
[CORBA-RT]
Real-Time CORBA v1.1. OMG Document, formal/2002-08-02. http://www.omg.org/technology/documents/formal/real-time_CORBA.htm
[CORBAServices] CORBAServices Specification. OMG Document.
http://www.omg.org/technology/documents/corbaservices_spec_catalog.htm
[DCE-RPC]
DCE 1.1: Remote Procedure Call. Open Group, 1997. http://www.opengroup.org/onlinepubs/009629399/toc.htm
[DCOM] DCOM Technical
Overview. Microsoft Corporation. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/htm/pgservices_events_5x4j.asp
[EJBBench] EJB Benchmarking Web site. Distributed Systems
Group, Charles University, Prague. http://nenya.ms.mff.cuni.cz/projects.phtml?p=ejbc&q=4
[Emmerich00]
W. Emmerich. Software Engineering and Middleware: A Roadmap.
The Future of Software Engineering, ed. A. Finkenstein,
pp.117-129
2000.
[Issarny et al.02] V. Issarny, C. Kloukinas and A. Zarras.
"Systematic Aid for Developing Middleware Architectures". Communications
of the
ACM (CACM), vol. 45, no. 6, pages 53-58, 2002.
[J2EEv1.4] The Java 2
Enterprise Edition (J2EE) Specification v.1.4. Sun Microsystems.
http://java.sun.com/j2ee/
[JavaRMI] Java Remote Method Invocation
(RMI). Sun Microsystems. http://java.sun.com/j2se/1.4.1/docs/guide/rmi/spec/rmiTOC.html
[Henning et al.98] M. Henning and S. Vinosky. Advanced
CORBA Programming with C++. Addison Wesley, 1998.
[Gopalan98] S. R.
Gopalan. A Detailed Comparison of CORBA, DCOM, and Java/RMI.
OMG whitepaper, 1998. http://my.execpc.com/~gopalan/misc/compare.html
[Laprie85]
J-C. Laprie. "Dependable Computing and Fault Tolerance: Concepts
and Terminology". In Proceedings of the 15th International
Symposium on Fault-Tolerant Computing (FTCS-15), pp. 2-11, 1985.
[Lo
et al.98] S. Lo and S. Pope. "The Implementation of a High
Performance ORB over Multiple Network Transports". AT&T
Labs Cambridge, Technical Report 98.5, 1998. http://www.uk.research.att.com/abstracts.html
[MDA]
OMG: Model Driven Architecture. OMG Document ormc/2001-07-01, 2001.
http://www.omg.org/mda.
[ORBIX] ORBIX v.3 Web site. http://www.iona.com/products/orbix3_home.htm
[RMODP] ISO/IEC. Open Distributed Processing Reference Model
(RM-ODP) Part 3: Architecture, 1995.
[Roman et al.99]
E. Roman and R. Oberg. "The Technical Benefits of EJB and
J2EE Technologies over COM+ and Windows
DNA". The MIDDLEWARE
Company,
1999.
http://www.middleware-company.com
[Plasil et al.98] F.
Plasil and M. Stal. "An Architectural View of Distributed
Objects and Components in CORBA, Java RMI and
COM/DCOM". Software Concepts
and Tools, vol. 19 no.1, 1998.
[Puder et al.00] A. Puder and
K. Romer. MICO and Open Source CORBA Implementations. Morgan
Kaufmann Editions, 2000.
[Schmidt et al.98] D. C. Schmidt,
D. L. Levine and S. Mungee. "The Design of the TAO Real-Time
Object Request Bromer".
Computer Communications,
vol. 21 no. 4, pp. 294-324, 1998.
About the author
Apostolos Zarras got his Ph.D. in the year
2000 from the University of Rennes I, France. From 2000 to
2002, he worked as a research engineer at INRIA-Rocquencourt,
France. Currently he is a visiting assistant professor at the
University of Ioannina, Greece. His current research interests
include model driven architecture development, adaptive middleware,
and quality analysis of software systems. He can be reached
at zarras@cs.uoi.gr.
Cite this article as follows: Apostolos Zarras: "A Comparison
Framework for Middleware Infrastructures", in Journal
of Object Technology, vol. 3, no. 5, May-June 2004, pp. 103-123. http://www.jot.fm/issues/issue_2004_05/article2
|