Distributed Objects - OMG/OMA/CORBA

Some Distributed Object Systems:

We focus on OMG's CORBA/OMA.

OMG sees Distributed Computing in the context of its use and calls it Enterprise Computing. Here is OMG's view of Enterprise Computing.

	+---+--------------------------------------------+---+
	| M | CORBA Domain | CORBA Domain | CORBA Domain |   |
	| E +--------------------------------------------+   |
	| T |         Common Business Objects*           |   |
	| A +--------------------------------------------+   |
	|   |         Business Object Facility*          |   |
	| O +--------------------------------------------+ S |
	| B |             CORBA Facilities               | E |
	| J +--------------------------------------------+ C |            UML
	|   |              CORBA Services                | U |         MODELING
	| F +--------------------------------------------+ R |
	| A |       Interoperability: IIOP, Asynch*      | I |
	| C +--------------------------------------------+ T |
	| I |        Real Time*, Embedded* options       | Y |
	| L +--------------------------------------------+   |
	| I |          Components*, Scripting*           |   |
	| T +--------------------------------------------+   |
	| Y |     IDL Interfaces, Mappings, and ORB      |   |
	+---+--------------------------------------------+---+

	          (from: J.Siegel, J.ACM, Oct. 1998)
[the * next to a topic means that the topic is being standardized]

OMG seems to make a distinction between Interfaces, Components, Application Objects, and Business objects. Interfaces, or just Objects, correspond closely to C++ classes. Components, which are currently being defined, will include one or possibly more interfaces. Application Objects are objects designed to operate using all available services and facilities of CORBA/OMA. Business Objects are Application Objects that carry out specific busines functions, things like Order Entry and Shipping. Here is how Application Objects are supposed to interact in OMA:

	+-------------+  +------------------+  +------------------+
	| Application |  | Vertical (Domain)|  |    Horizontal    |
	|   Objects   |  | CORBA Facilities |  | CORBA Facilities |
	+--------+----+  +--------+---------+  +--------+---------+
                 |                |                     |
                 |                |                     |
	   +     |                |                     |         +
	 / +-----+----------------+---------------------+---------+ \
	+               Object  Request  Broker                      +
	 \ +-------------------------+----------------------------+ /
	   +                         |                            +
                                     |
		+--------------------+-------------------+
		|                                        |
		|               CORBA  SERVICES          |
		|                                        |
		+----------------------------------------+

	    Interaction of Objects in their environment (OMA)

CORBA objects can:

It is believed by some that in time many devices will be placed on the internet and seen and used by their neighbors as Corba objects. A similar route is being taken in the Java/Sun world with the Jini system.

JavaBeans can:

DCOM objects can:

These different distributed object models are being developed with mutually communicating gateways

Here is a diagram that represents the basic elements of CORBA's model:

	+-----------+   +---------+   +---------------+
	| Interface |   |  IDL    |   | Implementation|
	| Repository|   | Compiler|   | Repository    |
	+-----------+   +---------+   +---------------+


	+-------+                            +--------+
	| Client|--------+                 +-| Servant|-------+
	+-------+         \               /  +--------+       |
	    |    \         \             /     |     \        |
	    v     \         \           /      v      \       |
	+-----+   +-----+    +---------+  +--------+  +-----+ |
	| DII |   | IDL |    |   ORB   |  |  IDL   |  | DSI | |
	+-----+   |Stubs|    |Interface|  |Skeleton|  +-----+ v
	          +-----+    +---------+  +--------+ +---------+
	                                  +----------+  Object |
	                                  |            Adapter |
	                                  +--------------------+

	+------------------------------------------------------+
	|                   ORB  Core                          |
	|                using GIOP -IIOP                      |
	+------------------------------------------------------+
where:

It is convenient to distinguish between the object being accessed, and the code that implements that object. This implementation code is called a servant. The object is what executes, including the connections to its environment. The servant is just the code that implements the behavior of the object.

