Source Page[1]
Inside DCOM: Microsoft's Distributed Object Architecture Extends the
Capabilities of COM to Work Across the Network.
By Mark Roy and Alan Ewald"
-----------------------------------------------------------------------
Complex multitier applications are becoming more and more commonplace as
companies rush to meet their information processing needs. Distributed
object computing is a key enabler for these applications: It combines
object-oriented concepts with client/server technology to produce a
framework for building modular and scalable distributed applications at
a relatively high level of abstraction.
To date, the Object Management Group's CORBA specification and
corresponding products have provided the distributed object computing
platform of choice. [For more information on CORBA, see Warren Keuffel's
article in DBMS , March 1997[2] , page 42.] Software professionals must
now seriously consider another distributed object architecture from
Microsoft Corp. called Distributed COM, or DCOM.
DCOM is an extension of the Component Object Model (COM), which has been
part of the Windows family of operating systems for many years as the
underlying framework that makes OLE, and more recently ActiveX,
possible. COM is an object-based framework for developing and deploying
software components. COM lets developers capture abstractions as
component interfaces and then provide binary classes that implement
those interfaces. Encapsulation is enforced by COM such that client
applications can only invoke functions that are defined on an object's
interface.
COM's binary interoperability standard facilitates independent
development of software components and supports deployment of those
components in binary form. The result is that ISVs can develop and
package reusable building blocks without shipping source code. Corporate
application developers can use COM to create new solutions that combine
in-house business objects, off-the-shelf objects, and their own custom
components.
DCOM extends COM to the network with remote method calls, security,
scalability, and location transparency. As DCOM becomes available on
platforms other than Windows NT and Windows 95, companies can build
software architectures that take advantage of their existing
infrastructure and deploy business objects that access legacy
applications and databases.
In this article, we present an overview of the DCOM architecture. We
begin with a discussion of the fundamentals of COM and then show how
DCOM extends the architecture for the network.
COM Overview
COM is an object-based programming model designed to allow development
of software components at different times by different vendors using a
variety of languages, tools, and platforms. Once developed, COM
components are easily deployed and integrated in a customer's
environment. To appreciate how COM development and deployment is
possible, it is important to understand some of COM's key concepts,
including interfaces, classes and servers, object life cycle, binary
interoperability, and location transparency.
Interfaces
A COM interface defines the behavior or capabilities of a software
component as a set of methods and properties. An interface is a contract
that guarantees consistent semantics from objects that support it. Each
COM object must support at least one interface (called IUnknown),
although it may support many interfaces simultaneously.
Component designers describe interfaces using Microsoft's Interface
Definition Language (MIDL), an object-oriented extension of the DCE RPC
IDL. Microsoft provides an MIDL compiler that generates proxy and stub
code in C or C++ from an interface definition. The generated proxy code
provides a client-side application programming interface (API) for
objects that support the interface in question. Stub objects decode
incoming client requests and deliver them to the appropriate object in
the server. Internally, the proxy and stub code interact with the
appropriate runtime libraries to exchange requests and responses. The
COM runtime software is smart enough to bypass this extra work in the
case of objects deployed in the same process as the client.
Component designers assign a universally unique identifier (UUID) to
each interface to eliminate any ambiguity that might arise from name
collisions. The identifier, called an interface identifier or IID, is
also the cornerstone of COM's interface versioning model.
Each COM object must support at least the standard IUnknown interface.
IUnknown defines methods that provide the basic building blocks for
managing object life cycles and allowing graceful evolution of
interfaces supported by an object.
The QueryInterface method of IUnknown is used by clients to determine
whether or not a particular interface, specified as an IID, is supported
by an object. Over time, an object may support new interfaces or new
versions of the same logical interface, each with its own unique IID.
Existing clients can continue using an earlier version of an interface
without even being recompiled, and new clients can query for -- and take
advantage of -- the latest version of the interface.
QueryInterface returns a pointer called an interface pointer.
Internally, an interface pointer points to a data structure that is
dictated by COM's binary interoperability standard (further described
later in this article). The standard dictates the way interface
functions must be called, regardless of differences in the
implementation environments of the client and server programs.
Classes and Servers
Interfaces by themselves are not sufficient to build complete COM
applications. A COM class is a body of source code that is, among other
things, an implementation of one or more COM interfaces. It provides
real functions in any supported programming language for each interface
method it supports.
Just as each interface is uniquely identified by an IID, each COM class
has a unique identifier, called a CLSID. To interact with a component, a
client application must know about (or be able to find out about) at
least one CLSID and an IID for an interface that is supported by that
class. Using this information, a client can ask COM to create an object
and return an appropriate interface pointer.
One or more COM classes are packaged into a server using one of several
available techniques. A COM server can be packaged as a dynamic link
library (DLL) that is loaded into the client process when a class within
the server is first accessed by a client. This is called an in-process
server. An ActiveX control is an in-process COM server. A COM server may
also be packaged as a separate executable. This type of server can run
on the same machine as a client or on a remote machine that is
accessible using DCOM. These servers are called out-of-process servers.
The client code for interacting with the different kinds of COM servers
is identical.
Client applications interact with COM objects through interface
pointers. Encapsulation provided by COM ensures that a client is not
dependent on any implementation details of a COM object. In the case of
in-process COM servers, calls made by a client using an interface
pointer go directly to an object that is created in the client's
process. Calls to objects in an out-of-process server go first to an
in-process proxy object responsible for invoking the request using a
remote procedure call. In the out-of-process server, a stub object
receives each incoming call and dispatches it to the appropriate COM
object. Figure 1[3] shows a COM client interacting with COM objects
packaged in several different ways.
Object Life Cycle
Now that you have a basic understanding of the concepts of interface and
class and the communication between COM client and server, let's examine
how a client causes a COM object to be created in the first place. Each
COM object is an instance of a COM class. Each COM class is associated
with another COM class called a class factory, whose job is to create
instances of a COM class. COM's factory mechanism is illustrated in
Figure 2[4] . The factory typically supports a standard interface
defined by COM, called IClassFactory. Given a CLSID and a description of
the associated COM server, the COM runtime can locate a factory for the
given CLSID.
A client application interacts with the factory for a COM class in a
standard way to create an instance of the class and obtain an interface
pointer to the resulting COM object. Figure 3[5] shows an example of how
COM interfaces, classes, and objects relate.
Once a COM object has been created, COM specifies a standard protocol
for tracking how many outstanding references there are to an object and
when that object can be destroyed. COM objects maintain a reference
count that is manipulated through the AddRef and Release methods defined
on the IUnknown interface. Each COM class must implement these methods
to track the number of current uses of its instances. At the discretion
of the developer, this reference tracking can be done as a single count
for the entire object or as individual counts for each interface the
object supports.
When a reference count goes to zero, it is assumed that there are no
longer any clients referring to the object, and thus it can be
destroyed. Any methods that return interface pointers, including
QueryInterface, must call AddRef to indicate a new reference to an
object. Clients using interface pointers must call Release when they are
finished accessing an interface pointer.
Binary Interoperability
A central theme of COM is interoperability of components. To that end,
COM defines a binary call standard that dictates the layout of the call
stack for all method invocations. DCOM augments this interoperability by
defining a network interoperability protocol. These interoperability
specifications enable developers to focus on building components without
worrying about customizing them for different client environments. The
binary standard makes it easy to use off-the-shelf components without
having access to source code.
The binary standard defines an interface pointer as a pointer that
points to a pointer to a function table. For in-process servers, the
function table points to actual object implementation functions. For
out-of-process servers, the function table points to proxy functions.
Packaging Transparency
A key feature of the COM architecture is packaging transparency.
Developers can deploy components as DLLs or as executables. COM client
applications need not be concerned with how a server is packaged or
where its DLL or executable is located. Instead, the application uses
COM to create objects based on a desired CLSID. The client can restrict
the kind of server but does not need to do so. The client code for
interacting with an in-process server is identical to that for calling
out-of-process servers.
The COM Library locates the implementation of a requested class and
establishes a connection between the client and the server. COM offers
this service by requiring providers of COM classes to register
information about the type of server and the location of its DLL or
executable in a local registry.
COM's Service Control Manager (SCM) has the job of looking up the CLSID
in the registry and taking the appropriate action to activate the
server. Developers do not interact with the SCM directly; instead, the
COM library uses the SCM when asked to create an object or locate a
class factory.
How DCOM Extends COM
Distributed COM extends the programming model introduced by COM to work
across the network. These extensions include improved location and
packaging transparency, additional threading models, new security
options, and additional administration capabilities. In this section, we
briefly examine each of these extensions.
Location and Packaging Transparency
With COM, client applications are written independently of the packaging
of the server. COM objects may be loaded into the client process or
launched in a separate process on the same machine. DCOM extends this
transparency to include location transparency, allowing objects to exist
anywhere on the network.
DCOM "Object RPC" (ORPC) is based on DCE RPC. It extends RPC to include
an object reference datatype and adds a parameter to each call for the
target object. When a client requests a COM class factory for a remote
object, the local SCM contacts the SCM on the remote machine. The remote
SCM locates and launches the server and returns an RPC connection to the
requested class factory provided by the server. A class factory proxy is
created for the client application, and the object creation continues as
in the nondistributed case.
With appropriate administration settings, clients can access DCOM
objects on remote machines without specific coding for the network. An
administrator can experiment with various server packaging and location
options to optimize performance and scalability. Alternatively, clients
can specify the remote host that should be accessed when creating a new
DCOM object. This input could come from application settings controlled
by the end user.
Another packaging option introduced with DCOM is the ability to deploy a
DCOM server as an NT Service. This capability provides a consistent and
convenient mechanism for managing servers that need to be available
whenever a particular server machine is running.
Free-Threading Model
Several factors impact the scalability of distributed object systems. To
achieve the highest throughput on a single machine, developers typically
need to build multithreaded servers. This type of object concurrency
enables the server to leverage the power of a multiprocessor server
machine. DCOM extends COM's support for development of multithreaded
servers in any of the server packaging modes we described earlier in
this article.
Prior to the introduction of DCOM on Windows NT 4.0, multithreaded COM
servers were restricted to a form of threading called apartment model
threading. This model limits each COM object to be accessed by a single
thread: the one that created the object. Windows NT 4.0 introduces a
concurrency model called free threading.
With free threading, each incoming object invocation may be handled by a
separate thread, and multiple incoming calls can be dispatched on a
single object at the same time in different threads. Dispatching is
managed by the COM library in conjunction with the RPC runtime library.
The burden is on the developer to use concurrency primitives such as
mutexes to ensure that all of the objects are thread-safe; for
applications that need the highest performance, however, the added
complexity pays off.
Security
An important part of any distributed architecture is its support for
security. DCOM provides multiple levels of security that can be selected
as needed by the developer and administrator. The ability to configure
security of a component provides another level of transparency for
developers: The same binary component can be used in one environment
with no security requirements and in another environment that requires
very strict security.
DCOM achieves this transparency by supporting Access Control Lists
(ACLs) on COM components. If the requesting user is not allowed to
access or launch a component, DCOM will deny the request before the
component code is ever involved.
For high-level security, you can manage ACLs with a tool called
DCOMCNFG. Using this tool, an administrator can manage which users and
groups have access to specific object servers on a particular machine. A
machinewide default is available as well, which initially permits only
administrators to access DCOM objects remotely. One additional level of
security that DCOM offers is the ability to control which users and
groups are allowed to launch a server. By default, only administrators
are allowed to launch remote DCOM objects.
To achieve finer levels of security granularity, DCOM methods can
programmatically control authorization of individual method invocations.
Using a combination of registry keys and Windows NT APIs, a method can
implement custom security policies.
Reference Counting and Pinging
One of the issues faced by distributed application developers is writing
servers that can detect when their clients have died. This is
particularly important with DCOM, given the use of reference counting to
determine when an object should go away. The typical solution is to
perform periodic pings that indicate that a process is still alive. In
the world of distributed objects, this could result in a vast amount of
network traffic between clients and components simply to track the
status of the relevant processes. Fortunately, the DCOM architects
designed pinging support with high performance in mind.
To optimize pinging, DCOM uses keep-alive messages on a per-machine
basis. That is, independent of the number of client processes on a
machine and the number of component servers being accessed on a
particular remote machine, a single ping message is used between
machines. If a client process dies, DCOM detects the situation and
invokes the Release calls on the appropriate server interface pointers.
Additional optimizations available in DCOM include piggybacking ping
messages onto ordinary requests and tracking changes to the set of
remote references instead of always transmitting the entire set.
To accomplish this tracking, DCOM implements a component called the
Object Exporter, which tracks objects and object references that have
been exchanged with other machines. The Object Exporter is responsible
for tracking the liveness of client processes on a given machine.
Administration
Distributed object computing has matured significantly over the past
several years, yet management and configuration of large-scale
distributed object environments are still daunting tasks. The initial
DCOM environment is no exception. DCOM provides tools to make the job
easier, but it is certainly not trivial.
Each deployed component must be registered on individual client machines
as well as one or more server machines. In a small deployment,
installation and maintenance are not an issue. As the number of client
and server machines and components involved grows, network managers
should be concerned with balancing the load of client requests across
multiple server machines. DCOM does not have built-in support for load
balancing. If an application does not balance the load dynamically, the
network manager must statically configure the environment such that
certain client machines use a specific server. If a component must be
moved to a different server machine, every reference to the old machine
must be updated. A similar issue arises with respect to failover. With
DCOM, there is no straightforward way to indicate that a client should
look for a server on one of a list of machines instead of one specific
machine.
Today and Tomorrow
DCOM is part of Windows NT 4.0; at the time of this writing it had
entered what is likely to be the final beta test for Windows 95. You can
download the Developer Beta RC2 version from Microsoft's Web site and
try it out yourself. To satisfy the demands of customers with
heterogeneous environments, however, DCOM must go beyond its
Windows-centric roots. To accomplish this, Microsoft enlisted Software
AG and Digital Equipment Corp. as partners. A beta form of DCOM on
Solaris is currently available from Software AG and is expected to be
released during 1997 on a number of platforms, including IBM MVS,
OS/400, and AIX, HP-UX, Digital Unix and OpenVMS, Linux, and SCO
UnixWare.
Regarding improved scalability and robustness, DCOM is counting on a
pair of new Microsoft technologies. The first is the next-generation
Directory Services, scheduled to ship with Windows NT 5.0. These
services will provide a highly scalable store for object references and
security information for DCOM.
The second technology extending the reach of DCOM is the Microsoft
Transaction Server, which began shipping in early 1997. Transaction
Server is a transaction processing system that enables development,
deployment, and management of multitier applications composed of COM and
DCOM objects. DCOM is used for all object communication among machines.
Transaction Server transparently provides transaction support to
objects; it also manages threads, processes, database connections, and
shared properties so that developers can focus on providing business
objects. Transaction Server has a tight integration with SQL Server, but
it is architected to support a wide range of databases.
Another area in which COM and DCOM will be important is database access.
Microsoft's OLE DB specifies how databases should interoperate and how
applications will access databases. [For more information on OLE DB, see
Ken North's article in DBMS , November 1996[6] , page 87, or refer to
David Linthicum's column on OLE-enabled middleware in DBMS, January 1997[7]
, page 26.] OLE DB will provide a single set of component interfaces
that let any kind of data store expose data in a tabular form. As
Microsoft pushes to provide enterprise-level solutions, OLE DB will be
the means to access all corporate data, not just data in relational
databases. OLE DB is not intended to replace ODBC. Instead, it will
access relational databases through ODBC. Third parties will support
non-RDBMS access.
DCOM is poised to be a key player in the world of multitier distributed
object solutions. It provides all of the basic components necessary for
designing and deploying sophisticated systems, and it promises numerous
scalability and robustness improvements in the years to come.
-----------------------------------------------------------------------
Mark Roy is a principal consultant at Semaphore (North Andover,
Massachusetts) and has been designing and developing distributed object
systems since 1990. Prior to merging with Semaphore, Mark cofounded
NetLinks Technology, a leading provider of distributed object consulting
and training. You can email Mark at mroy@sema4usa.com.
Alan Ewald is a software architect at NobleNet Inc. (Southboro,
Massachusetts) and has been designing and developing distributed object
technology and applications since 1990. Prior to joining NobleNet, Alan
was a principal consultant with Semaphore and a cofounder of NetLinks
Technology. You can email Alan at aewald@noblenet.com.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
* Microsoft Corp., Redmond, WA; 800-426-9400, 206-882-8080, or fax
206-936-7329; www.microsoft.com[8] .
-----------------------------------------------------------------------
Figure 1.
[IMAGE][9]
--DCOM provides location and packaging transparency. An object can be
in-process, out-of-process on the local machine, or out-of-process on a
remote machine. In the case of out-of-process servers, DCOM uses
interface-specific proxy and stub code (typically generated from an IDL
file) and an RPC mechanism.
Figure 2.
[IMAGE][10]
--COM servers expose classes and class factories. When a client
application requests creation of a new object, COM locates and loads or
launches the server and asks the factory to create an object. COM
returns an interface pointer to the client, and subsequent calls are
invoked directly on the COM object.
Figure 3.
[IMAGE][11]
--A COM interface defines a related set of methods and is assigned a
unique interface identifier. A COM class implements one or more
interfaces and is assigned a unique class identifier. Each COM class has
an associated class factory responsible for creating COM objects.
-----------------------------------------------------------------------
[1] http://www.dbmsmag.com/9704d13.html
[2] 9703d13.html
[3] #figure1
[4] #figure2
[5] #figure3
[6] 9611d14.html
[7] 9701d06.html
[8] http://www.microsoft.com
[9] 9704d131.gif
[10] 9704d132.gif
[11] 9704d133.gif