SOM & DSOM - An Introduction

By Nicholas McGuigan

''The System Object Model (SOM) is one of the foundations of IBM's comprehensive, multi-platform, distributed object environment. This is being delivered as you read this and will continue to rollout over the next few years.''

Components of the environment include SOM with its component frameworks of DSOM, PSOM, RSOM and so on, OpenDoc from the Component Integration Laboratories (CIL) and Frameworks and an Object Oriented environment from Taligent. IBM is a member of both the CIL and Taligent consortiums. And it all started here with OS/2 Version 2.0 and the first appearance of SOM Version 1.0.

OS/2 had been improving incrementally ever since its first release as OS/2 Version 1.0. However, it was basically a 16 bit protected mode environment with very limited DOS support. It appealed to corporations writing their own client server applications but to few others.

OS/2 Version 2.0 was a radical find. It featured a switch to 32 bit code, not fully complete but on the way, support for Windows and DOS applications and a new user interface, the Workplace Shell. The Workplace Shell is an Object Oriented User Interface (OOUI) which placed the user's data at the centre of things rather than the traditional Graphical User Interfaces provided by Presentation Manager 1.x and Windows which placed the program there. Underneath this interface was a new engine, the System Object Model, making it all happen.

Since that time, OS/2 Version 2.0 has evolved into OS/2 Warp Version 3.0 and SOM has independently developed into SOM Version 2.1. I say independently because SOM can be purchased separately for Warp and a whole list of other environments including:
 * AIX (IBM's Unix)
 * AS/400 (a mid range application system)
 * MVS (IBM's big host OS)
 * Microsoft Windows
 * Apple

It also forms one of the pieces of the OpenDoc composite document architecture and will eventually be found on all platforms implementing OpenDoc. SOM Version 2.1 is a part of Warp although, to get the full range of SOM services, additional enablers are required. More about this later.

What is SOM ?
SOM is a language neutral object oriented environment for defining, operating and packaging libraries of classes (see the sidebar "A Quick and Hopelessly Inadequate Introduction to Object Orientation" for a brief summary of objects and classes). In essence, SOM provides an environment that enables programmers to define a class's external interface and to create the methods associated with that class. These classes are packaged, usually in a DLL but sometimes in an EXE, from where they may be used to instantiate objects at execute time.

SOM provides a number of language bindings to enable the programmer to create the class methods. Currently, bindings for C and C++ are provided but more will follow in the future. Class bindings are also provided to enable client programs to instantiate and use the SOM objects. SOM is called language neutral because the using (client) language need not be the same as that used to create the class in the first place.

The SOM kitbag provides the following pieces:
 * IDL Compiler:The interfaces to classes are specified using the Object Management Group's (OMG) Interface Definition Language (IDL) (see the sidebar "Object Management Group" for more information). These are then "compiled" by the supplied IDL compiler to create the appropriate language bindings for the class.
 * Distributed SOM (DSOM) ORB:A CORBA compliant Object Request Broker that enables objects to communicate across processes within a single workstation or across the network to other workstations.
 * Replication SOM (RSOM):A replication framework that enables you to create copies of objects and have updates automatically copied to all the copies.
 * Persistence SOM (PSOM):A persistence framework that enables the lifetime of objects to persist beyond the operating environment or program that created them. This may be achieved by storing the objects to files, databases and the like.
 * Collection Classes:A framework of collection classes implementing various object containers such as bags, lists, sets, queues and so on.
 * Event Management:An event management framework that enables the sending and receiving of asynchronous events to be handled.
 * Emitter Framework:A framework designed to assist programmers implementing their own SOM language bindings. The framework produces an output file representing the class bindings in a particular language as set up by the programmer.
 * Interface Repository:The interface repository is a database for storing all the information known about a class from its interface. The structure and content are defined by the OMG CORBA architecture. In addition, SOM provides a class framework to populate and access the repository.

This article will concentrate on SOM basics and DSOM.

Classes and MetaClasses
SOM implements three types of entity as follows:
 * Objects, which are instances of
 * Classes, which are also objects and instances of
 * Metaclasses

Classes provide the behaviour (methods) and structure information (attributes) for the objects instantiated from them.

For example, we might define a class called Window with attributes such as xPosition, yPosition, cxWidth, cyHeight and methods such as makeVisible, setMinimised and so on. A SOM object instantiated from this class might be called myWindow and have an xPosition of 30, yPosition of 50, cxWidth of 200 and a cyHeight of 150. Invoking the makeVisible method on the myWindow object would (hopefully) make the window visible.

In SOM, the classes themselves are objects and are thus instances of a class. These classes of classes are called metaclasses. They provide methods for use with the class objects. More on this later.

SOM implements a kernel of classes from which all other classes and metaclasses are derived using inheritance. Figure 1, "SOM Kernel and Classes", shows this kernel which is delivered in SOM.DLL. In Warp systems, SOM.DLL may be found in the \OS2\DLL directory on the boot drive.

The SOMObject class is the ancestor of all SOM classes. It provides methods that define the basic behaviour inherited by all SOM classes including lifecycle behaviour, dynamic method dispatching, query of relationships and debug support.

The SOMClass class is the ancestor of all SOM metaclasses. It provides the methods for manufacturing object instances, finding methods and getting information about classes. All SOM classes are instances of SOMClass. As SOMObject is a class, it is an instance of SOMClass. This relationship is shown in Figure 1 by the dashed arrow between them. In addition, SOMClass, being a class itself, is an instance of itself. This relationship is shown by the dotted line pointing to itself. Finally, as a SOM object, SOMClass is a subclass of SOMObject just like any other SOM object. This is shown by the solid arrow between the two in Figure 1.



Figure 1: SOM Kernal Classes and Objects.

The other class in the SOM kernel is SOMClassMgr. A single instance of SOMClassMgr, SOMClassMgrObject, is created when SOM is initialised to maintain a registry of all SOM classes that exist within the process. SOM is initialised for each process (say program) using its services. SOM interprocess communication is handled by DSOM. As SOMClassMgr is a class, it is an instance of SOMClass and a subclass of SOMObject. SOMClassMgrObject is an object and an instance of SOMClassMgr.

To this basic structure, programmers (such as yourself, gentle reader?) can add their own classes and metaclasses. Classes can be added directly as subclasses of SOMObject or as subclasses of intermediate classes such as those of Workplace Shell for example. The latter could be done to add function to or refine the existing behaviour of Workplace Shell objects.

An example of this can be found in the Multimedia Viewer, delivered as a part of the OS/2 Warp BonusPak. Here, the standard Workplace Shell folder behaviour has been enhanced to provide a "light table" for multimedia objects. This is not done by copying the original folder code and giving it a hack. In all probability, the Multimedia Viewer developers have never seen that code. Instead, they have subclassed the actual folder code using SOM to create a new class and have added the additional behaviour in that derived class. The new behaviour is added by adding new methods and attributes and by overriding and augmenting existing methods. There are three advantages to doing things this way:
 * 1) The developer doesn't have to reinvent the parent object's code. He or she is able to use as much of the parent class as fits his or her requirements leaving just the incremental code required to implement the light table function to be written.
 * 2) The user benefits because the behaviour of the derived folder, the "light table", is inherited from the standard folder which is familiar to him or her from normal OS/2 usage. Try playing with the light table folder and see if this is true.
 * 3) Finally, as the classes are compatible at the binary level, the parent class, the standard folder, can be updated without the need to recompile or otherwise dicker with the derived class, the light table. This situation can arise when, for example, OS/2 Warp Version 3.0 is replaced by OS/2 Warp Version the next one. Any new features and functions introduced by an updated folder class will be automatically inherited by the derived light table class.