Here are the programming steps typically required to compile and use a new object:

  1. Define the object interfaces in the Interface Definition Language (IDL). The definition takes the form of an interface, the IDL equivalent of classes.
  2. Implement these interfaces with C++ classes (assuming you are using C++, or Java, or C, or SmallTalk, or ..).
  3. Write a server mainprogram which can create instances of the servant.
  4. Register the server with some sort of service (something like PORTMAP of ONC RPC).
  5. Write a client to bind to and use the server's objects.
It is now possible on some systems to skip the implementation of the server and have the ORB activate the servant code thorugh the use of Object Adapters.

Method Invocation Modes: In a Distributed Object System a call to a method of a remote object takes place through a local Proxy (also known as a Stub) which communicates with the object on the remote system through a Skeleton also on that system. The call can be:

Parameter Passing Modes: When a method of a remote object is invoked, the parameters of the call are sent across from the client to the server. If a parameter has a traditional data type, i.e. not an object, it is passed by value. If it is an object, in CORBA until very recently it could only be passed by reference. Now it can be passed by reference or by value; in RMI and DCOM it can be passed either by reference or by value. The mode in which a parameter is passed has a great impact on performance. When an object is passed by reference the server to which it is passed will call the methods of the object remotely for execution wherever that object is. If instead the object is passed by value, a copy of the object is serialized over to the server and used there locally. Of course this requires that the methods of the transferred object be able to execute on the receiving system. This is easy if the code is Java (or we remain within a WINTEL world), less so in other languages. When the parameter is passed by value, any changes made in the transferred object are not seen in the system where the object was copied from. Dynamic Class Download is what allows the passing of objects by value.

Linking Mode: The methods of an object can be called statically or dynamically. Statically is the usual way: we know at compile time what is the object, say foo, what is the method, say moo, and what are the parameters, thus we call explicitly foo.moo(...). But in some cases when we write our program we may not know what objects will be available in its environment at run time. We want to be able at run time to invoke a service (see below) and find out what objects are available, calling then what is appropriate. This can be done through the Dynamic Interface Invocation. Similarly on the server side the invocation of the servant code can be done statically, through the IDL skeleton, or dynamically through the Dynamic Skeleton Interface.

Interface Definition Language (IDL)
This is the mechanism for defining interfaces, particularly in the inter-language systems of CORBA and DCOM. Java was designed to separate Interface definition from Implementation definition, and thus the interface definition constructs are utilized.

Here is an example of an IDL file (from "Corba Distributed Objects using Orbix", by S. Baker, Addison-Wesley 1997);

	// front.idl
	typedef float Price;
	struct Place {
		char row;
		unsigned long seat;
	};
	interface FrontOffice {
		readonly attribute string name;
		readonly attribute unsigned long numberOfSeats;
		Price getPrice (in Place chosenPlace);
		boolean bookSingleSeat (in Place chosenPlace, in string creditCard);
	};
and here is the corresponding .h file generated by the IDL compiler:
	// front.h
	#include <CORBA.h>

	typedef CORBA::Float Price;
	struct Place (
	    CORBA::Char row;
	    CORBA::ULong seat;
	};
	// .. some other declarations that we skip, and then 

	class FrontOffice: public virtual CORBA::Object {
	public:
		virtual char* name() throw CORBA::SystemException);
		virtual CORBA::uLong numberOfSeats() 
				throw (CORBA::SystemException);
		virtual Price getPrice(const Place& chosenPlace)
				throw (CORBA::SystemException);
		virtual CORBA::Boolean bookSingleSeat (
			const Place& chosenPlace,
			const char* creditCard)
				throw (CORBA::SystemException);
	};
