At its core, the CORBA architecture for distributed objects shares many features with the architecture used by Java RMI. A description of a remote object is used to generate a client stub interface and a server skeleton interface for the object. A client application invokes methods on a remote object using the client stub. The method request is transmitted through the underlying infrastructure to the remote host, where the server skeleton for the object is asked to invoke the method on the object itself. Any data resulting from the method call (return values, exceptions) is transmitted back to the client by the communication infrastructure.
But that’s where the similarities between CORBA and RMI end. CORBA was designed from the start to be a language-independent distributed object standard, so it is much more extensive and detailed in its specification than RMI is (or needs to be). For the most part, these extra details are required in CORBA because it needs to support languages that have different built-in features. Some languages, like C++, directly support objects, while others, like C, don’t. The CORBA standard needs to include a detailed specification of an object model so that nonobject-oriented languages can take advantage of CORBA. Java includes built-in support for communicating object interfaces and examining them abstractly (using Java bytecodes and the Java Reflection API). Many other languages don’t. So the CORBA specification includes details about a Dynamic Invocation Interface and a Dynamic Skeleton Interface, which can be implemented in languages that don’t have their own facilities for these operations. In languages that do have these capabilities, like Java, there needs to be a mapping between the built-in features and the features as defined by the CORBA specification.
The rest of this section provides an overview of the major components that make up the CORBA architecture: the Interface Definition Language, which is how CORBA interfaces are defined; the Object Request Broker (ORB) and Object Adaptor, which are responsible for handling all interactions between remote objects and the applications that use them; the Naming Service, which is a standard service in CORBA that lets remote clients find remote objects on the network; and the inter-ORB communication protocol, which handles the low-level communication between processes in a CORBA context.
The Interface Definition Language provides the primary way of describing data types in CORBA. IDL is independent of any particular programming language. Mappings, or bindings, from IDL to specific programming languages are defined and standardized as part of the CORBA specification. At the time of this writing, standard bindings for C, C++, Smalltalk, Ada, COBOL, Lisp, Python and Java have been approved by the OMG. Chapter 14 contains a complete description of IDL syntax.
The central CORBA functions, services, and facilities, such as the ORB and the Naming Service, are also specified in IDL. This means that a particular language binding also specifies the bindings for the core CORBA functions to that language. Sun’s Java IDL API follows the Java IDL mapping defined by the OMG standards. This allows you to run your CORBA-based Java code in any compliant Java implementation of the CORBA standard, provided you stick to standard elements of the Java binding. Note, however, that Sun’s implementation includes some nonstandard elements; they are highlighted in this chapter where appropriate.
The core of the CORBA architecture is the Object Request Broker, as shown in Figure 4-1. Each machine involved in a CORBA application must have an ORB running in order for processes on that machine to interact with CORBA objects running in remote processes. Object clients and servers make requests through their ORBs; the ORB is responsible for making the requests happen or indicating why they can’t. The client ORB provides a stub for a remote object. Requests made on the stub are transferred from the client’s ORB to the ORB servicing the implementation of the target object. The request is passed on to the implementation through an object adaptor and the object’s skeleton interface.
The skeleton interface is specific to the type of object that is exported remotely through CORBA. Among other things, it provides a wrapper interface that the ORB and object adaptor can use to invoke methods on behalf of the client or as part of the lifecycle management of the object. The object adaptor provides a general facility that “plugs” a server object into a particular CORBA runtime environment. Older versions of the CORBA specification and Java IDL supported a Basic Object Adaptor (BOA) interface, while newer versions (CORBA 2.3 and later, JDK 1.4 and later) support a Portable Object Adaptor interface (we’ll discuss the difference later in the chapter). All server objects can use the object adaptor to interact with the core functionality of the ORB, and the ORB in turn can use the object adaptor to pass along client requests and lifecycle notifications to the server object. Typically, an IDL compiler is used to generate the skeleton interface for a particular IDL interface; this generated skeleton interface will include calls to the object adaptor that are supported by the CORBA environment in use.
The CORBA Naming Service (sometimes abbreviated to
COSNaming, from “CORBA Object
Services, Naming”) provides a directory naming
structure for remote objects. The CORBA Naming Service is one of the
naming and directory services supported by JNDI, so the concepts used
in its API are similar to the general model of
used in JNDI.
The naming tree always starts with a root node, and subnodes of the object tree can be created by an application. Actual objects are stored by name at the leaves of the tree. Figure 4-2 depicts an example set of objects registered within a Naming Service directory. The fully qualified name of an object in the directory is the ordered list of all of its parent nodes, starting from the root node and including the leaf name of the object itself. So, the full name of the object labeled “Fred” is “Living thing,” “Animal,” “Man,” “Fred,” in that order.
Each branch in the directory
tree is called a naming context, and leaf
objects have bindings to specific names. Each
node in the naming directory is represented by an
org.omg.CosNaming.NamingContext object. Each
NamingContext can be asked to find an object
within its branch of the tree by asking for the object by name,
relative to that particular naming context. You can get a reference
to the root context of the naming directory from an ORB using the
resolve_initial_references( ) method. Once you
have a reference to the root of the naming directory, you can perform
lookups of CORBA objects, as well as register your own CORBA objects
with the Naming Service. We’ll see more concrete
details of utilizing the CORBA Naming Service later in this chapter
in Putting It in the Public Eye.
Version 2.0 (and later) of the CORBA standard includes specifications for inter-ORB communication protocols that can transmit object requests between various ORBs running on the network. The protocols are independent of the particular ORB implementations running at either end of the communication link. An ORB implemented in Java can talk to another ORB implemented in C, as long as they’re both compliant with the CORBA standard and use the same CORBA communication protocol. The inter-ORB protocol is responsible for delivering messages between two cooperating ORBs. These messages might be method requests, return types, error messages, etc. The inter-ORB protocol also deals with differences between the two ORB implementations, like machine-level byte ordering and alignment. As a CORBA application developer, you shouldn’t have to deal directly with the low-level communication protocol between ORBs. If you want two ORBs to talk to each other, you need to ensure that they are compatible in terms of CORBA compliance levels (do they support similar levels of the CORBA specification?) and that they both speak a common, standard inter-ORB protocol.
The Internet Inter-ORB Protocol (IIOP) is an inter-ORB protocol based on TCP/IP. TCP/IP is by far the most commonly used network protocol on the Internet, so IIOP is the most commonly used CORBA communication protocol. There are other standard CORBA protocols defined for other network environments, however. The DCE Common Inter-ORB Protocol (DCE-CIOP), for example, allows ORBs to communicate on top of DCE-RPC.
 Example adapted from Categories, by Aristotle. Please pardon the categorization “man,” as opposed to “human.” This is the typical translation of Aristotle’s original Greek, perhaps because political correctness wasn’t in fashion in 350 B.C.