Library

Volume 4, Number 2, July 2001

Use Of COM+ And .net For Building Distributed Systems

    Abstract

    This paper provides an overview of the COM+ distributed component-based middleware that was introduced with the launch of Windows 2000. It is important to understand the capabilities of this technology since it will be present in the Australian Defence Force (ADF) Common Operating Environment (COE) and so will be available in many ADF systems. If this technology were taken advantage of, it would support the development of component-based systems for the ADF without requiring large expenditures for new IT infrastructure. Looking further out the recently announced .NET platform will be a standard part of future Windows releases and so is likely to find its way into the COE as well. The .NET platform builds on COM+ services and concepts to provide a platform for building loosely coupled Internet-based applications.

    Introduction

    The computing industry has witnessed the migration from centralised mainframe systems to the use of distributed collections of computers. This has increased the requirement for software to support the construction of distributed applications. Another trend in application development is the use of object-oriented and component-based technologies. These two trends have led to the requirement for operating systems to provide support for component-based distributed systems development.

    Distributed systems are important in Command and Control (C2) systems for a number of reasons. Military operations are typically distributed in nature so one would expect the system to reflect this rather than constraining the manner in which the organisation operates. Having a distributed system allows data to be economically stored near the source while still providing access to distributed users throughout the system. A well-designed distributed system does not have a single point of failure so can provide resilience and graceful degradation in the face of equipment failures. Finally a distributed system can exploit load balancing to adapt to rapid changes in system load and to enable a cost effective means by which to upgrade the system. Component-based technologies are also important to C2 systems as they provide a mechanism to manage complexity in a way that still provides a flexible system that can evolve and change to match new requirements.

    While these technologies are currently layered on top of the operating system (OS) and run in user mode, services to support component-based distributed applications provide a number of useful abstractions for application developers and so the technologies can be regarded as extensions to the operating system. In fact the history of OS development shows that over time new abstractions have been introduced to provide new operating systems capabilities. Support for components and distribution are increasingly desired with major industry players offering competing ‘standard’ solutions. Many of the competing systems are based on similar principles and only time will tell which will prevail and which abstractions become a common part of standard operating systems.

    Two well-known alternative distributed object infrastructures are CORBA and Enterprise Java Beans (EJB). The Object Management Group (OMG) industry consortium developed the CORBA standard. CORBA provides a cross language and multiple hardware middleware platform for developing distributed systems. The CORBA standard uses an interface definition language (IDL) to define the interfaces to CORBA services. A binary wire protocol is defined in the standard to allow distributed operation. The OMG also define standards for basic middleware services required to build distributed systems. These include event, naming, life cycle, notification, security, time, trading, and transaction services. The EJB standard was developed by SUN Microsystems and is based on the JAVA platform from the same company. The EJB standard defines a container in which EJB components execute. By executing within the container the container is able to provide many of the required infrastructure services such as security, life cycle management, and data access.

    Microsoft has recently introduced the Windows 2000 OS for workstations and servers. While Microsoft has supported distributed component-based development with DCOM for some years, this has mainly been used on the desktop. Windows 2000 represents a committed move by Microsoft to position their operating system as a serious platform for enterprise level distributed component-based development. As such this represents a useful time to revisit the capabilities of the Windows platform for distributed component-based development.

    The Windows 2000 platform contains a number of technologies of interest to distributed application development including Active Directory, the Distributed File System, Microsoft Message Queue, and the Component Object Model (COM+). This paper examines the Component Object Model (COM+) introduced in Windows 2000 and the associated component services that support the development of distributed systems.

    The use of Microsoft technologies is increasing in the Australian Defence Force (ADF) via their inclusion in several C2 projects and via the Common Operating Environment (COE). It is not clear at present whether the fully distributed and component-based capabilities of the Microsoft environment are being leveraged. As with any environment it is possible to continue to build stove-piped systems on top of a component-based infrastructure such as Windows 2000 COM+. Given the imminent inclusion of Windows 2000 server in the ADF COE it is important that an understanding of its ability to support distributed component-based development is understood and leveraged.

    The recently announced .NET platform will continue the trend of providing further services and infrastructure for building loosely coupled distributed systems. A full description of .NET is beyond the scope of this paper, however a brief description of its history and architecture shows some of the limitations of the COM+ platform. This helps show the direction the Microsoft platform will take in the future. As such systems are likely to be increasingly used within the ADF it is important to understand the direction such technologies are taking.

    Components, Middleware, and Distributed Systems

    This section describes some of the basic concepts needed to understand COM+ and distributed systems. Some of the advantages of distributed systems are also outlined. In Figure 1 an illustrative framework is provided to help show how these concepts fit together. Components are typically brought together to build client applications or some application service accessible via some programmatic interface. In this paper the COM+ technology is described in the following section and .NET introduced latter. Middleware is used to tie components together and abstract away the communications details to simplify the construction of distributed systems. In this case COM describes how components communicate and the DCOM specification introduced a wire protocol for distributed communications. Component and Middleware platforms are expected to provide basic services to assist in building distributed component based systems such as event, and transaction services. For the case of COM+ some of the services provided are described in a later section.

    Components, Middleware and Distributed Systems.
    Figure 1. Components, Middleware and Distributed Systems.

    Components

    Despite the promise of Object Oriented Technology to deliver increased code reuse, reuse has not occurred in a large-scale commercial way. One of the reasons for this is that it has often been necessary to supply source code to use object libraries effectively.

    The idea of a component is to have an independently deployable piece of software, with an agreed interface and known requirements. A component must be usable by a third party without the requirement to understand its internal structure. The interface to the component is like a contract between the component supplier and component user. Components can be developed using object-oriented or non-object oriented languages. Current examples of component technologies include COM+, CORBA, Java Beans (client components), and Enterprise Java Beans (server components). The development of add-ons for Visual Basic was an early example of component reuse in practice and spawned a whole industry in the supply of reusable components on the Windows platform [6].

    Middleware

    The term middleware is used in many contexts in the information technology area. In fact a search on www.google.com for ‘middleware’ provides around 44,000 hits on a range of products, organizations, and research areas. Most generically, middleware refers to software technology used to connect one layer of software to another via some abstraction such as remote procedure calls, object invocations, or messaging.

    In the context of this paper middleware refers to technology to provide the abstraction of distributed components on top of a collection of distributed networked computers. This allows the application programmer to develop distributed components that can locate and communicate with each other. The middleware hides the details of transferring information between components on the network and locating components in a distributed environment. Examples of such middleware include COM+, CORBA, and Java RMI.

    Distributed Systems

    A distributed computing system consists of a number of separate computers each with their own CPU and memory resources connected together via some form of network. Several types of physical architectures are possible with the most popular being a networked collection of workstations and servers. In the context of this paper one would have a network of Windows 2000 workstations and servers connected by a number of possible networks with Ethernet being the most common connection technology.

    Distributed computing hardware and software are typically more complex to develop and maintain than centralized systems. Despite this, their use and popularity have been growing. This is due to the many advantages of distributed systems such as the following.

    • Many business applications are inherently distributed due to the increasing distributed nature of organisations. For example, some business processes may involve multiple locations.
    • Information is often distributed throughout organisations and distributed systems can support information sharing without requiring arbitrary centralisation of data.
    • Distributed systems facilitate sharing of resources in work groups such as disks (file servers), and printers (print servers).
    • The price-performance ratio of distributed systems is better than centralised systems. This is due to the decreasing cost of commodity workstation hardware and the ability of resource sharing to decrease total system costs.
    • By spreading applications across multiple computers the power of multiple CPUs can be leveraged for a single application. This has the potential to provide higher performance. Having a dedicated workstation for each user often provides shorter response times for common tasks.
    • Properly designed distributed systems can provide a higher degree of reliability than centralised systems. Even if part of a distributed system is destroyed the other parts can continue to function with some capability.
    • Distributed systems can be extended in small increments at linear cost increments. The price of centralised systems increases at a greater rate, as more performance is sought.

    The operating system for a single computer manages the resources of that computer and provides useful abstractions for the users and programmers. Similarly the operating systems used in distributed systems must manage the resources across the whole distributed system and provide useful abstractions for using and programming a distributed system. Two broad classes of OS for distributed systems exist; network operating systems and distributed operating systems. In network operating systems each computer runs it own operating system and the network operating systems provides distributed services such as file sharing, printer sharing and component communication. The users view the system as a collection of independent computers with some common distributed services. Windows 2000 fits this kind of model where it provides both the operating system for the individual computer and the common distributed services. COM+ provides a component framework for both the individual computers and the distributed collection. Distributed operating systems provide a single system image to users and programmers. In this case, a single operating system runs over the whole distributed computing system with each machine running a part of the distributed OS. While distributed operating systems have several advantages over network operating system models and several research level distributed operating systems exist, they are not in wide commercial use at present. Some of the possible future developments of COM+ and Windows 2000 may make the system much more like a distributed operating system.

    The Evolution of COM+

    The evolution of COM+ can be traced back to Microsoft’s early Windows technologies. This evolutionary development has resulted in multiple API’s to maintain backward compatibility while moving forward. Soon after Microsoft Windows was developed it was recognized that it would be useful if applications could communicate data between each other, which led to the development of Dynamic Data Exchange (DDE), as part of Windows 2.1. Next, as part of the Microsoft Office development, the concept of treating applications as components that could be launched from each other to give a seamless appearance of a single larger application was developed. This led to the development of Object Linking and Embedding (OLE) technology that allowed a single document to contain sections from multiple applications. As part of the second-generation OLE effort Microsoft developed a generic component architecture on which to build OLE2. This component architecture was called the Component Object Model (COM). Since this was a generic component architecture it became the foundation for many Windows technologies in addition to OLE and migrated into a standard part of the Windows operating system.

    The Open Software Foundation developed the Distributed Computing Environment (DCE) to provide a standard platform on which to develop distributed applications. Part of this specification was the DCE remote procedure call (RPC) mechanism that provides a standard way for distributed computers to make a procedure call across the network. Since the calling process and the target procedure may use different languages, a common way to represent procedure calls is required. For this purpose the Interface Definition Language (IDL) was developed that describes procedure calls and data types in a language neutral way. An IDL compiler was then used to convert IDL to the language of choice. The DCE infrastructure handles the translation of data types between different machine architectures during the RPC. The client and server use stubs and skeleton code generated from the IDL to interface with the DCE infrastructure and with each other as shown in Figure 2.

    DCE IDL operation and RPC mechanism.
    Figure 2. DCE IDL operation and RPC mechanism.

    With the release of Window NT 4.0 Microsoft introduced Distributed COM (DCOM) that allowed COM components to communicate across machines in a distributed environment. The RPC mechanism was based on DCE RPC with extensions to support objects and components hence the term object RPC (ORPC) is sometimes used. Since COM also required a language neutral interface specification mechanism DCE IDL was extended to support component interfaces and is referred to as Microsoft IDL (MIDL).

    The final milestone on the road to COM+ was the introduction of the Microsoft Transaction Server (MTS) as part of the NT 4.0 option pack. The name of MTS is somewhat misleading since as well as providing transactional support for COM components it provides a container in which COM components can be managed in a more structured and scalable manner. MTS was developed due to the realisation that developing robust application servers was extremely difficult even with a distributed component infrastructure such as DCOM (or CORBA for that matter). With DCOM the application server developer had to handle such issues as threading to handle multiple connections, activation strategies, transactions and database connection pooling. MTS is designed to handle all these issues and allows the developer to focus on the business logic rather than scalability issues. Basically, MTS provides a server environment (the MTX.EXE executable) that can host DLL COM components. This container manages transactions for the components, provides just in time activation services, and creates pools of components to enhance scalability. The EJB standard adopted this model to support the development of server side JAVA components.

    COM, DCOM and COM+ technical overview

    COM is Microsoft’s implementation of a Component Standard to deliver a platform that supports component-based development. The COM specification [7] is a document that can be obtained from Microsoft that outlines the environment supplied by COM and how to develop components to take advantage of its infrastructure. The currently available COM specification is version 0.9 dated October 24 1995 and the DCOM specification is labelled v1.0 as submitted to the IETF in January 1998. COM+ was introduced with Windows 2000 in February 2000 and is documented in the Platform Software Developers Kit.

    The COM architecture is based on the use of well-defined interfaces, defined in the Microsoft Interface Definition Language (IDL) that is based on the DCE IDL. IDL provides a C-like syntax to describe the functions that are exposed by an interface in a language neutral way. No implementation details or constructs are provided in IDL, only a description of the interfaces function API’s. Many of the Microsoft languages automatically generate the required IDL so that Java and Visual Basic programmers do not have to write the IDL files. This interface definition is used throughout the Windows system to allow clients to connect to server components.

    To provide binary compatibility between COM components the COM specification provides a binary standard for component interfaces. COM uses a virtual function table (v-table) structure to define binary component interfaces as used in C++ virtual function tables. A virtual function table (v-table) is a C++ array of pointers to functions. As with the case in C++ the use of virtual function tables in COM efficiently supports dynamic binding from the interface to the implementation of that interface. Hence as shown in Figure 3 when a component is instantiated it will have a pointer to a pointer (called a handle) to a v-table plus its own private data. This allows multiple components to reuse function implementations and so reduce memory requirements.

    Handle to COM component and v-table operation.
    Figure 3. Handle to COM component and v-table operation.

    In the COM model a component can provide implementations of multiple interfaces so that a single object may provide multiple services or different versions of the same service. When a component is first accessed the IUnknown interface (described below) is returned to the calling program. The IUnknown Query Interface method is then used by the calling program to query for other interfaces the programmer wishes to use. This capability is used extensively within the Windows platform where certain classes of components are defined as those that implement certain interfaces. For example, an Active X control is simply a COM component that implements certain defined interfaces.

    The COM standard specifies that all components implement the IUnknown interface that consists of three methods, Query Interface, Add Ref, and Release. This interface defines the basic functionality required by all COM components. Query Interface allows a COM components client to dynamically determine what interfaces a component supports. The client passes a pointer to the interface type required to the Query Interface method and if the COM component supports this interface it will return a pointer to the components implementation of that interface (that is a pointer to a v-table). This allows a client to adapt to the capabilities of a particular COM component at run-time. In many higher-level languages such as Visual Basic and Visual Java the call to Query Interface is hidden, the programmer simply declares the object as one having the desired interface and the language libraries insert the required code. The Add Ref and Release methods provide a simple lifetime management for the component via reference counting. When a client uses a component interface it must call the Add Ref method on that component which increments its reference count. Then when the client no longer requires the component it calls Release so the component can decrement the reference count. While a component’s reference count is above zero it knows it is in use and so should remain active. When the count is decremented to zero it knows the last client has disconnected and so is free to release its resources and shut down if required. In many higher-level languages such as Visual Basic and Visual Java the calls to Add Ref and Release are generated automatically so the programmer does not have to deal with this complexity. A COM component developed in these languages will have these methods added automatically to so that the programmers do not have to concern themselves with this detail unless they want to over-ride the default behaviour with some special behaviour. A COM component then is a component with a number of interfaces including the IUnknown interface. A COM component is typically shown as a box with a jack for each interface as shown in Figure 4.

    COM object and interfaces.
    Figure 4. COM object and interfaces.

    To support identification of COM Interfaces and component classes in a distributed environment with potentially large numbers of systems and components, COM requires a Globally Unique Identification (GUID). Microsoft employed the universally unique identifiers (UUID) as defined by Open Software Foundation in DCE. This is a similar concept to the Interoperable Object Reference in CORBA.

    A GUID or UUID is 128 bit hexadecimal number which is generated by a system call or system utility. The algorithm to generate this number is in the DCE specification and is guaranteed to be unique. It is this number and not the text name that the system actually uses to identify interfaces so even if two programmes in different parts of the world generate interfaces with the same name they can be distinguished because they will have different GUID’s.

    To tie these concepts described together suppose one has an interface ICalc with two methods, Add and Sub. The IDL for this is given in Figure 5 where a generated GUID or UUID has been inserted.

    IDL for ICalc interface.
    Figure 5. IDL for ICalc interface.

    Note that the ICalc interface inherits from the IUnknown interface as all COM interfaces inherit from the IUnknown interface. The IUnknown interface has three methods Query Interface, Add Ref and Release so the v-table for ICalc will have 5 function pointers as shown in Figure 6.

    ICalc v-table.
    Figure 6. ICalc v-table.
    Table 1. ICalc v-table.
    Pointer to QueryInterface
    Pointer to AddRef
    Pointer to Release
    Pointer to Add
    Pointer to Sub

    Once we have components with defined interfaces and unique identities, we require an infrastructure to support instantiating components and making connections between components as well as other housekeeping tasks. This functionality is supported by a part of the operating system called the Component Object Library, located in the library OLE32.DLL. The Component Object Library delegates the process of locating and executing COM components to the Service Control Manager (SCM) implemented by the rpcss.exe process. The SCM accepts a unique identifier for a component then locates the associated server code by querying the system registry, and then uses this code to instantiate the COM server. In the case of DCOM, if the component is located on another machine (which would be indicated by the registry entry) the SCM will communicate with the SCM on the other machine to instantiate the remote component.

    With the double indirection model of using pointers to the vtable for component references, COM has the ability to support multiple ways of components communicating with each other. Firstly the component may run in the client’s process memory space by providing a direct pointer to the components vtable. In this case the component is referred to as an in-process server and is implemented as a dynamic linked library (DLL) that can be loaded into the process address space. The in-process server has the advantage of allowing components to be used without any extra calling overhead since a direct pointer to the vtable can be provided. A disadvantage to this approach is that if the server component causes a problem, say due to a bug, it can bring down the client as well since they are running in the one process. A second disadvantage is that the component is less easily shared among multiple clients. With in-process components the component will be running in the same security context as the client. Hence there is no protection against the client or server components interfering with each other. However this is no different than letting a single process have full access to its own process space. The second type of server component is one that runs in a separate process to the calling client. This is referred to as a Local Server and is implemented using an EXE executable program. In this case, rather than the client handle pointing directly to the server component, it connects to a local object stub in the client process that communicates via a lightweight remote procedure call to the server stub. The local server has the disadvantage of slower access times due to the use of a cross process lightweight remote procedure call but has the advantage that if the component server crashes due to a problem or bug the client can detect this and recover gracefully. Further if the server COM component is designed correctly it can be shared among multiple client processes. Finally DCOM introduced the Remote Server that executes on a separate machine to the client. The Remote Server can be implemented as DLL or EXE and again stubs and skeletons mediate the communication between the client and server. In this case the communication is over the network using the DCE based object RPC. The remote case has the disadvantage of even slower access times due to the network being traversed for each method call. However it has the advantages of the local server case plus it allows the flexibility of taking advantage of multiple machines in the overall system. In the local and remote server cases the client and server run in separate processes so access between each of them is controlled by standard Windows 2000 security. Access control lists for a component can control exactly who can execute operations on the component. These three cases are illustrated in Figures 7, 8 and 9.

    In-process COM.
    Figure 7. In-process COM.
    Local server COM.
    Figure 8. Local server COM.
    Remote process COM.
    Figure 9. Remote process COM.

    COM+ is the next version of COM that is being shipped in Windows 2000. In this version of COM the functionality of MTS has been embedded in the COM+ infrastructure. An advantage of this is that all COM components can be hosted in a managed environment and the developer does not have to maintain two sets of component types, namely COM and MTS components. To provide additional services over COM, COM+ uses additional levels of interception to insert policy objects that can perform required operations between the client stub and server skeleton and the RPC channel. This is illustrated in Figure 10.

    COM+ policy interceptors.
    Figure 10. COM+ policy interceptors.

    Currently only the operating system has access to inserting these policy interceptors but in the future this ability may be exposed to the application developer. As with the MTS, COM+ provides a server container in which to execute server side components. Because of this all COM+ components must be packaged as DLL’s and not EXE files since they will be executing within a server container or the clients own process. To manage COM+ components, an administrative tool is provided that allows components to be installed into the system and properties set on the component which control how it will operate.

    COM+ stores a much larger set of configuration information on components than was the case with standard COM. Instead of using the system registry to store this information COM+ uses a new system database called the COM+ catalogue. This catalogue can be manipulated via a component-based API or via the administrative tool described above. As with the use of the system registry, each machine has its own COM+ catalogue although one can access other machines catalogue via the management API and tool. The lack of a unified directory for components may be addressed in the future via the use of Active directory technology to provide a common directory service for components in a distributed system.

    Component Services

    Just as with other distributed object infrastructures such as CORBA and Enterprise Java Beans, COM+ includes a number of component services in addition to the basic distributed component infrastructures as supplied by DCOM. The services are designed to provide capabilities that are required in many distributed systems and would be difficult for the application developer to build. This section describes some of the key services that were introduced in COM+.

    Transactions

    Within a distributed system it will often be necessary to coordinate the operation of various components. For example, when moving items from one database to another it may be important that items are only removed from one database if they are added to another database. To enforce these types of properties the concept of a transaction is introduced. A transaction is a unit of work that a group of components participate in. The transaction complies with the ACID properties (that is, atomicity, consistency, isolation and durability). Atomicity means that all of the components participating in a transaction will either all succeed or will all fail and roll back to their pre transaction state. Consistency refers to the fact that all components and databases must be in a legal state both before and after the transaction where it commits or aborts. During a transaction, components external to the transaction must not see any inconsistent state due to the processing of the transaction. This is referred to as isolation and the use of database row locking is a common way to enforce this. Finally the results of a transaction must be durable in that they are recorded to permanent storage and survive system failure.

    It is extremely complex to develop a component from scratch that satisfies the ACID properties despite the failures that can occur within a distributed environment. As a result many vendors are building infrastructure to support building transaction aware components such as the SUN Enterprise Java Bean (EJB) standard, the CORBA Transaction Service and Microsoft’s Transaction Service (MTS) that is now one of the services supplied by COM+. With COM+ rather than each component having to deal with the complexities of transaction management, this is managed by the COM+ infrastructure. The Distributed Transaction Coordinator (DTC) is part of COM+ that manages the creation, committing and aborting of transactions. An individual component is only required to vote on whether it wishes a transaction to commit or abort. This is done through the IObjectContext Set Complete and Set Abort method calls. The component does not have to manage starting or ending a transaction or have to be aware that it is even in a transaction. A component’s requirements for transactions are set administratively rather than programmatically. This can be achieved by setting a property in a programming environment or by using the COM explorer administration program. A component can have one of the following five transaction modes.

    Does not support Transactions: The component will not participate in a transaction or allow a transaction to continue in a processing stream involving this object.

    Supports Transactions: The component does not require a transaction but will correctly allow a transaction to proceed.

    Requires Transaction: This component must be in a transaction to operate. If it is already in a transactional context when called it will simply proceed. If a transaction has not been created when it is called, the DTC will create a new transactional context before calling the method.

    Requires New Transaction: In this case the component always requires a new transaction so the DTC will always be called to create a new transactional context when the components method is called.

    Disabled: This indicates that the component wishes to do its own transaction management and will communicate with the DTC directly.

    Queued Components

    Up to now it has been assumed that the client and server are both running and connected when making a distributed remote procedure call. As the number of machines and components increases, this assumption becomes increasingly unlikely and will limit the scalability of a distributed system. A more scalable approach is to remove the required connection between the client and server process lifetime. Just as with email, where one does not require the sender and receiver to be on line for a message to be transmitted in asynchronous communication, the client and servers lifetimes are independent. Several vendors such as IBM’s MQ Series and Microsoft’s MSMQ have developed asynchronous messaging infrastructures. These infrastructures provide a message-based communication path between components and must be used through their own unique API.

    With COM+ Queued Components a recorder stub and a player skeleton replace the COM+ stubs and skeletons. The recorder stub accepts all the COM calls made by a client until it is deactivated. The player skeleton retrieves the packaged calls from a queue and replays them to the COM+ server as COM+ calls. The recorder and player use the MSMQ infrastructure included in Windows 2000 to provide an asynchronous communications channel. Since the MSMQ infrastructure supplies queues to place the recorded calls on it is not necessary for the server to even be running when the client executes.

    To develop a queued component in COM+ one builds a standard COM+ component with the restriction being that all methods on the component can only have IN parameters since the communication path provided by the message queue is one way. When the component is deployed its interfaces are marked as queued which results in the queuing stubs, skeletons, and MSMQ communication infrastructures being employed rather than the standard COM+ synchronous stubs and skeletons. The parameters in a component must be passed by value and not by reference since all the required parameters must be sent to the server asynchronously. A COM object that supports the IPersistStream interface can also be passed as a parameter.

    The return code on a queued component cannot contain any application-specific information since the return code only indicates whether the call has been recorded by the messaging infrastructure not that the server has actually executed (or even received) the method call. To provide feedback when needed a call to a queued component may contain a string or object reference for a COM+ queued component on the client machine that can have a method invoked on it by the server when it wishes to provide feedback.

    The underlying MSMQ infrastructure of queued components supports the use of transactions. MSMQ is a resource manager so that it can participate in a transaction just as a database can. So if a queued call is part of a transaction that aborts then the message will be discarded rather than sent. Only when the transaction commits will the queued method call be placed on the queue and sent. On the server side transactions can be used to ensure a message is actually processed and results committed before the message is dequeued. This way if a problem occurs and the operation aborts or machine goes down the message will remain on the queue so that it can be retried at a later stage. Note the transactions on the client and server side will be different transaction contexts. So some logic will have to be developed to handle the ultimate failure of a server side transaction. If a server-side message causes repeated failures it is eventually placed on the dead queue. It is then up to the administrative or business logic code to handle this failure situation. In some situations it may require callbacks to the client side to execute compensating transactions.

    Events

    In any distributed system with multiple components it is common for components to wish to be notified of the occurrence of various events within the system. Typically one will have various Publisher components that provide notification of events and Subscriber components that wish to be notified of events occurring.

    One of the simplest ways for the subscriber to detect events is for it to periodically poll the publisher to see if an event has occurred. This is a simple architecture to code but is inefficient as it requires the subscriber to continually poll the publisher plus the subscriber will only obtain notifications when it polls and not when the event actually occurs. The next way to develop an event infrastructure is through the use of callbacks. In this case the subscriber passes a reference to a callback interface to the publisher. Then, when an event occurs, the publisher invokes a method on the subscribers’ callback interface that notifies it that an event has occurred. This is the way that the Active X event notification works. While this is more efficient than polling it still has some disadvantages for building distributed systems. Firstly both the client and the server must both be running at all times. This is not a problem on a single machine but may be a problem in a distributed system. Secondly the publisher and subscriber must have an understanding of the callback interface used, which could be different for each publisher and subscriber. It would be better if there were some standard mechanism for making event connections. Finally the publisher has to maintain the list of subscribers itself that adds complexity to the publisher component.

    The COM+ event service is an operating system service that allows the event publishers and subscribers to be more loosely coupled and provides a standard mechanism for publishing and subscribing to events. This is achieved by the use of an object between the publisher and the subscriber and by storing the subscriptions in the COM+ catalogue rather than requiring each publisher to maintain that information. To use the COM+ event service the first step is to provide an interface definition (IDL) for the event object. This will define the method that the publisher must call to fire an event and the interface the subscribers must implement if they wish to receive these particular events.

    Once this interface is defined it is registered in the Component services administration tool. When this is done the COM+ Event Service synthesises an event object that implements the supplied interface. A publisher can then fire this event type by creating an event object of this class and then calling the event method supplied in the interface. The publisher does not have any knowledge of what components (if any) have subscribed to this event. To subscribe to an event a component must implement the event class interface so that the COM+ Event service can call the method on the subscribing component. The component implementing the required interface can then subscribe to the event by registering with the Event service via the component services tool. When this is done the COM+ Event service adds the component to the list of subscribers to be notified of the event. Then when a publisher fires an event of this type the COM+ Event service goes through the list of subscribers and fires the event method on each of the subscriber components which notifies them of the event. The subscriptions can be transient, which means they will not last beyond a machine reboot, or permanent so that they do.

    Currently the event service itself is not distributed in the sense that the COM+ Event services running on separate machines are not connected, and there is no sense of an enterprise wide distributed event service. So to use the event service among a collection of machines, one must designate a single machine as the one with all event registrations. A further limitation with the current event service is that it doesn’t make use of multicast mechanisms for event notifications. While these are possible areas of improvement for the event service Microsoft has made no announcements on whether these issues will be addressed.

    Past futures and the .NET Framework

    To help understand some of the limitations of COM+ and where Microsoft are moving their middleware platform to it is informative to examine some of the historical documents describing future versions on COM+ and the recent emergence of the .NET platform. In some of the original articles [4,5] describing COM+ v1.0 in Windows 2000 much more functionality was described than was finally delivered in COM+ 1.0. Much of the advanced capability described is now delivered via the .NET framework rather than via upgrading COM+. The .NET Framework is briefly described here after some of the issues with COM+ that were addressed are outlined.

    Currently when building COM components the programmer is required to implement the IUnknown functionality that is not related to the business problem at hand. As mentioned earlier, many high-level languages such as Visual Java and Basic have shielded the programmer from this by automatically generating the required functionality via runtimes supplied with these languages. However this results in the potential for different levels of support for specific COM features between different languages. In the vision for COM+ in the original articles it was planned to introduce the COM+ runtime. This system-supplied runtime would provide default implementations for the interfaces required by components such as the I Unknown methods. The complier vendors would then interface to the COM+ runtime to provide COM functionality in a consistent manner. Another goal of this development would be to make writing COM components more like writing standard object oriented code in the particular language. By the use of keywords in languages and compiler interfaces to the runtime, the metadata required by COM would be generated automatically from the programmer’s source code. Again some high-level languages such as Visual Basic already provide this capability but the COM+ runtime would have provided it consistently across all languages. Programmers will then define interfaces directly in their target language rather than having to generate IDL first. IDL could be generated if the developer required it. As time has shown, the COM runtime has not been introduced; instead a common language runtime is a key component of the .NET framework.

    The introduction of implementation inheritance was also planned. This would allow developers to provide a basic implementation of some component type, say an Active X control which could then be sub classed to develop more specific functionality. Taken as a whole, the capabilities of the planned COM+ runtime would provide a consistent environment and services that can be used from multiple languages. Some reviews described the COM+ runtime as a virtual machine like environment for COM objects. The system supplied runtime will be designed to allow developers to access COM functionality within their native language environment without extra external languages such as IDL. By supplying this runtime at the system level it can be used by multiple languages in an integrated manner so that the cross language capabilities of COM will still be supported. Again cross language inheritance has not been introduced with COM+ but rather as part of the new .NET architectural framework.

    The runtime was also to support garbage collection similar to the case in the Java Virtual Machine (JVM). This would handle reference counting transparently to the programmer so that when objects go out of scope they can be marked for garbage collection. Again languages such as Visual Basic provide this now but the runtime will provide this capability to all languages under COM+. Finally as mentioned in the COM+ section, the interception framework to support new services in COM+ v1.0 may be exposed to developers to allow third parties to provide new services to the COM+ infrastructure. Garbage collection has been introduced as part of the .NET framework rather than in COM+.

    COM+ was developed to allow components to interoperate via standard interfaces and a wire protocol. As such multi-language based components could interoperate with each other. With the .NET Framework [10], which has been recently announced by Microsoft, the concept of cross-language integration has been implemented. This will be the first widely available commercial system that will provide a common type system and object model across multiple languages. As a result the .NET system will support cross language inheritance so that developers will be able to directly inherit the functionality of other components without concern of the language used. So now as well as cross-language component interoperability one will have cross-language object integration.

    Another key concept in the .NET Framework is that of Web Services. With COM+, CORBA, or RMI a wire protocol and interface standard was defined to allow distributed components to interoperate. However all these systems made assumptions that certain infrastructure was installed at each node that implemented the required standards. As such it became difficult to deploy such systems across multiple organisations and the Internet. With the .NET framework the concept of Web Service is introduced. A Web service is a piece of functionality accessible via an API that uses the Simple Object Access Protocol (SOAP) XML standard to describe data across the API. SOAP messages can be transported by a variety of protocols such as IIOP, SMTP, or HTTP. Since it can be transported by HTTP the only common infrastructure assumption at the cooperating nodes is the support for the Internet protocol HTTP and the ability to parse XML streams. As such this provides an open way for multiple services built in multiple languages and middleware technologies to interoperate.

    The .NET Framework consists of a number of layers as illustrated in Figure 11. At the top level a large number of languages from Microsoft and third parties are supported. Each of these languages must support the common language specification that defines the common type system used across languages. Each language is compiled to an Intermediate language called Microsoft Intermediate Language (MSIL). As well as the compiler emitting code it generates metadata that is included with the MSIL assembly. Storing metadata with the component removes the need to store such data in the registry and in the future offers the hope to make installations and removal of software more robust. A number of layers of class libraries are then supplied which can be accessed from any supported language. The Windows Forms library provides classes to support the development of user interfaces for the Windows environment. The ASP.NET library provides libraries to support the development of Web based user interfaces and to support the development of Web Services. A uniform access to all data sources that uses XML as its native format is provided in the ADO.NET library. Access to core system functionality is provided by the Base Class Library.

    The Common Language Runtime provides the infrastructure on which to run .NET code. It is responsible for loading code, compiling MSIL to native code when required, and providing a common security service across all languages. The runtime also provides garbage collection and manages code according to metadata stored in each component. The runtime will support the dynamic loading of components from a URL location description that will support the development of highly dynamic systems. The use of the Common Language Runtime plus the Common Language Specification enables cross language inheritance to be implemented.

    In the first release of the .NET implementation several of the libraries and provision of component services will be via the underlying platform. For example the Win Forms library provides a .NET wrapper of the Win32 GDI+ API, and the .NET transactions services will be implemented using COM+ transactions.

    Conclusions

    COM+ has evolved over a long period from Microsoft’s requirement to develop an infrastructure to support component-based development on Windows desktop workstations.

    The COM infrastructure has been highly successful on the desktop and supports a large third party industry which develops COM based components and applications for the Windows platform. With the introduction of Windows NT 4.0, Microsoft extended COM to the distributed environment via the use of a remote procedure call (RPC) mechanism based on OSF DCE protocols. This provided the foundational middleware required for building distributed systems.

    The use of IDL, stubs and skeletons provides a similar architecture to other middleware technologies such as CORBA, DCE and RMI. However, the original version of DCOM included only a limited set of services to support the development of scalable and reliable distributed system. By contrast, the OMG had defined a standard for a large number of services for use in conjunction with the basic CORBA ORB to develop distributed systems.

    With the release of Windows 2000, COM+ has been introduced. It has been designed to support distributed systems development and includes a series of services to support the development of scalable and reliable distributed systems. This represents a concerted effort to position Windows 2000 as a platform for enterprise system development and not just a desktop platform. With the combination of distributed component-based middleware and now a collection of services targeted at distributed application development, COM+ and Windows 2000 represent a serious potential platform for enterprise system development. Only by testing this technology in domains of interest will it be discovered if it is suitable for specific application areas and its advantages and disadvantages discovered. Given that this infrastructure will be present in the ADF COE in the near future it will provide a cost effective base on which to build C4ISR component-based applications. Hence the suitability of this infrastructure to support component-based C4ISR developments must be assessed.

    The COM+ framework will be enhanced with the release of COM+ 1.1 in Windows XP. However many of the original advanced capabilities envisioned for COM+ are now to instead appear in the new .NET framework. The .NET Framework will be aimed at making distributed component-based development even simpler for the application developer. By using Internet based protocols and standards the .NET framework will be more open to connecting to multiple technology platforms. In the first release of .NET many of the underlying component services such as transactions will be supplied by the underlying COM+ infrastructure.

    References

    [1] W. Bolosky, R. Draves, R. Fitzgerald, C. Fraser, M. Jones, T. Knoblock and R. Rashid, Operating System Directions for the Next Millennium, http://research.microsoft.com/os/ millennium/mgoals.html.

    [2] G. Eddon and H. Eddon, Inside Distributed COM, Microsoft Press, 1998.

    [3] P. Greenfield, “Microsoft Distributed Object Technology”, Cutter Executive Report, Vol. 2, No. 9, Cutter Consortium, 1999.

    [4] M. Kirtland “Object-Oriented Software Development Made Simple with COM+ Runtime Services”, Microsoft Systems Journal, November 1997.

    [5] M. Kirtland, “The COM+ Programming Model Makes it Easy to Write Components in Any Language”, Microsoft Systems Journal, December 1997.

    [6] P. Maurer, “Components: What If They Gave a Revolution and Nobody Came?”, IEEE Computer, pp. 28-34, June 2000.

    [7] Microsoft Corporation, The Component Object Model Specification, V. 0.9, 24 October 1995, http://www.microsoft. com/com.

    [8] D. Platt, Understanding COM+, Microsoft Press, 1999.

    [9] S. Pradeep, Dsitributed Operating Systems: Concepts and Design, IEEE Press 1997.

    [10] J. Richter, “Microsoft.NET Framework Delivers the Platform for an Integrated, Service Oriented Web”, MSDN Magazine, September 2000.

    [11] C. Szyperski, Component Software: Beyond Object-Oriented Programming, Addison Wesley, 1998.

    Author

    John Hildebrandt is a Senior Research Scientist in the Information Technology Division of the Australian Defence Force's Defence Science and Technology Organisation (DSTO). He has a PhD in image restoration and has worked in the area of image management and dissemination systems. He has held posting in the Australian Defence Intelligence Organisation's Image Exploitation Centre and to a US imagery organisation (NIMA). Most recently he has been involved in developing distributed component-based C4ISR systems concepts. His interest include imagery systems, technologies to develop distributed component-based systems, and collaborative environments.