This paper discusses common basic concepts
found on a set of different component models: JavaBeans,
COM, EJB and CCM. It provides an overview of the basic features
found on component models in general and then gives more detail about
these concepts in the context of these particular component models.
1.-
Introduction
Many component
technologies exist today. Among
them, some of the most well known include Microsoft's COM [COM] and .NET [NET],
Corba's Component Model [CCM]
and Sun's JavaBeans [Beans] and
Enterprise JavaBeans [EJB]. These
technologies target different types of applications, from the visual
assembly of client-side applications to the construction of complex
server-side applications. Since all these technologies claim to be
component-based, it is interesting to question what are the common
concepts that exist among them. The study of these common concepts is
not an easy task mainly because these component technologies are
described in large specifications which often make an excessive
emphasis on implementation details and not so much on the concepts.
This paper will discuss common concepts between the following
technologies:
-
COM: Microsoft's Component Object Model which
appeared in the mid 90's [COS]
resulting from earlier tentatives to solve needs such as embedding
Windows applications within each other. COM is a binary standard, so it
supports components written in different languages to interoperate.
Initially the model only supported "local" distribution, that is
communication in the same machine by different processes, but was later
extended to suport physical distribution and its name was changed to
distributed COM or DCOM [DCOM]
(in this paper, only basic COM is discussed). The ideas introduced by
COM have inspired other successful component models like Dassault
Système's Object Modeler [OM]
and Gnome's Bonobo [Bonobo].
-
EJB: Sun's Component Model oriented towards
the construction of distributed server-side applications. This model
introduced many facilities for adding certain non-functional aspects
to the components, such as security, distribution and persistence. It
also introduced a more 'formal' deployment model than the standard
JavaBeans
one.
-
CCM: The Corba Component Model which, as EJB, is
oriented towards the construction of distributed server-side
applications. This model is very similar to EJB in many aspects. One
important difference with EJB is that CCM supports multiple languages
since it is built on top of CORBA.
The next section
gives a brief discussion on the features that characterize components,
section 3, 4 and 5 will discuss components at three levels : components
at the type level, at the instance level and at the deployment level.
Section 6 will also discuss issues relative to the component framework.
2.-
Components
One of the main
promises behind components is reuse. The basic idea is that
applications should not be built from the ground-up, but they could
rather be built like electronic circuits, where some integrated
circuits are bought and wired among each other, creating connections
among their ports. This appealing idea sounds simple but unfortunately
its
realization is not, starting with the difficulty of finding a
definition of what a component is in the software realm. In the
litterature, there exists no consensual definition for this concept,
instead, many definitions for the word component can be found, each
reflecting a particular point of view. Some people consider that
components can be source code units, altough the models studied in this
paper all follow a "black-box" approach where the source code is not
available. This approach is close to the definition for components
given by Clemens Szyperski:
"A Software Component is a
unit of composition with
contractually specified interfaces and explicit context dependencies
only.
A software component can be deployed independently and is subject to
composition
by third parties" [SZY]
This definition,
however, misses some aspects that will be discussed in this paper. In
particular it doesn't mention explicitly that components, like object
oriented classes, can create instances (something that has no
equivalent in the hardware realm), that they can be customized or that
non functional-properties can be defined for the components. In this
paper, components will be studied under three points of view:
-
Components as types (instance
template). A Component type is used to create instances usually with
the help of a factory [GAMMA].
A Component type includes the external view of a component, that is
its interface, and defines the way that this interface
is implemented. This interface describes what is provided and what is
required by the component type and its instances. A component type can
have properties that are applied at the type level, and in particular
this concerns non functional properties which affect all of the
instances
of the component type.
-
Component as instances: this is comparable to objects in
the object-oriented world. Component Instances connected between each
other give rise to applications. In the component world, instances can
be persistent and accessible through a key that identifies them.
Component
instances are sometimes embedded into a container which is
a mechanism to deal with the non-functional properties defined for the
component
type from which the instance originates. Instances may also receive a
reference to their context, which represents the 'place' where
they are executing. This context often serves as an interface to access
the
component framework.
It is important to
underline that in the litterature, the word component is often used
when referring to either the instances, the component types or the
bundles. This leads to many confusions, and for that reason this
article will try to be rigorous in pointing out if a discussion is
relevent to a component instance, type or deployment unit. In case the
word component is used without precision, it is supposed to make
reference to the component type level.
The component framework is a software
infrastructure that provides runtime services to the components and to
their instances. These framework services include:
The next section begins with a discussion of components
on the first level that was mentioned, that is at the component type
level. It compares the different models with respect to the way they
define
a type and the way they create instances.
3.- Component
types and factories
A component type is
a concept similar to a class in the object oriented world. The
component type is defined by the external view of a component, which is
built from a set of ports, and the way these ports are
implemented. Depending on the component model, the external view may
only offer a single kind of port such as an interface, or it may give a
more complete description of what the component provides and requires
and about its properties.
The implementation of a
component type is often hidden from clients to enforce the use of
interfaces. This, however, poses a problem for clients who cannot
create instances of the implementations. To solve that issue and to add
flexibility, the factory pattern is often used to create the
component instances and each factory is associated
to a particular component type. Factories are special objects (normally
singletons) whose responsability is to create instances of a particular
component type. Being objects, they have an interface which can include
properties that would be equivalent to static properties (shared by all
instances) in standard object-oriented classes. This pattern is
discussed
thoroughly by Gopalan Suresh Raj in [Raj].
The use of component factories also introduces the need of location for
these factories, which must in consequence be uniquely identified (a
factory
being associated to one component type, this means that component types
are
uniquely identified too).
Some component
models allow the addition of the so called non-functional
properties, such as distribution, security and persistence to component
types. These properties are added to the component type without the
need to modify the code of the implementation. When instances of the
component type are created, they are embedded in what is called a container
which is responsible for handling these non-functional aspects, often
by acting as a proxy between the client
and the component instance and capturing the calls to the component
instance.
The following
paragraphs give a bried description of the way these features appear in
the component technologies studied in this paper.
JavaBeans :
JavaBeans component types are
standard Java classes that have certain constraints such as a
no-parameter constructor and that follow a set of naming conventions on
their methods. The name of the methods implemented by the JavaBean
class describe the different characteristics (ports) of the JavaBean
instances: their callable methods, event sources, event sinks and
properties. A JavaBean component, as any standard Java class, can
implement several interfaces, however, all of the methods of the
interfaces must be implemented by a single object.
In the JavaBeans component
model, there are no factories for creating instances of the component
types, instead there is a factory method provided by a particular class
(java.beans.Beans).
JavaBeans are not registered in a registry, they are found by following
the standard Java classpath, this results in the fact that only one
version of a JavaBean can be available.
COM :
COM components are
characterized by the fact that they can
implement different interfaces and that these interfaces need not to be
implemented
by a single object. COM interfaces are described in an Interface
Definition
Language (IDL) where every interface is identified in a precise way by
a
unique number (UUID). A COM interface describes the methods that can be
called
on the component instance, but does not describe the required
dependencies
of the component. COM makes a strong emphasis in the fact that a
published
interface can never change, and the fact that a component can implement
several
interfaces is proposed as one solution to solve the problem of
interface
evolution.
In COM, component types are
associated to COM Class Factories (also known as Class Objects), which
allow instances to be created.
Factories must implement a particular interface called IClassFactory
which provides a method to create the instances, though other
specialized
interfaces can be provided too. These factories are also associated a
unique
identifier called a CLSID so that they can be retrieved (COM also
provides
a mechanism called Monikers to avoid coupling a client to a
particular
implementation). The Windows registry is used to register the COM
factories.
EJB :
EJB component types are
different from COM ones by the fact that an Enterprise Java Bean cannot
implement multiple interfaces. An EJB component provides a unique
interface to its clients, called the remote interface. The
implementation of this interface
is called the Enterprise Bean Class.
In the EJB component model,
component instance factories are called homes. In a similar way
to COM's factories, EJB homes provide a method to create instances. In
addition to the creation of instances, homes allow the search of entity
instances, which are named and persistent. When instances
are created, they are embedded inside a container that is responsible
for handling non functional aspects.
Since EJB is a distributed
component model, the retrieval of a component must be done by doing a
distributed lookup with the help of a JNDI server. EJB are identified
in a particular naming context.
CCM :
CCM component types introduced
an innovation with respect to other component models: the possibility
for a component to implement several times the same interface. For this
purpose interfaces (called
Facets) along with the other ports that define a CCM component type are
named. The other named ports that are declared by a component type are:
Receptacles to connect a component instances between each other,
Event Sources and Event Sinks and Attributes.
In CCM component instances are
created through factories that are also called homes. Homes provide
methods for creating, removing and searching component instances. As in
EJB, component instances are embedded inside a container.
CCM is a distributed component
model, components are retrieved
by doing a distributed lookup.
This section has described components
as units of instantiation called component types. The characteristics
that have been found in the different models are the following:
Characteristic \ Model
|
JavaBeans
|
COM
|
EJB
|
CCM
|
Existence of component
type concept ?
|
YES
|
YES
|
YES
|
YES
|
Use of factories to create
instances ?
|
NO
|
YES
|
YES
|
YES
|
Factories provide method
to recover named
instances ?
|
NO
|
NO
(standard factories)
|
YES
|
YES
|
Non functional properties
can be attached to the
component type ?
|
NO
|
NO
(standard COM)
|
YES
|
YES
|
Table 1. Summary of features at the type
level.
The next section will give more detail
about component instances and the way assemblies are created by
connecting
these instances.
4.- Components instances, assemblies,
containers and contexts
The previous section has discussed
component factories as a means to create component instances. Instances
are the 'real' entities from which component-based applications are
built. There are two ways in which the instance of a component can be
connected to another instance: through instantiation and association.
Instantiation occurs when a component instance request the creation of
another component instance. This is
usually done by first doing a lookup on a factory and then a call on
the creation method. Association occurs when a third party connects
two instances by passing references to the component instance. This of
course is a simplified vision, since an instance that creates another
one through instantiation can then act as a third party to connect
other
instances. An assembly is a graph of connected instances.
There are often discussions about
component models being recursive. In this paper, a component model is
considered to be recursive if an assembly can become the implementation
of a component type.
This can be done at the code level or in a descriptive way, in which
case
it is said to be direct. The mechanisms needed for direct recursivity
allow
the ports in the external view of the component to be connected to
elements
in the assembly [CER].
Certain models place the component
instances inside containers, which are special objects that
play the role
of proxies between the clients of the component instance and the
instance itself. Containers intercept the calls that are targeted to
these instances (or to their factories) and then act for example by
checking security restrictions and refusing a call to a particular
method.
The concept of context is
different to that of container. The context is not a proxy between
clients and a particular instance, it is rather a provider of services
for an instance and can
act as a bridge to the component framework. The container can, however,
be the provider of the context for the instances.
The following paragraphs describe
how these aspects are represented in the different component models:
JavaBeans :
In JavaBeans, component
instances are used for two different things: to become prototypes for
other instances (as it was described in the previous section) and as
elements in an assembly. The JavaBeans model promotes assembly creation
through association, with a third-party connecting instances between
each, although instantiation relationships can exist too. Assemblies
can be stored in a special XML format, the JavaBeans model, however, is
not considered to be recursive directly since this format doesn't allow
the assembly to become itself a JavaBean (this can be done
programmatically though).
It is possible to serialize a
JavaBeans instance to later use it as
a prototype, in that case the instance (which is not uniquely
identified)
is indistinguishable from the component type. The JavaBeans model
doesn't
support instance lookup, that is the possibility of finding a named
instance.
In the JavaBeans model there is
no concept of container, instances are connected directly to each
other. A later addition to the specification introduced the notion of a
context which allows the creation of hierarchies of component
instances, this context can also provide services
to the instances that it contains. To be included in a context, the
JavaBean must implement a particular interface, so contexts are not
used by default.
COM :
In COM, an instantiation model
is followed to connect component instances between each other since
facilities to locate factories are provided. The code that creates
instances of other components is normally the implementation of a
component type itself, so this model supports recursivity in a direct
way. Two different techniques are used to build a component type out of
instances of other component types: containment or aggregation
[WHI].
COM supports a mechanism
similar to JavaBeans for creating instances from a serialized state,
that is a prototype. In JavaBeans, prototypes are searched
automatically upon instance creation, in COM, however, the client must
use a particular method (CoGetInstanceFromFile)
and provide a file name. COM doesn't provide a standard mechanism to
find named instances.
EJB :
The EJB model organizes component instances in different
categories:
-
Stateless session: An instance created only for a
limited period of time which has no state, so that its only goal is to
be a service (receive values through method calls and return a result).
This instance might be shared.
-
Stateful session: An non-shared instance created only
for a limited period of time which has a state. The typical example for
this is a kart in an e-commerce application
-
Entity: A persistent
instance identified by a "primary" key that is unique. The state of the
instance is typically stored in a database. This type of instance must
be destroyed explicitly.
Every time an instance is
created, it is placed inside
a container that implements a set of non-functional policies. The
container interposes itself between the clients of the instance and the
instance itself and captures the calls to the instance methods. The
container itself is placed inside a server that gives it access to the
infrastructure. A bean instance receives a context that allows it to do
things such as lookups on the homes of other EJBs.
As in COM, some Enterprise
JavaBeans are created specially to create instances of other components
(typically by the application assembler [ROM]),
though these assemblies are done at the code level and there is no
standard way to describe them.
CCM:
The Corba Component Model has
categories of instances similar to those introduced by EJB, it also
introduces a persistent non named
type of instance (called a process). In the same way, instances
are
placed inside a container.
In CCM assemblies are described
in a special file called an assembly descriptor. Since CCM component
types describe the interfaces that a component instance requires,
called the receptacles, the assembly descriptor allows graphs
of instances of components to be described. CCM doesn't support
recursivity since an assembly cannot become the implementation of
another
component type.
This section has
described the instance level in component models. Even though instances
are never mentioned as being of importance in component definitions,
they clearly play a major role in the models studied in this paper. The
following table summarizes characteristics related
to the instance level in the component models studied in this paper:
Characteristic \ Model
|
JavaBeans
|
COM |
EJB |
CCM
|
Instances can create other
component instances ?
|
YES
|
YES
|
YES
|
NO
(?)
|
Assemblies described ?
|
YES
|
NO
|
NO
|
YES
|
Recursivity supported
directly ?
|
NO
(yes
at code level)
|
NO
(yes at code level)
|
NO
(yes
at code level)
|
NO
|
Named Instances available ?
|
NO
|
NO
|
YES
|
YES
|
Persistent instances ?
|
YES
(for
prototypes)
|
YES
(for prototypes)
|
YES
|
YES
|
Instances are placed inside a
container ?
|
NO
|
NO
(?)
|
YES
|
YES
|
Instances receive a context ?
|
NO
(unless
explicited)
|
NO
(?)
|
YES
|
YES
|
Table 2. Summary of features at the instance
level.
5.-
Deployment
units
The definition
given by Clemens Szyperski about a component (see section 2.)
explicitly states that the component can be deployed
in an independent way. This aspect is extremely important to allow a
component to be reused in different contexts. Sometimes, the deployment
unit is considered to be the component itself, for example in the COM
vocabulary, the word component makes reference precisely to the
deplyoment unit. It must be noticed
that these units are tipically used to deploy component types and not
instances
(except for prototypes). To be deployed, a component must be first
delivered
(transferred) to a particular location, this paper considers that the
delivery
and deployment units are the same.
Deployment units
often contain information (called meta-information) about
their contents, about their dependencies and about their version
number. This information is necessary for the person or the application
that manages the deployment units to know if the dependencies of the
component are resolved so that there will be no problems during
instantiation. When components are delivered as "black boxes" (their
source code is not available), it is also necessary to provide some
kind of mechanism to allow changes in the component properties to be
done so that the component can be fitted to the particular environment
where it is deployed. This mechanism takes
shape as a file that can be modified and that is sometimes called a deployment
descriptor. The deployment step frequently includes the
registration (or publishing) of the components (through their
factories) included in the deployment unit so that they can be used by
clients, though this registration can also happen dynamically, that is
during execution.
Altough Szyperski's definition states that a component can be
deployed independently, in the different component models studied in
this paper, deployment units can contain several components. The
following paragraphs give a more detailed description on the way these
aspects are expressed in the different models:
JavaBeans:
JavaBeans are delivered in a special file called a JAR file
that contains: the binary code of the components, serialized instances
(prototypes)
and resources. This JAR file also contains a special file called a Manifest
that gives basic information about the component types that are
contained
along with their dependencies inside of the JAR file. Versioning and
information
about other types of dependencies is not treated in the JavaBeans
component
model.
Deployment of JavaBeans is
done by placing the JAR files on a path that is searched by the JVM
when it loads classes called the classpath. There is no
explicit registration of the components types and this means that only
the first occurrence of a component type will be loaded and
also that only one version of a component type can exist at a
particular moment.
JavaBeans doesn't provide
mechanisms to change properties in the components other than through
prototypes (described in the previous section).
COM:
COM binary modules are referred
as COM components which are the dployment units in the COM model. They
take shape as two different kinds of files: EXEs (executable) and DLLs
(dinamically linked library). These deployment units can contain
several components types and their associated factories.
COM supports the dynamic registration of factories, this
means that a factory can be registered during execution. Factories are
registered
in the windows registry along with the CLSID number that identifies
component types.
Version information can be included in the deployment file,
although this is not mandatory, which can cause problems.
EJB:
Enterprise JavaBeans are delivered in an EJB-JAR file which
is the same kind of file used to deliver standard JavaBeans. EJB-JARs
are used to deliver a single component or an application (a collection
of inter-dependent
components). The EJB-JAR file contains a deployment descriptor that
gives
information about the beans it contains. This information specifies for
a component the location of its remote interface, its home and of its
implementation.
It also describes the policies that the container must apply on the
components and that can be changed depending on particular needs.
When a bean is deployed, the
home is registered in a naming service with the help of a nickname which
the client will use to find the home in a particular naming context.
Inside the deployment descriptor, it is possible to express
dependencies at the component type level.
CCM:
CCM component types are delivered in a Zip file called
a component package. Assemblies are delivered in an assembly archive.
The
component package file contains a deployment descriptor similar to
EJBs,
altough in CCM there are no dependencies at the component type level
since
component types describe their receptacles, that is the ports that need
to
be connected by a third party that interprets the assembly information.
This section has described how deployment is
realized in the different component models studied in this paper. The
following
table summarizes this comparison.
Characteristic \ Model
|
JavaBeans
|
COM |
EJB |
CCM
|
Deployment unit can
contain several instantiation
units ?
|
YES
|
YES
|
YES
|
YES
|
Deployment unit contains
meta-information ?
|
YES
(basic)
|
YES
(basic)
|
YES
|
YES
|
Deployment descriptor
with settable properties ?
|
NO
|
NO
|
YES
|
YES
|
Table 3. Summary of features at the
deplyoment level.
The next section
focuses on the component framework, which is the infrastructure that
provides runtime services to the components.
5.- The
Component Framework
The
previous sections have discussed components at tree levels : the
instance, the type and the deployment unit. Components, however, need a
set of runtime services to operate. These services might be accessible
to the component instances through a context passed to the instances or
by means of a global API. The containers that
surround component instances also need services provided by the
component
framework. Among the services provided by frameworks, the following can
be
mentioned:
The way these features are implemented in the different
models is the following:
JavaBeans:
JavaBeans instances don't receive a context reference by
default, and the framework services are rather provided by some classes
that have static methods. These classes are java.beans.Beans
and java.beans.Introspector. In JavaBeans
there is
no concept of factory, so the framework classes only allow requests for
creation
of instances based on a component type. Introspection information is
obtained
in two different ways, either through standard Java type information or
by
including a special class along the bean when it is packaged. This
particular
class, called a beaninfo is responsible for providing the
introspection
information, and the introspector will first look for it when
information
about a component is needed.
When BeanContexts are used, JavaBeans instances can use them
to request services that are registered with the context.
COM:
In standard COM, factory lookup
is done through the COM API which is accessible to every instance.
Introspection facilities mainly include the possibility to ask an
instance if it implements a particular interface (QueryInterface).
EJB:
In the Enterprise JavaBeans
model, the component framework provides support for the containers and
the instances they contain. The
instances can access the component framework through the context they
receive
which allows them to access their home object. They can obtain other
homes
by using a JNDI naming context. The container uses services provided by
the framework, which in this case is a middleware, to apply the
non-functional
requirements of the components.
CCM:
The role of the CCM framework is very similar to the
EJB one. One difference is that the underlying middleware is Corba. CCM
component instances may not be able to do factory lookups to internally
create other instances, since they expect to be connected externally
through their ports.
6.-
Summary and Conclusions
This paper has
described a comparison between four component models: JavaBeans, COM,
EJB and CCM. These models were compared at three different levels :
component type level, instance level and deployment level. Their
frameworks are also compared briefly. From this conceptual comparison,
a series of common features arise:
Concept
|
Motivation
|
Component Type
|
A template for instance creation
which includes:
- External view : provided and required interfaces, properties
- Internal view : implementation of external view
- Non functional requirements
|
Component Factory
|
Creation, destruction and
retrieval
of component instances
- Named
|
Component Instance
|
Created from component types
through factories
- Named
- Persistent
- Sharing
|
Container
|
Surrounds a component instance and
becomes a proxy between the clients of the instance and the instance by
intercepting calls and applying non-functional requirements.
|
Context
|
Provides services to the component
instance
- Bridge to the component framework
- May be provided by the continer
|
Assembly
|
A graph of component instances
connected between each other through their ports.
- Can become the implementation of a component type.
|
Deployment unit
|
Used to deliver component types
(including their factories) and their resources.
- May
contain one or more component types
- Contains
meta-information about the contained component types
- External view
- Dependencies (between component types and
environment)
- Version information
|
Component Framework
|
Provides runtime services to the
component instances and their containers, can be built on top of a
middleware such
as CORBA.
- Factory lookup
- Introspection facilities
- other services (persistence,etc...)
|
Table 4. Common component concepts.
Altough these features don't appear in every
model (in particular the containers), the features on this list should
be expected to exist in any component model. This list is also useful
to provide a way to compare other component models.
It is interesting to notice that some of these
features exist in object-oriented languages too. With the exception of
containers, contexts ,the component framework as a well defined entity
and deployment units with meta-information, the rest of the concepts
are not really new. New languages such as the ones introduced by
Microsoft in the .NET framework are incorporating some of the concepts
mentioned here, particularly at the deployment unit level,
where meta-information has now become standard.
7.-
Bibliography
[Beans] Sun Microsystems, "JavaBeans
Specification", Version 1.0.1, 1997
[Bonobo] "Bonobo Component Model" : http://developer.gnome.org/arch/component/bonobo.html
[CER] H. Cervantes, J.M. Favre, F. Duclos "Describing
Hierarchical Compositions with the Beanome Language", Proceedings
of the Workshop on Software Composition (SC 2002), April
2002 Grenoble, France.
[CCM] "Corba Component Model" : http://ditec.um.es/~dsevilla/ccm/
[COM] Microsoft "Component Object Model" : http://www.microsoft.com/com/
[DCOM] Thuan L. Thai, "Learning DCOM",
O'Reilly & Associates, 1999
[COS] "The Evolution of Components" http://www.componentsource.com/AboutComponents/ComponentEssentials/TheEvolutionOfComponents.asp
[EJB] "Enterprise Java Beans": http://java.sun.com/products/ejb/index.html
[GAMMA] E. Gamma et Al., "Design Patterns :
Elements of reusable Object-Oriented software", Addison Wesley, 1995
[NET] Microsoft "the .NET framework": http://www.microsoft.com/net/
[OM] Remy Sanlaville, "Software Architecture: An
industrial experimentation with Dassault Systèmes"
http://www-adele.imag.fr/~sanlavil/Recherche/These/These.html
(in french)
[Raj] Gopalan Suresh Raj, "The Factory
Method (Creational) Design Pattern" http://gsraj.tripod.com/design/creational/factory/factory.html
[ROM] Ed Roman, S. Ambler, T. Jewell "Mastering
Enterprise JavaBeans, Second Edition", Wiley Computer Publishing,
2002
[SZY] Clemens Szyperski and Cuno Pfister, "Special
Issues in Object Oriented Programming" Workshop on
Component-Oriented Programming at ECOOP 1996
[WHI] Andrew Whitechapel, "Containment and
Aggregation", CodeGuru website http://www.codeguru.com/atl/containmentAndAggregation.html
|