Metaclasses are created to add new or override existing class methods for new classes. These class methods are typically factory methods or, in C++ parlance, constructors which are used to customise the initialisation of new objects when they are created. Just as classes form an inheritance hierarchy based on SOMObject, so metaclasses form an inheritance hierarchy based on SOMClass. However, the two hierarchies are independent of each other and should not be confused.

In summary, the things to remember from this section are:
 * 1) An object is an instance of a class.
 * 2) A class is an instance of a metaclass.
 * 3) All classes are derived from SOMObject, the ancestor class of all SOM classes, either directly or through an intermediate inheritance chain.
 * 4) All metaclasses are derived from SOMClass, the ancestor metaclass to all SOM metaclasses, either directly or through an intermediate inheritance chain.
 * 5) All classes are instances of a metaclass that provides factory or constructor class methods for use in creating new objects.
 * 6) The SOM kernel, SOMObject, SOMClass and SOMClassMgr, is contained in SOM.DLL.

Creating Classes
The SOM development toolkit provides all the tools necessary to develop, test and package SOM classes. Of course, you need to add the C or C++ compiler. I recommend the use of C++ rather than C as the object oriented features of C++ nicely wrap the SOM objects. On the whole, they are a more natural fit. In addition, a new technology called Direct to SOM (DTS) will enable SOM classes to be generated directly from C++ classes. DTS is shipping today with the MetaWare C++ compiler and will ship with IBM C Set++ Version 3.0 or VisualAge C++ as it has now been renamed.