Object Request Broker (ORB)
A system that uses objects (the client), or a system that makes available objects (the servers), must have an Object Request Broker (ORB). The ORB is the basic mechanism for making requests to an object and for receiving the responses. If the client and server are in different systems, their ORBs (even if by different manufacturers) must be able to interoperate. They can communicate using a connection-oriented protocol called GIOP (General InterOrb Protocol), or, if the transport layer is TCP/IP, using IIOP (Internet InterOrb Protocol). Basic message codes are Request, Reply, CancelRequest, LocateRequest, LocateReply, CloseConnection, MessageError. Usually the ORB does not take the form of a separate process, instead it is a library linked with the user process. For example, the Netscape browser comes with an included ORB.
Interoperable Object References (IORs)
References to objects are called Interoperable Object References (IORs). A IOR consists of three kinds of information: Binding is the process by which we arrive at a servant given a IOR.
Object Adapters (OA)
Object Adapters mediate between ORBs, Corba object references, and the code written in some programming language that implements them, the servants. Object Adapters are responsible for Since an object may not be currently running, and it must run in the context of a server process, an Object Adapter must if necessary activate a process or a thread and execute the servant code. A Basic Object Adapter (BOA) is available for this purpose. It takes the form of a process distinct from the ORB's. BOA implementations have tended to be proprietary so that servant code is less portable than desireable. Currently Portable Object Adapters (POA) are becoming available that obviate this problem. As indicated in the following diagram, a system may have multiple POA which in turn can be each responsible for many objects.
 
                  Server System
           +----------------------------+
           |                  ->servant |
           |         +---+   /          |
   Call    | +---+-->|POA|-->-->servant |
  -------->| |ORB|   +---+              |
           | +---+-->+---+----->servant |
           |         |POA|----->servant |
           |         +---+              |
           +----------------------------+

A servant is executed within a thread of a POA or as a process forked by the POA. A POA may follow a number of object activation policies in forking processes:

A POA may follow a number of multithreading policies in creating threads. These policies to an extent mirror the activation policies seen above:
Registry
This is a feature of the name service. Corba supports a registry with ongoing persistence, while RMI's registry is restarted everytime the server is restarted. DCOM utilizes the NT's registry for finding objects/interfaces by their GUID (Globally Unique Identifier - 16 bytes). Corba's registry is distinguished in a Interface Repository, where are kept the IDL definitions for all the objects, and a Implementation Repository, where are kept the executables for all the objects.
Interface Multiple Inheritance
In the definition DCOM, Microsoft dealt with the fragile base class problem by eliminating multiple inheritance when defining interfaces. Microsoft provides similar functionality through aggregation and containment, containing the objects you might otherwise inherit from and either expose there interfaces as your own, or wrapping the object. All other systems appear to provide multiple inheritance for interfaces, easing the programmer's workload.
Maintain state between connections
Because DCOM has a more procedural basis to its system than other distributed objects systems, in can suffer when an unplanned disconnect occurs. If the programmer has not saved the state of the DCOM object before losing a connection, the objects state will be lost. Because the other systems are based on a 'true' OOP model, the object does not need to be explicitly saved, and a connection loss will not result in the loss of the objects state. This also means that DCOM relies on the client to provide the information necessary to restore an object from storage when it has been saved.
Through Firewalls
Firewalls can pose problems to distributed object systems, since many DO systems are based on tcp/ip connections that for safety's sake are often filtered out of a company's Internet feed at its entry firewall. Several mechanism have been put in place to remedy this, including tunneling in HTTP connections (inefficient), using proxies such as SOCKS, or replacing the standard firewall with a firewall that is friendly to Distributed Object System. Iona appears to have done just that with its WonderWall firewall software.
Multicast
Systems supporting this feature allow simultaneous broadcast to multiple clients. While DCOM documentation mentions it's feasibility, RMI has stated plans to implement this feature.
Distributed Garbage Collection
It deals with the question of how remote objects are managed when they are no longer needed. This is a problematic issue and it seems that no perfect solutions exists. In RMI this is handled by remote reference counting, which means that if a client disconnects for a period of time, the object they were connected to could be garbage collected (although an exception does notify the program when this occurs). In Corba systems this is addressed in the Life Cycle Management Services. It is again done by keeping count of the number of connections to an object, saving and/or deleting the object when the number of connections falls to zero. In Java DCOM implementations, it is left to the OS to do garbage collection at program shutdown time. Obviously this won't work for ongoing servers, and it is likely a temporary solution since C++ DCOM utilizes another mechanism whereby an object keeps track of the events occurring when another object claims to be using it and/or finished with it. This system too would seem to be frought with problems, since it makes an object dependent on the good behavior of other objects (ie. on their programmers ) so that they will release it when they are done with it.