The key SOM link in the development chain is the SOM compiler, SC.EXE. Classes are defined in a text file using the Interface Definition Language (IDL) defined by the OMG CORBA standard. The details of this language are beyond the scope of the article (perhaps in the future) but here is a simple example: This defines a new class, or in IDL parlance an interface, called HelloWorld derived directly from SOMObject. It has one attribute, a string called Message, and one method, printMessage. Behind the scenes, two additional methods, _get_Message and _set_Message, are defined to get and set the contents of the attribute Message. These are automagically defined by defining Message as an "attribute".

The syntax allows for non-CORBA extensions to be placed into an implementation section. The releaseorder keyword is one of the mechanisms used to preserve binary compatibility through the inheritance chain. Through binary compatibility, a parent class can be replaced without any need to recompile or link the derived classes. That is something you can't do with C++!



Figure 2: SOM Class Development.

To create the HelloWorld class, the IDL source above is placed into a text file, for example HelloWorld.IDL. You are using HPFS, aren't you? Then the various files needed are created and processed as shown in Figure 2, "SOM Class Development":

1. Compile the IDL file. This produces various pieces of output:


 * Interface Repository:The SOM compiler can optionally update the Interface Repository. This is a repository of class information that contains the equivalent of the information in the IDL file for each class registered with it. In other words, it is a registry of interfaces. As we will see below, DSOM requires that each class that will be accessed from another process has its interface registered. The repository is defined as part of the CORBA standard and the SOM Interface Repository conforms to that standard.
 * Client Bindings (HelloWorld.xh):This is the header file, h for C and xh for C++, that must be included in each client source file that requires access to the class.
 * Implementation Skeleton (HelloWorld.cpp):A skeleton source file, c for C and cpp for C++, containing a code template for each method defined in the IDL file or generated for attributes (_get_*, _set_*). These must be completed by adding user code. If subsequently the IDL file is findd and the SOM compiler is rerun, the inserted user code is preserved.
 * Implementation Bindings (HelloWorld.xih):This is the header file, ih for C and xih for C++, that is included in the implementation skeleton.

The SOM compiler can do a variety of other tasks for the developer but a detailed review of these is beyond the scope of this description.

2. Add the method code to the implementation skeleton. As described above, each method is represented by a function definition in the file. The code that implements the actual method behaviour is added into this. When complete, the resulting source file, which (#)includes the implementation binding file (ih or xih), is compiled and linked alone to form a DLL or together with the client program code to form an executable program (EXE).

3. The client program code is compiled and linked to form an executable (EXE). The link may directly link the SOM class into the executable. Alternatively, the program may be linked with DLL import libraries created when the SOM class DLLs are created.

4. Finally, the client program may be executed to use the SOM objects created in steps 1 and 2.

A lot of the files produced in this process are internal to the development process. However, the following files are required to be made public in order to make the SOM class useable by all and sundry:
 * 1) To use the created objects in a program, the client binding file (h or xh) must be available at compile time, the import library at link time and the DLL at runtime. SOM classes linked into EXE files are considered private and are not useable by other programs.
 * 2) To derive new classes from a class by subclassing, the IDL file must be available when the SOM compiler is run against the new class IDL. The new class IDL file (#)includes the parent class IDL file. The import library must be available at link time and the DLL at runtime as before.

Distributed SOM
So far everything we have talked about happens within a single process, or program if you like. Life in a multitasking system like Warp is rarely like that. That is why, for normal procedural programming, Warp provides a variety of structures to help separate processes talk to each other. These include such things as queues, pipes, named pipes, semaphores and shared memory.

In a similar way, SOM objects may want to talk to SOM objects in a different process or even a different system altogether. It is entirely possible for them to use the available facilities listed above. However, the SOM kit provides an additional framework that enables SOM objects to talk across processes and across systems using the mechanism that comes naturally to objects, invoking each other's methods. That framework is the Distributed System Object Model or DSOM.

Before we talk about the mechanics of DSOM, I would like you to think a moment about the implications. Here is a mechanism that enables objects to transparently invoke each other's methods as if they were in the same program even if they are separated by a process boundary or worse a system boundary.

I have always said that hardware has a fundamental bug, it has boundaries. Up to now, software has faithfully replicated this bug to a greater (sockets!) or lesser (RPC) extent. In other words, most programs that operate in a multi-system environment have been aware of those boundaries and have had to jump them explicitly by calling a cab (use a comms link) to get across.

DSOM, on the other hand, offers software people a chance to forget all that nonsense and concentrate on the problem at hand. This will be of particular benefit in a client server environment where we may have to find our mind about where function (objects) actually lives. We may have to do this quickly in response to competitive pressures or to exploit opportunities. Failure to do so may result in loss of revenue or market share for your business. Ever tried reorganising a system with hardwired communications connections in a hurry? Not a pretty sight! Leave it to the infrastructure to handle and that means leave it to DSOM.

Distributed SOM is just that, Distributed SOM. Like SOM it uses all the SOM stock in trade like IDL to define the class interfaces, the SOM compiler to create the bindings and so on. To handle the distribution aspects, it implements an Object Request Broker (ORB). An ORB is the machinery that enables objects to transparently call the methods of other objects, be they local or remote. The calling object is never aware of the intermediate mechanisms used to accomplish this.

The DSOM ORB is a CORBA-compliant ORB. In fact it complies with CORBA Version 1.1. As mentioned above, CORBA is one of the standards defined by the Object Management Group (see sidebar). Unfortunately, CORBA Version 1.1 concentrated on the Object to ORB interface and largely ignored the ORB to ORB connections. This means ORBs from different vendors will be unlikely to work together unless the vendors get together and make it happen. However, recently announced is CORBA Version 2.0 which, amongst other things defines a mandatory TCP/IP-hosted protocol and a DCE-based protocol. To be CORBA compliant, you must have the TCP/IP support. DSOM is not yet CORBA Version 2.0 compliant, in fact nobody is yet, but this shouldn't be long in coming. IBM was one of the new standard's proposers. The ORB handles both Workstation and Workgroup connections as shown in figures 3 and 4. Two of the key pieces of the puzzle are the use of proxy objects to substitute locally for the remote objects and the DSOM daemon to create and destroy the remote server objects.



Figure 3: Work Station DSOM.



Figure 4: Work Group DSOM.

Proxy objects are created in the client process to represent the actual server objects the client wishes to call. To the client they look just like the real thing with all the same methods as the server object. The client can invoke those methods as if they were local. The proxy object handles passing the method call across to the server object to be executed. The client uses the services of a DSOM Object Manager to locate and gain access to server objects.

The DSOM Object Manager uses information stored in a set of files called the Implementation Repository to achieve this. The Implementation Repository is created when class information is registered in it using the supplied regimpl utility. This is required before they can be used in a DSOM environment. The Implementation Repository is not the same as the Interface Repository. This is built using the SOM compiler (optionally) and is used by the DSOM code that builds the proxy objects.

On workstations that host server objects, even in a workstation only situation, a program called the DSOM Daemon (somdd) must be running. This program creates new processes and loads objects to satisfy incoming client requests and keeps track of these server processes. It also uses the Implementation Repository to determine the DLL to be loaded to satisfy a request.

In the Workstation case, the communication is handled inboard using the standard OS/2 interprocess communications vehicles (queues, pipes etc.). In the Workgroup case, the communication is passed across a TCP/IP, NetBIOS or IPX network using the SOMSockets interface. Judging from the CORBA 2.0 announcement, a DCE version may be available soon and a proposed MQI (another topic) version has been foreshadowed by IBM.

Don't confuse SOMSockets with BSD Sockets used to program to TCP/IP. SOMSockets is implemented as a class. Programmers (brave ones) may subclass this to implement new protocol support besides those provided.

Products
For OS/2 Warp, Windows and AIX, IBM's UNIX implementation, SOM is delivered as three packages. You select the appropriate mix of packages to meet you particular needs. The packages are:

There is a product for each supported platform. The current product for OS/2 Warp is IBM SOMobjects Workstation Enabler Version 2.1 for OS/2.
 * IBM SOMobjects Workstation Enabler

The Workstation Enabler enables the execution of SOM-based applications including the use of DSOM within a single machine. This is the product you buy if you want to run SOM applications on a single workstation (see SOM and Warp below). The following are included:
 * Collection Class Enabler
 * DSOM (Single Machine) Enabler
 * Persistence Enabler
 * Replication (Single Machine) Enabler
 * SOM Kernel Enabler
 * Installation/Configuration Guide

There is a product for each supported platform. The current product for OS/2 Warp is IBM SOMobjects Workgroup Enabler Version 2.1 for OS/2.
 * IBM SOMobjects Workgroup Enabler

The Workgroup Enabler enables the execution of SOM-based applications including the use of DSOM across multiple systems. This is the product you buy if you want to run SOM applications across multiple workstations such as in a client server environment. The following are included:
 * Collection Class Enabler
 * DSOM (Multi-Node) Enabler
 * Persistence Enabler
 * Replication (Multi-Node) Enabler
 * SOM Kernel Enabler
 * Installation/Configuration Guide

There is a product for each supported platform. For example, the current product for OS/2 Warp is IBM SOMobjects Developer Toolkit Version 2.1 for OS/2.
 * IBM SOMobjects Developer Toolkit

The Developer Toolkit is used to develop SOM classes and client programs. If you plan to do any programming, this is the product for you. The following are included: As noted, SOM is or will be available for Apples, MVS and OS/400 amongst others. Of course, the packaging may be different on those platforms.
 * SOM IDL/OIDL Compiler
 * Language Bindings for C & C++
 * OIDL Migration Aid
 * Distributed SOM Application Programming Interface (API) - Collection Classes Framework
 * Persistence Framework API
 * Replication Framework API
 * Interface Repository
 * Emitter Framework
 * SOMobjects Workstation Enabler
 * COMM Emitter (Windows Only)
 * Publications

SOM and Warp
As mentioned elsewhere in this article, SOM is the underpinning of the Workplace Shell and thus it follows that SOM function is integrated into Warp. The question is, what is there and what isn't.

The supplied Warp SOM is at Version 2.1, which is the latest at the time of writing, and is a subset of the Workstation Enabler. The elements supplied are the SOM kernel and single workstation only DSOM. Omitted are the collection classes and the PSOM and RSOM enablers. If you need these, you need the Workstation Enabler at the very least. If you don't, the standard Warp kit will do.

Tools to build the Implementation Repository (regimpl) and start the DSOM Daemon (somdd) are all present. This can be easily verified by issuing these commands from an OS/2 command line. Follow the prompts to view information with regimpl but don't find any thing unless you know what you are doing! Ctrl-Break can be used to end somdd.

If you are a developer and subscribe to the IBM Developer's Connection (DEVCON), the CD-ROMs supplied have the latest version of the SOMobjects Developer Toolkit together with the SOMobjects Workstation Enabler and the SOMobjects Workgroup Enabler. This is the full product with an evaluation licence that runs until the next issue of CDs at which time it may be renewed if you are still subscribing. You will find it all in the LAN DEVCON catalog rather than the OS/2 one.

Summary
This has been a brief overview of the System Object Model and its Distributed SOM framework. There is complexity and detail in it that I have skated over to avoid writing a book rather than a magazine article. However, the good news is that the complexity is on the inside as part of the implementation not on the outside where you have to deal with it.

SOM is remarkably easy to use. As an end user, it is virtually invisible of course. However, we see the effects in the Workplace Shell with the appearance of programs and controls built out of existing SOM-based Shell objects and inheriting their current behaviour.

As programmers, SOM is also easy to use. This is particularly true when we consider the use of DSOM to hide the complexities of communications programming. It makes workstation to workstation programming a process to process affair.

I haven't had the time or the space to cover Persistence SOM, Replication SOM and the other frameworks that make up the total kit. Maybe next time. However, to summarise, these encapsulate and thus simplify a variety of tasks we find ourselves facing in a multi-workstation or client server environment.

Object oriented technology is a wave of the future that has finally reached the beach. The enabling technologies such as SOM are in place and are gaining in maturity, function and platform spread. It is now accepted that the future of information systems will be built on an Object Oriented base. The way things are shaping up, a large piece of that base will be the System Object Model.

A Quick and Hopelessly Inadequate Introduction to Object Orientation
We live in a world of objects. Everything we perceive is a distinct object with its own inherent behaviour and state. Programs seek to model a portion of our world to automate in some way the processes concerned with that portion. We call a portion of the world we try to model in this way a Problem Domain. Like anything else, any problem domain is composed of interacting real world objects.

Traditionally, these real world objects are modelled by replicating aspects of their behaviour through things such as programs, files, databases and so on. In contrast, object orientation attempts to model the salient characteristics of the problem domain itself by implementing the real world objects as Software Objects. This preserves their identity into the delivered solution with consequent benefits in timeliness, cost, maintenance and quality of the final result.

To understand software objects, it is useful to start by looking at real world objects and understanding what they are. To start with, all real world objects have attributes and behaviour. The attributes define the object's state and the behaviour defines how it interacts with the outside world. The same is true of software objects. Each object is made up of a set of Attributes or data elements and a set of Methods or functions that operate on them. The attributes define what the object is and its state at any particular time. The methods define its behaviour.

External entities, usually other objects, that interact with a software object do not see the object as a collection of attributes and methods. Instead they see a single entity from which they can request a defined set of services through a set externalised interface. The implementation details, how the methods work and what attributes it uses, are not visible to other objects. This property is called Encapsulation and is fundamental to object oriented systems.

Just as human beings perceive the real world of objects through classes, for example tables, chairs and so on, so software objects are all instances of classes that define their form and behaviour. An object Class is in fact a definition of what the actual objects that make up the class will be like. Like a COBOL record layout, a class defines the number and type of attributes that objects of that class will have. Unlike a COBOL record layout, a class also defines the behaviour of the particular objects that belong to the class. In other words, the methods are defined at the class level not the individual object level.

Individual objects are created as instances of a particular class, a process called Instantiation. When an object is instantiated, the attributes that make up the class instance, the object, are filled in with its own instance data. The methods provided by the class are then used to implement its behaviour.

Inheritance and Aggregation are key reuse mechanisms. Inheritance enables new, more specific classes to be created from old, more general classes and Aggregation enables new classes to include other objects as part of their attributes.

With Inheritance, new classes inherit all the old class attributes and methods and may add to or override these with attributes and methods of its own. In this relationship, the parent classes are called super-, parent or base classes and the derived classes are called sub- or derived classes.

This is not the same as copying the original class definition and then making finds to produce a new class ("copy and hack"). With inheritance, the actual content of the base class becomes part of the derived class. finds to the internal implementation of the base class are inherited automatically by the derived class.

Another way in which classes can be related is Aggregation or Composition where a particular class can be composed of others. In other words, the attributes of a particular class can include objects of other classes. When an object is instantiated from that class, the attributes are instantiated at the same time.

Object Management Group
The Object Management Group (OMG) is a non-profit industry consortium of over 485 members including Apple, IBM, Microsoft, HP, SUN, Taligent and Component Integration Labs (CIL). It is one of the key drivers behind the standardisation of object oriented technology in the distributed environment. OMG has two primary aims:
 * 1) The promotion of the OO approach to software engineering in general
 * 2) The development of common models and a common interface for the development and use of large-scale distributed applications (open distributed processing) using OO methodologies.

In late 1990, the OMG published its Object Management Architecture (OMA) Guide document. This document outlines a single terminology for OO languages, systems, databases and application frameworks, an abstract framework for OO systems, a set of both technical and architectural goals and an architecture (reference model) for distributed applications using OO techniques. To fill out this reference model, four areas of standardisation have been identified:
 * 1) Object Request Broker (ORB) for handling distribution of method calls between application objects in a highly interoperable manner,
 * 2) Object Model for communicating with OMG-conforming OO systems,
 * 3) Object Services which will provide the main functions for realising basic object functionality using the ORB, the logical modeling and physical storage of objects,
 * 4) Common Facilities that will provide facilities which are useful in many application domains and which will be made available through OMA compliant class interfaces.

In late 1991, OMG adopted its first interface technology for the Object Request Broker. It is called the Common Object Request Broker Architecture (CORBA). Work on other areas continues to this day. For more information on OMG, they have a web server at http://www.omg.org. You can also order copies of the OMA and CORBA architecture documents as well as subscribe to their magazine, First Class.