In addition to supporting calls to methods of remote objects Distributed Object Systems provide a variety of Services and Facilities that make easier the development of reliable distributed applications.

Life Cycle Service
Object Operations for:
Persistence Service
A single interface for storing components persistently on a variety of storage servers, such as: Java has begun supporting this internally through the java.io. Serialization and Externalization mechanisms.
Naming Service
Allows components on the bus to locate other components by name, including federated naming contexts. The service allow object to be bound to existing network directories or naming contexts - including: Corba supports this feature with persistence saving changes to the registry. Corba, given the name of an object, returns an object reference to that object. RMI does have a Naming Service, but it lacks persistence. DCOM does have a registry to lookup objects by their GUID (Globally Unique Identifier).
Event Service
Allows Components on the bus to dynamically register or unregister their interest in specific events. The service defines a well known object called an event channel that collects and distributes events among components that know nothing of each other, from the servers to the clients. This is supported by CORBA, and JDK 1.1 new event model certainly goes a long way towards making this feasible in pure-Java systems.
Concurrency Control Service
Provides a lock manager that can obtain locks on behalf of either transactions or threads and make concurrent access to objects safe.
Transaction Service
Provides two-phase commit coordination among recoverable components using either flat or nested transactions.
Relationship Service
Provides a way to create dynamic associations (or links) between components that know nothing of each other. Provides mechanisms for traversing the links that group these components. Use this service to:
Externalization Service
Provides a standard way to get data into and out of a component using a stream-like mechanism. This supports objects migration.
Query Service
Provides query operations for objects via a superset of: SQL3 and... ODMG's OQL (Object Database Management Groups's Object Query Language)
Licensing Service
Provides operations for metering the use of components to ensure fair compensation for their use. The service supports any model of usage control at any point in a components life cycle. It supports charging by: CORBA provides this facility. DCOM provides a licensing system that looks to a local file to see if a file exists that contains the license number to enable a user to run a program. DCOM also enable a per component licensing model via a licensing key in the registry.
Properties Service
Provides operations to let you associate named values (properties) with any component. Using this service you dynamically associate properties with a component's state, such as a title or date. It would seem this is simple enough to do in Java, by having your object contain an java.util.property object.
Security Service
DCOM supports many of these features, and according to some newsgroup arguments, implements them better than Corba does.
Time Service
Maintains a single notion of time across different machines. One can also request alarms, that is events to occur at specified times.
Trader Service
'Matchmaking' services Provides a yellow pages like service, advertising attributes of object offered. Federations of traders advertise services, while each individually manages policies and services.
Collections Service
Provides operations to manipulate objects in a group Examples: Queues, Stacks, Lists, Arrays, Trees, Sets, Bags A third-party library jgl offers many of these features to Java.
Change Management Service
Provides facilities to track different component versions, both interface and implementation. Maintains evolution history Ensure an object uses a consistent implemention version Version encoded into object references Find object versions by name Contexts, such as example, demo, test & release Check-out/Check-in DCOM provides a Versioning service


Where Services are utilities for objects, Facilities are utilities for applications. Facilities are separated into:

Facilities will be implemented taking advantage of existing services. Objects will be able to utilize, by inheritance or aggregation, both services and facilities.


Here is a very simple example that runs with the Orbix ORB.