47
CHAPTER 1 Object-orientation Encapsulation provides the ability to hide the internal details of an object from its users. The state of an object may be altered indirectly using accessor and mutator methods. Encapsulation is implemented using the access modifier keywords public, private and protected. Encapsulation is also known as data hiding or information hiding. Inheritance is used to build new classes using the existing class definitions. The original class is known as parent or base class and the modified one is known as derived class or subclass or child class. The main purpose of inheritance is reusability of existing code. Polymorphism is the ability to take more than one form. The behavior depends upon the types of data used in the operation. Polymorphism is extensively used while implementing inheritance. Abstraction – An essential element of object-oriented programming is abstraction. A powerful way to manage abstraction is through the use of hierarchical classifications. Hierarchical abstractions of complex systems can also be applied to computer programs. The data from a traditional process-oriented program can be transformed by abstraction into its component objects. Thus, each of these objects describes its own unique behavior. Reasons to Distribute for Centralized Objects The properties of data that lead naturally to distribution are as given below: 1) Data are used at one peripheral location and rarely or never at other locations 2) Data accuracy, privacy and security are a local responsibility 3) Files are simple and used by one or a few applications 4) Update rates are too high for a single centralized storage system 5) A localized decision-support system is used 6) Data are used by centralized applications 7) Users in all areas need access to the same data and need the current up-to-the-minute version 8) Users of the data travel among many separate locations and it is less expensive to centralize data than to use a switched data network 9) Data as a whole will be searched 10) Mainframe database software is needed 11) A high level of security must be maintained over the data 12) Data are too large to be stored on peripheral storage units 13) Details are kept of transactions updating certain data, so it is cheaper and more secure to store centrally Advantages of Distributing > Reduced transmission costs > Improved response times > Increased availability > Increased survivability (from multiple copies of the same data) > Organization of databases around the use of data Problems of distributing include: > More difficult transaction updates > Inconsistent views of data > Increased opportunity for deadlocks > Increased control overhead > Increased recovery complexity > Multiple data representations > Difficult to audit > Security and privacy control complexity

Overview of Com-Dcom

Embed Size (px)

Citation preview

Page 1: Overview of Com-Dcom

CHAPTER 1

Object-orientation

Encapsulation provides the ability to hide the internal details of an object from its users. The state of an object

may be altered indirectly using accessor and mutator methods. Encapsulation is implemented using the access

modifier keywords public, private and protected. Encapsulation is also known as data hiding or information hiding.

Inheritance is used to build new classes using the existing class definitions. The original class is known as parent

or base class and the modified one is known as derived class or subclass or child class. The main purpose of

inheritance is reusability of existing code.

Polymorphism is the ability to take more than one form. The behavior depends upon the types of data used in the

operation. Polymorphism is extensively used while implementing inheritance.

Abstraction – An essential element of object-oriented programming is abstraction. A powerful way to manage

abstraction is through the use of hierarchical classifications. Hierarchical abstractions of complex systems can also

be applied to computer programs. The data from a traditional process-oriented program can be transformed by

abstraction into its component objects. Thus, each of these objects describes its own unique behavior.

Reasons to Distribute for Centralized Objects

The properties of data that lead naturally to distribution are as given below:

1) Data are used at one peripheral location and rarely or never at other locations

2) Data accuracy, privacy and security are a local responsibility

3) Files are simple and used by one or a few applications

4) Update rates are too high for a single centralized storage system

5) A localized decision-support system is used

6) Data are used by centralized applications

7) Users in all areas need access to the same data and need the current up-to-the-minute version

8) Users of the data travel among many separate locations and it is less expensive to centralize data than to use a

switched data network

9) Data as a whole will be searched

10) Mainframe database software is needed

11) A high level of security must be maintained over the data

12) Data are too large to be stored on peripheral storage units

13) Details are kept of transactions updating certain data, so it is cheaper and more secure to store centrally

Advantages of Distributing > Reduced transmission costs

> Improved response times

> Increased availability

> Increased survivability (from multiple copies of the same data)

> Organization of databases around the use of data

Problems of distributing include:

> More difficult transaction updates

> Inconsistent views of data

> Increased opportunity for deadlocks

> Increased control overhead

> Increased recovery complexity

> Multiple data representations

> Difficult to audit

> Security and privacy control complexity

Page 2: Overview of Com-Dcom

Mapping objects to locations – The distributed architecture maps distributed object locations to their exact locations and stores this information in a system database.

This database can be accessed using the Registry, Name Server or Directory Services. In Windows OS, the Registry acts as a decoupling

layer between the client and server objects. The client activates the server using some info that is stored in the Registry; one piece of

information is the physical location of the server executables. If the location changes, the information in the Registry is updated

accordingly, but this is transparent to the client, who just uses ProgIDs or CLSIDs.

Object oriented system architecture :

Client-server system architecture

Client-server architecture is network architecture in which each computer or process on the network is either a

client or a server. Servers are powerful computers or processes dedicated to managing disk drives (file servers),

printers (print servers), or network traffic (network servers). Clients are PCs or workstations on which users run

applications. Clients rely on servers for resources, such as files, devices, and even processing power.

Multi-tier system architectures

Servers are mainly file and database servers; application servers are the exception. Database-servers only offer

data on the server; consequently the application intelligence must be implemented on the client PC. Since there are

only the architecturally tiered data server and client, this is called 2-tier architecture. The 2-tier model is

widespread because of the quality of the tools and middleware that have been most commonly used since the 90’s:

Remote-SQL, ODBC, relatively inexpensive and well integrated PC-tools. In comparison the server side uses

relatively expensive tools.

Why 3-tier?

> In a 2-tier architecture, business-logic is implemented on the PC.

> Some O.S. like Windows etc., have tough resource restrictions.

> Increased network load: since the actual processing of the data takes place on the remote client, the data has to

be transported over the network.

> Data is only "offered" on the server, not processed. Stored-procedures are a form of assistance given by the

database provider.

> Application logic can’t be reused because it is bound to an individual PC-program.

> The influences on change-management are drastic: due to changes in business politics or law

> the 2-tier-model implies a complicated software-distribution-procedure: as all of the application logic is executed

on the PC, all machines have to be updated in case of a new release. This can be very expensive, complicated,

prone to error and time consuming. Distribution procedures include the distribution over networks or the

production of an adequate media like floppies or CDs.

> 3- and n-tier architectures endeavour to solve these problems. This goal is achieved primarily by moving the

application logic from the client back to the server.

Client-tier (User Interface) - Responsible for the presentation of data, receiving user events and controlling the

user interface. The actual business logic has been moved to an application-server.

Application-server-tier-Not present in 2-tier architecture in this explicit form.Business-objects that implement the

business rules are here,and r available to the client-tier.This tier protects thedata from direct access by the clients.

Data-server-tier (Data storage) - Responsible for data storage. Boundaries between tiers are logical. It is possible

to run all three tiers on one and the same machine. The main importance is that the system is neatly structured, and

that there is a well planned definition of the software boundaries between the different tiers.

Design of object oriented system architecture:-In distributed object systems, the

architecture is of great importance. The architecture document is a reference guideline to which all the developers

and users must adhere. If not, an expensive and time- consuming chaos results.Some Design Issues:

System interface- The boundaries between tiers are represented by object interfaces. Due to their importance they

have to be very carefully designed, because their stability is crucial to the maintenance of the system, and for the

reuse of components. Architecture can be defined as the sum of important long-term system interfaces. They

include basic system services as well as object-meta-information.

Security - In distributed systems, data-protection and access control is the important thing. In the CORBA-standard,level 1 provides

authentication control for security unaware applications.Level 2 is much more fine-grained.

Transactions - Transaction mechanisms have to be used. Standardized OMG interfaces are present, and many implementations have

been done. The standard defines interfaces to two-phase-commit and offers new concepts like nested transactions.

Page 3: Overview of Com-Dcom

CHAPTER 3

COM as better C++ software distribution

• Principle goals for C++ is to allow programmers to build user-defined types that could be reused outside

their original implementation context. The principle uses the idea of class libraries or frameworks.Many

libraries are documented in such a manner that user of the library will refer to the library’s source code for

reference. This results in coupling between the client application and class library. The coupling effect

reduces the modularity of a class library and makes it more difficult to adapt changes in the library

implementation.Clients treat the library as part of the project’s source code base and not modular reusable

component.

• Reuse has always been one of the classic motivations for object orientation. C++ object model is less

than ideal substrate for building reusable software components. Many of these obstacles stem from the

compilation and linkage model assumed by C++.

• Allows dynamic and efficient composition of systems from independently developed binary components.

• Problems using C++ as a component substrate is that the search time will be constant and not proportional

to the length of the target string.

• To make the algorithm as simple to use as possible, vendor would prepare a header file that contains a class

definition

• C++ libraries have been distributed in

source code form.

• Recompile the executable code of the

library would be bundled as part of

the overall client application.

• The generated machine code occupies

for eg. 16 MB of space in the target

executable image. If three

applications use the X library, each of the three executables will contain the 16 MB worth of code, i.e

occupies 48 MB of disk space. If the end user runs client application simultaneously 48MB of virtual

memory is occupied and the OS cannot dectect the duplicate code that is present in each executable image.

• If the library vendor finds a defect in the X class, there is no way to replace the implementation. Once the

X code is linked into the client application, one can no longer replace the X code at the end-user’s machine.

Dynamic Linking and C++

• Once the X code is linked into the client application, one can no longer replace the X code at the end-user’s

machine.For solving the problem stated above is to package the X class as a Dynamic Link Library (DLL).

This can be done in many ways.Simplest technique is to use a class-level compiler directive to force all of

the methods of X to be exported from the DLL.

• All the methods of X will be added to the

exports list of the X DLL, allowing

runtime resolution of each method name

to its address in memory. The linker will

produce an import library. The import

library simply contains references to the

file name of the DLL and the names of

the exported symbols. Stubs are added to

the executable that inform the loader at

runtime to load the X DLL dynamically and resolve any imported symbols to their corresponding locations

in memory.

class FastString

{ char *m_psz ;

public:

FastString( char *psz); ~FastString();

int Length(void) ;

int Find(char *psz);

};

#include “faststring.h”

FastString::FastString( char *psz) { m_psz=new char[strlen(psz)+1];

strcpy(m_psz,psz) ; }

FastString::~FastString() { delete[] m_psz ; }

int FastString::Length(void)

{ return strlen(m_psz); } int FastString::Find(char *psz)

{ //Code to find }

class __declspec (dllexport) FastString

{ char *m_psz ;

public:

FastString( char *psz); ~FastString();

int Length(void) ;

int Find(char *psz); };

#include “faststring.h”

FastString::FastString( char *psz) { m_psz=new char[strlen(psz)+1] ;

strcpy(m_psz,psz) ;

} FastString::~FastString()

{ delete[] m_psz ;

} int FastString::Length(void)

{ return strlen(m_psz); }

int FastString::Find(char *psz) { //Code to find }

Page 4: Overview of Com-Dcom

Runtime Polymorphism

• To avoid having OS generated errors when the client program is run on a machine that does not have the

object implementation installed. The client never needs to link against the DLL’s import library, the

client has no load dependences on the DLL and can execute on machines that do not have the DLL

installed.

• Another reason for using Runtime Polymorphism is lazy initialization of the process’s address space. The

DLL is not automatically loaded at process initialization time, if the object implementation is never used,

the DLL is never loaded.Another benefits of using this technique is faster start-up in the client and

conservation of address space for long-lived processes that may never actually use the DLL.Allow the

client to select dynamically between various implementations of the same interface from deriving

additional implementation classes from the same interface.

C++ and Portability

o Fundamental weakness of C++ is lack of standardization at binary level e.g., if import library is

generated using a compiler say “x” by library vendor.

o The developer attempts to link to this import library using a different development environment say

“y” – Linking problem occurs.

• Linking problem occurs because Compilers implement name mangling to support operator and function

overloading. There is no uniform name mangling standard therefore every vendor implements his own

schemes for name mangling.

• Linking problem can be solved - The library vendor should compile his library using different compilers

so that he produces import library for every possible C++ compiler.

• There are even much more problematic areas related to incompatibilities related to different compilers that

need to be dealt with. E.g., exception thrown from a function compiled using a Microsoft compiler cannot

be caught reliably by a Watcom compiler or Borland compiler.

• The lack of C++ binary standard limits what language features can be used across DLL boundaries. This

means that exporting C++ class members functions from DLL is not enough to create a vendor-

independent component substrate.

Separating Interface from Implementation

• In C++, a class is both interface & implementation

• Model interface and implementation differently

• Interface as a data type as one class

• The data types actual implementation as the

other class called as the implementation class

• Interface class to be kept constant whereas

implementation can be modified

• Associate the interface with the

implementation without revealing any implementation details to the client

o Forwarding methods compiled along with X DLL

o If implementation of X changes, XItf constructor is recompiled and it will therefore allocate enough

memory

• Client never includes class definition of C++ implementation class X

Diagram Interface

• A Pointer

• Method decl of public funcs

• No data members

Implementation

• Data members

• Member funcs

Page 5: Overview of Com-Dcom

Encapsulation and C++

• C++ supports syntactic encapsulation via its private and protected keywords

• C++ draft standard has no notion of binary encapsulation because all information regarding object layout in

order to instantiate an instance of a class or to make nonvirtual method calls. It includes information about

the size and order of the object’s private and protected data members of version 1 requires four bytes per

instance. Class definition allocates four bytes of memory. Version 2 of the constructor and destructor and

methods all assume that the client has allocated eight bytes per instance, the second four bytes really

belong to someone else. Common solution to the versioning problem is to rename the DLL each time a

new version is produced. Number of versioned DLLs could conceivably exceed the number of actual client

applications due to poor software configuration practices.

• Versioning problem is rooted in the compilation model of C++, which was not designed to support

independent binary components. C++ introduces a tight binary coupling between the client and object

executables. This tight binary coupling prevents class implementations from being replaced without client

recompilation.

Handle Classes

• C++ interface class should not contain any of the data members that will be used in the implementation of

the object. The interface class should contain only method declarations for each public operation of the

object. The C++ implementation class will contain the actual data members required to implement the

object’s functionality. Use a handle class as the interface. The handle class would simply contain an opaque

pointer whose type would never be fully defined in the client’s scope.

• Diagram The forwarding methods would be compiled as part of the X DLL. The client never

includes the class definition of the C++ implementation class X. This affords the X implementor the

flexibility to evolve the implementation over time without breaking existing clients. The interface class

imposes a binary firewall between the client and the object implementation. All client-object

communications take place through the interface class, which imposes a very simple binary protocol for

entering the domain of the object’s implementation. Weaknesses – With hundreds or thousands of methods

becomes quite tedious, the cost of making two function calls for each method (1 call to the interface, 1

nested cal to the implementation) is less than ideal. The handle class technique does not completely address

the problems of compiler/linker compatibility, which ultimately must be solved if we are to have a truly

usable substrate for reusable components.

Page 6: Overview of Com-Dcom

CHAPTER 4

Interfaces and Implementations Revisited

• Motivation for separating Interface from Implementation is to hide from the client all details about object

implementation.

• Data members of the Implementation are allowed to change, and the client program does not require to

recompile.

• Extended functionality could be discovered by querying the object at runtime.

• DLL de-coupled from particular C++ compiler.

• Can use any C++ compiler to develop a component and to code a client.

• This means that it is C++ compiler independent.

• Although it is C++ compiler independent, it ultimately uses a C++ compiler.

• Achieve language independence to create a truly universal substrate for binary component.

• The object implementer defined interface in form of C++ abstract base class definition in a C++ header

file.

• Interface definition is in C++ and therefore can be parsable in only one specific language.

• By providing interface definition in C++ the implementer is forcing the component’s target audience also

to work in C++.

• To solve this problem we now separate the language used for defining interface from the language used for

defining implementation.

• COM Interface Definition Language is a language which can be used to define Interfaces.

• IDL takes basic well known syntax of C and adds the ability to disambiguate precisely any C language

features.

IDL

o COM IDL is based on Open Software Foundation Distributed Computing Environment Remote

Procedure Call (OSF DCE RPC).

o DCE RPC allows remote procedure call to be described in a language neutral manner.

o The DCE RPC enables an IDL compiler to generate networking code, that remotes the described

operations over a variety of network transports.

o COM IDL adds a few COM specific extensions to DCE RPC to support object oriented nature of

COM (i.e., polymorphism, inheritance etc.)

o The DCE RPC enables an IDL compiler to generate networking code, that remotes the described

operations over a variety of network transports

o Windows 95, NT uses MS-RPC which is an implementation of DCE RPC

o Single point of definition avoids having multiple incompatible versions of an interface definition

that can fall out of sync over time.

o The Win32 SDK includes an IDL compiler called MIDL.EXE that parses COM IDL files and

generates several artifacts.

o MIDL generates C/C++ compatible header files that contain the abstract base class definitions that

correspond to the interfaces that are defined in the original IDL.

o MIDL generate a binary file that allows other COM-aware environments to produce language

mappings for the interfaces defines in the original IDL file.

o IDL should be seen in two perspectives –

• Logical – Methods of Interface and operations they perform focus on logical aspects

• Physical – Discussion of memory, stack frames, network packets or other runtime

phenomena usually refer to the physical aspect of the interface.

Page 7: Overview of Com-Dcom

Interfaces and IDL

The IDL interface keyword is used to begin the definition of the interface.

The Interface definition has four components

1) the interface name

2) interface body

3) base interface name

4) interface attributes.

Every COM interface must have two IDL attributes. The [object] attribute is

required to indicate that the interface is a COM interface & not a DCE - style

interface

Why COM Interface require a physical name that is distinct from the

logical name of the interface?

Consider there are 2 developers, the first developer might run against an object created by the second

developer. Because the two interfaces share a common logical name, if the client were to interrogate the object

support simply using the string. The two interfaces are completely different despite the fact that they share a

common logical name.

To eliminate the name collision, all COM interfaces are assigned a unique binary name at design time that

is the physical name of the interface. These physical names are called Globally Unique Identifiers (GUID). GUID

are 128 bit extremely large numbers that are guaranteed to be unique in both time and space. GUIDs are referred as

IDs or CLSIDs.

o 32 hexadecimal digit represent 128 bit physical name called as GUID

(24 bytes)

o UUID means Universally Unique Identifier (DCE RPC)

o In case of Classes GUID is called as CLSID

o In case of Interfaces GUID is called as IID

o HRESULT CoCreateGuid(GUID *pguid) ;

Using COM Interface Pointers

Use the methods of IUnknown explicitly because the C++ language mapping of COM does not provide a runtime

layer between the client’s code and the object’s code. IUnknown is simply a set of promises that all COM

programmers make to one another.C++ can produce code that is potentially more performant than languages that

require a runtime layer to deal with COM.Unlike C++ programmers, Visual basic and Java Programmers never see

QueryInterface, AddRef or Release. For these two languages, the details of IUnknown are hidden deep below each

language’s supporting virtual machine. Type casting is not required in Vb. Type casting is required in Java.

Java, QueryInterface maps to

the Type-Cast

public void

TryToSnoreAndIgnore( Object j

)

{

IPug pug;

try {

pug = (IPug)obj ; // VM calls

QueryInterface

pug.Snore( );

} catch(Throwable ex) {

// Ignore method or QI

failure

}

VB does not require clients to

type-cast, when an interface

pointer is assigned to a type-

incompatible var, the VB VM

silently calls QueryInterface on

behalf of the client.

Sub TryToSnoreAndIgnore( Obj

as Object )

On Error Resume Next ‘ignore

errors

Dim pug as IPug

Set pug = obj; ‘VM calls

QueryInterface

If Not( pug is Nothing) Then

[attribute1, attribute2, ….]

interface IThisInterface :

IBaseInterface

{

typedef1;

typedef2;

method1;

method2;

}

Interfaces

----------� IIDs

----------�

CLSIDs

GUIDs

(128-

bit)

Implementations

Page 8: Overview of Com-Dcom

ICat cat;

try {

cat = (ICat)obj ; // VM calls

QueryInterface

cat.IgnoreMaster( );

} catch(Throwable ex) {

// Ignore method or QI

failure

}

}

pug.Snore

End if

Dim cat as ICat

Set cat = obj; ‘VM calls

QueryInterface

If Not( cat is Nothing) Then

cat.IgnoreMaster

End if

End Sub

Technique that can potentially simplify using COM interface pointers from C++ is to hide them behind a

smart pointer class, eliminating the need to make raw IUnknown calls. A COM smart interface pointer would.

• Correctly handle AddRef/Release calls during assignment.

• Auto-release the interface in a destructor, reducing the potential for resource leaks and improving exception

safety.

• Leverage the C++ type system to simplify calls to QueryInterface.

• Transparently replace raw interface pointers in legacy code.

Optimizing QueryInterface

Many production environments and frameworks favor a data-driven implementation to achieve greater

extensibility and better performanance due to code size reduction. Such implementations assume that each COM-

complaint class provides a table that maps each supported IID onto some aspect of the object using fixed offsets or

some other technique.

To implement a table-driven QueryInterface, one first meeds to define what the table will contain. Each table entry

will need to contain a pointer to an IID. For maximum flexibility, storing a function pointer at each table entry

would support the addition of new techniques for finding interfaces beyond the normal offset calculation used

when simply casting to a base class.

Resource Management and IUnknown COM’s reference counting rules distilled down to three simple axioms –

1. When a non-null interface pointer is copied from one memory location to another. AddRef should be called

to notify the object of the additional reference.

2. Release must be called prior to overwriting a memory location that contains a non – null interface pointer

to notify the object that the reference is being destroyed.

3. Redundant calls to AddRef and Release can be optimized away if there is special knowledge about the

relationship between two or more memory locations

Common situations that require calls to AddRef method :-

1. When writing a non-null interface pointer to a local variable

2. When a callee writes a non-null interface pointer to an [out] or [in,out] parameter of a method or function.

3. When a callee returns a non-null interface pointer as the physical result of a function

4. When writing a non-null interface pointer to a data member of an object

Common situations that require calls to Release method:-

1. Prior to overwriting a non-null local variable or data member

2. Prior to leaving the scope of a non-null local variable

3. When callee overwrites an [in,out] parameter of a method or function whose initial value is non-null. [out]

parameters are considered to be null on input and must never be released by the callee

4. Prior to overwriting a non-null data member of an object

5. Prior to leaving the destructor of an object that has a non-null interface pointer as a data member

Page 9: Overview of Com-Dcom

HRESULT

Virtually all COM methods physically return an error number of type HRESULT. HRESULTs are 32-bit integers

that provide information to the runtime environment about what type of error may have occurred e.g. network

errors, server failures.

For COM-compatible implementation languages e.g. VB, Java HRESULTs are intercepted by a supporting

runtime or virtual machine and mapped to programmatic exceptions.

HRESULTs are partitioned into three bit-fields: the severity bit, the facility code and the information code.The

header SDK headers contain the definitions of all standard HRESULTs. HRESULTs have symbolic names that

correspond to the three components of an HRESULT using the format <facility>_<severity>_<information>

Data types of COM

> All Characters in COM are represented using the OLECHAR data type.

> Under Windows (32 bit )platform it is similar to wchar_t

> Win32 use wchar_t to represent 16 bit unicode characters

> BSTR is a string data type which is length prefixed (OLECHAR)

> VARIANT

Language IDL Microsoft

C++

VB Microsoft Java

Small Char Unsupported Char

Short Short Integer Short

Long Long Long Int

Float Float Single Float

Double double Double Double

Enum Enum Enum Int

Base

Types

Interface Pointer Interface

Pointer

Interface

Ref.

Interface Ref.

VARIANT VARIANT Variant Ms.com.Variant

BSTR BSTR String Lava.lang.String Extended

Types VARIANT_BOOL Short Boolean Boolean

BSTR

The BSTR string type must be used in all interfaces that will be used from VB or Java. BSTRs are length-prefixed,

null-terminated strings of OLECHARs. The length prefix indicates the number of bytes the string consumes and is

stored as a four-byte integer that precedes the first character of the string.

All BSTRs are allocated from a COM-managed memory

allocator.

VARIANT

COM predefines one common discrimination union for use with Viusal Basic. This union is called a VARIANT. It

can hold instances or references to a subset of the base types supported by IDL. Each supported type has a

corresponding discriminator value.COM provides several API functions for managing VARIANTs.

Severity

code

Reserved Facility

Code

Information

code

31 30-29 28-16 15-0

BSTR

4 0 0 0 ‘H’ 0 ‘i’ 0 ‘i’ 0

� Length Prefix � �Character Data � �Terminal Null �

“Hi” as BSTR

Page 10: Overview of Com-Dcom

CHAPTER 5

Classes and Servers

A COM server is a binary file that contains the method code for one or more COM classes. A server can be

packaged as either a dynamic link library (.dll) or a normal executable (.exe). The SCM is responsible for loading

either type of server automatically.

In-process activation, a DLL-based version of the server must be available to be loaded into the client’s address

space. Out-of-process or off-host activation, an executable will be used to start the server process on the designated

host machine. Without concern for which type of package is used or where the file is installed, COM keeps a

configuration database. The Primary location of this configuration database is the NT Directory. The NT directory

can contain information about COM classes as well. Info is stored in a part of the directory known as the COM

Class Store. COM uses the Class Store to resolve CLSIDs onto implementation files.

When an activation request for a CLSID is made on a given machine, a local cache is first consulted. If no

configuration information is available in the local cache, COM sends a request to the Class Store to ask the

implementation be made available from the local Machine.

The local cache referred to in the discussion of the Class Store is formally called the Registry. The Registry is a

per-machine file-based hierarchical database that COM uses to map CLSIDs onto either filenames or remote host

names. Prior to Windows NT 5.0, the Registry was the sole location for COM configuration information. The NT

4.0 implementation of COM stores most of its configuration information under the key

HKEY_LOCAL_MACHINE\Software\Classes

In Windows NT 5.0, COM first consults HKEY_CURRENT_USER\Software\Classes COM keeps machine-wide

information related to CLSIDs under the registry key HKCR\CLSID and in Windows NT 5.0 or greater at

HKCU\Software\Classes\CLSID

Optimization One of the advantages of having a standard interface for instantiation is that COM can provide a more efficient

technique for instantiation

As seen in the above example to perform one

operation three sub operations are required i.e.,

CoGetClassObject, CreateInstance and Release

operations are called to instantiate a object

If the server is in-process server then this is not

a big issue, but if it is a out-process remote

server then each of these operations will require

a round trip between the client and the server

process and therefore is an expensive operation

COM provides an API function

CoCreateInstanceEx that subsumes the

functionality o CoGetClassObject and

IClassFactory::CreateInstance to allow a single

round trip creation of new objects.

HRESULT CoCreateInstanceEx(

[in] REFCLSID rclsid, //what kind of object

[in] IUnknown *pUnkOuter //for aggregation

[in] DWORD dwClsCtx, //locality?

[in] COSERVERINFO *pcsi, //host/security info

[in] ULONG cmqi, //how many interfaces

[out] MULTI_QI *prgmq ); //where to put itfs

HRESULT CreateChimp( Iape *rpApe ) {

extern const CLSID CLSID_Chimp ;

rpApe = 0 ;

IClassFactory *pcf = 0 ;

HRESULT hr = CoGetClassObject(

CLSID_Chimp,CLSCTX_ALL,0,IID_IClassFactory,

(void **) &pcf );

if(SUCCEEDED(hr)) {

hr = pcf->CreateInstance(0, IID_IApe,(void

**)&rpApe ) ;

pcf ->Release() ;

} return hr ;

}

Page 11: Overview of Com-Dcom

If only one interface is needed and no COSERVERINFO will be passed, COM provides a somewhat more

convenient version of CoCreateInstanceEx called as CoCreateInstance

If only one interface is needed and no COSERVERINFO will be passed, COM provides a somewhat more

convenient version of CoCreateInstanceEx called as CoCreateInstance

HRESULT CoCreateInstance( [in] REFCLSID rclsid, //what kind of object [in] IUnknown

*pUnkOuter //for aggregation

[in] DWORD dwClsCtx, //locality? [in] REFIID riid, //what kind of interface [out] void **ppv );

//where to put itf

Server Lifetime We have discussed how COM automatically loads a DLL to bring object implementations into the address space

of client programs.What has not been discussed is how and when these DLLs are unloaded.Clients that wish to

free idle DLLs call the COM API function CoFreeUnusedLibraries (void ) ;This routine is called by clients at idle

time to garbage-collect their address space.When CoFreeUnusedLibraries is called COM queries each DLL that

has been loaded to discover unneeded DLLs.It does this by calling each DLL’s DllCanUnloadNow function,

which must be explicitly exported from the DLL.If the DLL wishes to be freed it return S_OK else S_FALSE.

DLL will not be unloaded at least as long as there are interface pointers to its objects. In order to achieve this DLL

keeps a count of all extant object references.

Classes and IDL

COM Treats interfaces and classes as distinct entities.COM classes also should be defined in IDL to provide a

language neutral description of the concrete data type a server may export. The IDL definition of the COM class

contains the list of interfaces that instances of the class export. e.g.,

[uuid(753A8A7D-A7FF-11d0-8C30-0080C73925BA)]

coclass Gorilla {interface IApe ;interface IWarrior ; }

IDL coclass definition always appear in the context of library definition.In IDL, library definitions are used

to group a collection of data types e.g., interfaces, coclasses etc into a logical unit All data types that appear in the

context of an IDL library definition will be tokenized into the resultant type library.Type libraries are used in lieu

of IDL files by environments such as Visual Basic and Java An IDL file can have at most one library statement,

and all data types defined or used inside the library definition will appear in the generated type library.

Optimizations

REFCLSID rclsid

IUnknown *pUnkOuter

DWORD dwClsCtx

COSERVERINFO *pc

ULONG cmqi

MULTI_QI *prgmqi

IUnknown *pUnkOuter

REFIID riid

void **ppv

prgmqi[0].pIID

prgmqi[0].pItf

prgmqi[0].hr

prgmqi[1].pIID

prgmqi[1].pItf

prgmqi[1].hr

REFCLSID rclsid

DWORD dwClsCtx

COSERVERINFO *pc

REFIID riid

void **ppv

REFIID riid

void **ppv

CoGetClassObject

CreateInstance

QueryInterface

CoCreateInstanceEx

Page 12: Overview of Com-Dcom

Query interface types and properties

The first rule of IUnknown that bears investigation is the Symmetric/Transitive/Reflexive requirement of

QueryInterface. The Requirement defines the relationship between al of an object’s interface pointers and begins

to define the notion of object identity in COM.

QueryInterface is Symmetric

if QI request for interface B is satisfied through an interface pointer

A, then a QI request for interface A through the resultant pointer of

type B on the same object must never fail

Which means that if QI(A)->B is true, then QI(QI(A)->B)->A

must be true as well

QueryInterface is Transitive

QueryInterface is Reflexive

QI request through an interface pointer must always

succeed if the requested type matches the type of pointer

used to make the request.

It means QI(A)->A must always be true

Interfaces and QueryInterface

Dynamic Composition

When multiple inheritance or composition is used to implement an interface in a C++ class, each object of that

class will carry a overhead of 4 bytes for vptr per supported interface.If the number of supported interfaces in a

class is small then the above overhead is negligible. But if the number of supported interfaces in a class is large

then the overhead may grow to an extent where it dwarfs the non-COM-related size of the object.

IF QI request for interface B is satisfied through an

interface pointer A and a second QI for interface C is

satisfied through the pointer of type B, then a QI request

for interface C through the original pointer of type A

must succeed.

Which means that if QI(QI(A->B))->C is true, then

QI(A)->C must be true as well.

IBoat

IUnknown

ICar

IPlane

Object

IUnknown

ICar Object

IUnknown

ICar

IPlane

Object

IUnknown

ICar

IPlane

Object

Page 13: Overview of Com-Dcom

The COM specification explicitly allows implementations to return different pointer values from

QueryInterface for any type of interface other than IUnknown, This means that for infrequently used interfaces, an

object can dynamically allocate the memory for the vptr on demand without having to worry about returning the

same dynamically allocated block of memory each time a particular interface is requested.These transient

interfaces are termed as tearoffs.

Activation

• In order to use the COM Objects there should be a mechanism to find the objects and bring them into

memory

• The objects reside as a DLL or an EXEcutable file.

The act of bringing an Object to life is called as object activation.

COM has three activation models to bring objects into memory

1. Bind to the Class Object of a given class

2. Create a new instance of a class based on CLSID

3. Bring a Persistent Object to Life based on CLSID

• Each Host Machine that hosts COM has its own SCM.

• All activation requests are serviced by COM SCM (COM Service Control Manager).

• SCM on a machine X forwards remote activation request to the SCM on the remote machine, where the

activation request will be treated as a local activation request

• The SCM is used only to activate the object and bind the initial reference pointer

• Once the object is activated, the SCM is not involved with client-object method invocation

• Under Windows NT SCM is implemented as RPCSS Service

• Whereas the COM library is implemented in OLE32.DLL

• The services of SCM are exposed to Clients via COM Library in the form of API functions

COM objects can be activated as

1. In Process activation

2. Local activation

3. Remote activation

Local & Remote activation is also called as Out Process Activation

In Process Activation

Object methods are implemented as DLL Diagram

• DLL is Loaded into clients address space

• No process switch is required and therefore method invocation is extremely efficient

• Client thread can execute the method code directly

• if client and object have compatible threading requirements than no thread switch is required

• No intermediate runtime is involved after the object is activated

• The only cost involved is making a virtual function call

Advantage - Well suited for performance sensitive applications

Local and Remote Activation : Diagram

• Code that implements the object methods executes in a distinct server process server process and all data

members reside in the server process address space

• To allow client to communicate with the out of process object, COM returns a proxy to the client at

activation time

• The proxy runs on the client’s thread and translates method invocation into RPC requests to the servers

execution context, where these RPC requests are then translated back into method invocations on the actual

object • This makes method invocation less efficient as a thread switch & a process switch is required for each access to the object

Advantages - Fault Isolation, Distribution & Increased Security.

Page 14: Overview of Com-Dcom

CHAPTER 6:- Apartments

Threads

Win32 Threads –

1. User-interface threads – They are associated with one or more windows. These threads have

message loops that keep windows alive and responsive to user’s input

2. Worker threads – are used for background processing and aren’t associated with a window. Worker

threads usually don’t have message loops.A single process can have multiple user-interface threads and

multiple worker threads.

COM Threads –

1.Apartment thread - user-interface thread is called as apartment thread in COM.

2. Free Thread - The Worker thread called as free thread in COM

Apartment • Apartments define a logical grouping of objects that share a common set of concurrency and reentrancy

constraints.

• An apartment is neither a process nor a thread.

• Apartments support the properties of both process and thread.

• Every COM object belongs to exactly one apartment.

• One apartment can be shared by multiple objects.

• An apartment is contained in exactly one process.

• Every process that uses COM has at least one group of object that share concurrency and reentrancy

requirements.

• Two objects that resides the same process may belong to two different apartments and therefore have

different concurrency and reentrancy requirements.

• A thread executes in exactly one apartment at a time.

• Before a thread can use COM it should enter an apartment.

• When a thread enters an apartment COM stores the information of the apartment in TLS ( thread local

storage) and this information remains associated with the thread until the thread exits the apartment.

• COM mandates that objects may be accessed only by threads executing in the apartment of the object.

• If a thread is executing in the same process as an object, it may be prohibited from accessing the object

even though the memory the object occupies is fully visible and accessible.

Windows NT 4.0 release of COM defines two types of apartments:

>> Multithreaded apartment

>>Single threaded apartment

• Each process has at most one MTA; however process can contain multiple STAs

• Multiple threads can execute in an MTA concurrently, whereas only one thread can execute in a STA.

• More precisely only one thread can ever execute in a STA.

• This means that objects residing in a STA can never be accessed concurrently.

• The disadvantage of STA is that is allows only one method called to execute concurrently no matter

how many object belongs to apartment.

• In an MTA threads can be dynamically allocated based on current demand with no correlation with

number of object in the apartment.

Page 15: Overview of Com-Dcom

Object Interfaces and Apartment

� When a interface pointer is return from a COM API called or from a method invocation,

the thread that invoke the API call or method determines which apartments the resultant

interface pointer belongs to.

� If the called returns a pointer to the actual object then the object itself resides in the

calling threads apartment.

� In case the object does not reside in the callers apartment then the client receives a

pointer to a proxy. > In COM, a proxy is an object that is semantically identical to

an object in another apartment.

� A proxy exposes the same set of interfaces as the object it represents, however the

proxy’s implementation of each of the interfaces methods simply forward call to the

object that is in another apartment.

� Object implementer decides the types of apartments in which their objects can execute.

� Therefore for in process servers to control their apartment type, COM allows each

CLSID to specify its threading model.

The different type of threading models are – � >> Both - The class can execute in either in an MTA or an STA.

� >> Free - The class can execute in only in an MTA.

� >> Apartment - The class can execute in only in an STA.

Cross-Apartment Access � Passing control form one apartment to another is referred to as method remoting and

this is how all cross thread, cross process and cross host communication occurs in

COM.

� COM allows interface pointers to be passed across apartment boundaries using a

technique called marshaling.

� Marshaling an interface pointer simply transform the interface pointer into a

transmissible byte stream whose contents uniquely identify the object and its owning

apartment.These marshaled object references simply contents connection

establishment information.

� When an in process activation process is made for a class incompatible threading

model,COM implicitly interface from the objects apartment and unmarshal the proxy

the clients apartment.

� When an out of process or off host activation request is made COM also marshals the

resultant pointer from the apartment of the object and unmarshals a proxy for the

clients. � To marshal interface pointers explicitly COM provides an API function CoMarshalInterface.

� There are three type of marshaling � >> Standard Marshaling

� >> Custom Marshaling

� >> Free Threaded Marshaling

Server Lifetime

� A server process control its lifetime and can elect to shutdown at any time it chooses.

� Even though it is legal for a server process to remain running indefinitely most server processes

elect to shutdown when there are no outstanding references to their objects or class objects.

� Most in process server use a similar policy in their implementation of DllCanunloadNow.

� This routine is called during garbage collection by the client.

� There are several differences how EXE based servers handle server shutdown.

� It is the job of the server process to initiate its shutdown.

� There is no garbage collector in out process server that will ask the server whether it would like

to shutdown. � The most direct technique is to use PostThreadMessage to post a WM_QUIT message to main thread.

Page 16: Overview of Com-Dcom

CHAPTER 10:--Java Native Interface

Background

Writing native methods for Java programs is a multi-step process.

1. Begin by writing the Java program. Create a Java class that declares the native method; this class contains

the declaration or signature for the native method. It also includes a main method which calls the native

method.

2. Compile the Java class that declares the native method and the main method.

3. Generate a header file for the native method using javah with the native interface flag -jni. Once you've

generated the header file you have the formal signature for your native method.

4. Write the implementation of the native method in the programming language of your choice, such as C or

C++.

5. Compile the header and implementation files into a shared library file.

6. Run the Java program.

The following figure illustrates these steps for the Hello World program:

Step 1: Write the Java Code

Create a Java class named HelloWorld that declares a native method. This class also includes a main method that

creates a HelloWorld object and calls the native method.

Step 2: Compile the Java Code

Use javac to compile the Java code that you wrote in Step 1.

Step 3: Create the .h File

Use javah to create a JNI-style header file (a .h file) from the HelloWorld class. The header file provides a function

signature for the implementation of the native method displayHelloWorld.

Step 4: Write the Native Method Implementation

Write the implementation for the native method in a native language (such as ANSI C) source file. The

implementation will be a regular function that's integrated with your Java class.

Step 5: Create a Shared Library

Use the C compiler to compile the .h file and the .c file that you created in Steps 3 and 4 into a shared library. In

Windows 95/NT terminology, a shared library is called a dynamically loadable library (DLL).

Step 6: Run the Program

And finally, use java, the Java interpreter, to run the program

Page 17: Overview of Com-Dcom

Getting Familiar with CORBA

Background: History of Distributed Systems

If you’re interested enough in CORBA to be reading this book, you probably know a thing or two already about distributed

systems. Distributed systems have been around, in one form or another, for some time, although they haven’t always been

called that and they certainly haven’t always had the flexibility that they do now. To discover where CORBA fits in, let’s

briefly review the history of distributed systems, starting with the venerable mainframe.

The Beginning: Monolithic Systems and Mainframes

In the beginning (or close to it), there was the mainframe. Along with it came hierarchical database systems and dumb

terminals, also known as green screens. Mainframes usually cost a great deal to maintain but were capable of serving large

numbers of users and had the advantage (or disadvantage, depending on one’s point of view) of being centrally managed.

Software systems written for mainframes were often monolithic—that is, the user interface, business logic, and data access

functionality were all contained in one large application. Because the dumb terminals used to access mainframes didn’t do

any of their own processing, the entire application ran in the mainframe itself, thus making the monolithic architecture

reasonable. A typical monolithic application architecture is illustrated in Figure 1.1.

Figure 1.1.Typical monolithic application architecture.

The Revolution: Client/Server Architecture

The advent of the PC made possible a dramatic paradigm shift from the monolithic architecture of mainframe-based

applications. Whereas these applications required the mainframe itself to perform all the processing, applications based on

the client/server architecture allowed some of that processing to be offloaded to PCs on the users’ desktops.

Along with the client/server revolution came the proliferation of UNIX-based servers. Many applications simply did not

require the massive power of mainframes, and because the client/server architecture was capable of moving much of the

processing load to the desktop PC, these smaller UNIX-based server machines were often more cost-effective than

mainframes. Also, these machines were much more affordable to small businesses than mainframes, which were often simply

out of reach for companies with relatively small bank account balances. Still another benefit was the empowerment of

individual departments within an organization to deploy and manage their own servers. The result was that these departments

could be more responsive to their specific needs when developing their own applications, rather than having to jump through

proverbial hoops to get the department controlling the mainframes to develop applications, as was often the case. Finally,

whereas terminals were typically restricted to running only applications on the mainframe, a PC was capable of performing

many other tasks independently of the mainframe, further enhancing its usefulness as a desktop machine.

Client/server applications typically distributed the components of the application so that the database would reside on

the server (whether a UNIX box or mainframe), the user interface would reside on the client, and the business logic would

Page 18: Overview of Com-Dcom

reside in either, or both, components. When changes were made to parts of the client component, new copies of the client

component (usually executables or a set of executables) had to be distributed to each user.

With the advent of multitier client/server architecture (discussed in the next section), the “original” client/server architecture

is now referred to as “two-tier” client/server. The two-tier client/server architecture is illustrated in Figure 1.2.

Figure 1.2. Two-tier client/server architecture.

The Evolution: Multitier Client/Server

The client/server architecture was in many ways a revolution from the old way of doing things. Despite solving the problems

with mainframe-based applications, however, client/server was not without faults of its own. For example, because database

access functionality (such as embedded database queries) and business logic were often contained in the client component,

any changes to the business logic, database access, or even the database itself, often required the deployment of a new client

component to all the users of the application. Usually, such changes would break earlier versions of the client component,

resulting in a fragile application.

The problems with the traditional client/server (now often called “two-tier” client/server) were addressed by the multitier

client/server architecture. Conceptually, an application can have any number of tiers, but the most popular multitier

architecture is three-tier, which partitions the system into three logical tiers: the user interface layer, the business rules layer,

and the database access layer. A three-tier client/server architecture is illustrated in Figure 1.3.

Figure 1.3. Three-tier client/server architecture.

Page 19: Overview of Com-Dcom

Multitier client/server architecture enhances the two-tier client/server architecture in two ways: First, and

perhaps most importantly, it makes the application less fragile by further insulating the client from

changes in the rest of the application. Also, because the executable components are more fine-grained, it

allows more flexibility in the deployment of an application.

Multitier client/server reduces application fragility by providing more insulation and separation between layers. The user

interface layer communicates only with the business rules layer, never directly with the database access layer. The business

rules layer, in turn, communicates with the user interface layer on one side and the database access layer on the other. Thus,

changes in the database access layer will not affect the user interface layer because they are insulated from each other. This

architecture enables changes to be made in the application with less likelihood of affecting the client component (which,

remember, has to be redistributed when there are any changes to it).

Because the multitier client/server architecture partitions the application into more components than traditional two-tier

client/server, it also allows more flexibility in deployment of the application. For example, Figure 1.3 depicts a system in

which the business rules layer and database access layer, although they are separate logical entities, are on the same server

machine. It is also possible to put each server component on a separate machine. Indeed, multiple business logic components

(and multiple database access components, if multiple databases are being used) can be created for a single application,

distributing the processing load and thus resulting in a more robust, scalable application.

Note: It is interesting to note that the multitier client/server architecture might actually have had its roots

in mainframe applications. COBOL applications on IBM mainframes could define the user interface by

using a tool called Message Format Service (MFS). MFS abstracted the terminal type (terminals could,

for instance, have varying numbers of rows and columns) from the rest of the application. Similarly,

applications could specify the database interfaces as well. Although the application would still run in one

monolithic chunk, the available tools enabled the design of applications using a logical three-tier

architecture.

The Next Generation: Distributed Systems

The next logical step in the evolution of application architectures is the distributed system model. This architecture takes the

concept of multitier client/server to its natural conclusion. Rather than differentiate between business logic and data access,

the distributed system model simply exposes all functionality of the application as objects, each of which can use any of the

services provided by other objects in the system, or even objects in other systems. The architecture can also blur the

distinction between “client” and “server” because the client components can also create objects that behave in server-like

roles. The distributed system architecture provides the ultimate in flexibility.

The distributed system architecture achieves its flexibility by encouraging (or enforcing) the definition of specific component

interfaces. The interface of a component specifies to other components what services are offered by that component and how

they are used. As long as the interface of a component remains constant, that component’s implementation can change

dramatically without affecting other components. For example, a component that provides customer information for a

company can store that information in a relational database. Later, the application designers might decide that an object-

oriented database would be more appropriate. The designers can make any number of changes to the component’s

implementation—even sweeping changes such as using a different type of database—provided that they leave the

component’s interface intact. Again, as long as the interface of that component remains the same, the underlying

implementation is free to change.

New Term: An interface defines the protocol of communication between two separate components of a system. (These

components can be separate processes, separate objects, a user and an application—any separate entities that need to

communicate with each other.) The interface describes what services are provided by a component and the protocol for using

those services. In the case of an object, the interface can be thought of as the set of methods defined by that object, including

the input and output parameters. An interface can be thought of as a contract; in a sense, the component providing an

interface promises to honor requests for services as outlined in the interface.

Distributed systems are really multitier client/server systems in which the number of distinct clients and servers is potentially

large. One important difference is that distributed systems generally provide additional services, such as directory services,

Page 20: Overview of Com-Dcom

which allow various components of the application to be located by others. Other services might include a transaction

monitor service, which allows components to engage in transactions with each other.

New Term: Directory services refers to a set of services that enable objects—which can be servers, businesses, or even

people—to be located by other objects. Not only can the objects being looked up differ in type, but the directory information

itself can vary as well. For example, a telephone book would be used to locate telephone numbers and postal addresses; an

email directory would be used to locate email addresses. Directory services encompass all such information, usually

grouping together related information (for example, there are separate volumes of the yellow pages for different cities;

contents of each volume are further divided into types of businesses).

New Term: A transaction monitor service oversees transactions on behalf of other objects. A transaction, in turn, is an

operation or set of operations that must be performed atomically; that is, either all objects involved in the transaction must

commit the transaction (update their own records) or all objects involved must abort the transaction (return to their original

state before the transaction was initiated). The result is that whether a transaction commits or aborts, all involved objects will

be in a consistent state. It is the job of a transaction monitor to provide transaction-related services to other objects.

To sum up, business applications have evolved over a period of time from a relatively rigid monolithic architecture to an

extremely flexible, distributed one. Along the way, application architectures have offered increasing robustness because of

the definitions of interfaces between components and the scalability of applications (furnished in part by the capability to

replicate server components on different machines). Additionally, services have been introduced that enable the end user of

an application to wade through the myriad of available services. Those who have been designing and developing business

applications since the days of mainframes have certainly had an interesting ride.

Why CORBA?

So far, in this evolution of business applications from the monolithic mainframe architecture to the highly decentralized

distributed architecture, no mention has been made of CORBA. Therefore, you might be asking yourself at this point where

CORBA fits in to all this. The answer, as you will see, is emphasized throughout the rest of this book. Recall that distributed

systems rely on the definition of interfaces between components and on the existence of various services (such as directory

registration and lookup) available to an application. CORBA provides a standard mechanism for defining the interfaces

between components as well as some tools to facilitate the implementation of those interfaces using the developer’s choice of

languages. In addition, the Object Management Group (the organization responsible for standardizing and promoting

CORBA) specifies a wealth of standard services, such as directory and naming services, persistent object services, and

transaction services. Each of these services is defined in a CORBA-compliant manner, so they are available to all CORBA

applications. Finally, CORBA provides all the “plumbing” that allows various components of an application—or of separate

applications—to communicate with each other.

New Term: The capabilities of CORBA don’t stop there. Two features that CORBA provides—features that are a rarity in

the computer software realm—are platform independence and language independence. Platform independence means that

CORBA objects can be used on any platform for which there is a CORBA ORB implementation (this includes virtually all

modern operating systems as well as some not-so-modern ones). Language independence means that CORBA objects and

clients can be implemented in just about any programming language. Furthermore, CORBA objects need not know which

language was used to implement other CORBA objects that they talk to. Soon you will see the components of the CORBA

architecture that make platform independence and language independence possible.

Exploring CORBA Alternatives

When designing and implementing distributed applications, CORBA certainly isn’t a developer’s only choice. Other

mechanisms exist by which such applications can be built. Depending on the nature of the application—ranging from its

complexity to the platform(s) it runs on to the language(s) used to implement it—there are a number of alternatives for a

developer to consider. In this section you’ll briefly explore some of the alternatives and see how they compare to CORBA.

Socket Programming

New Term: In most modern systems, communication between machines, and sometimes between processes in the same

machine, is done through the use of sockets. Simply put, a socket is a channel through which applications can connect with

each other and communicate. The most straightforward way to communicate between application components, then, is to use

sockets directly (this is known as socket programming), meaning that the developer writes data to and/or reads data from a

socket.

Page 21: Overview of Com-Dcom

The Application Programming Interface (API) for socket programming is rather low-level. As a result, the overhead

associated with an application that communicates in this fashion is very low. However, because the API is low-level, socket

programming is not well-suited to handling complex data types, especially when application components reside on different

types of machines or are implemented in different programming languages. Whereas direct socket programming can result in

very efficient applications, the approach is usually unsuitable for developing complex applications.

Remote Procedure Call (RPC)

New Term: One rung on the ladder above socket programming is Remote Procedure Call (RPC). RPC provides a function-

oriented interface to socket-level communications. Using RPC, rather than directly manipulating the data that flows to and

from a socket, the developer defines a function—much like those in a functional language such as C—and generates code

that makes that function look like a normal function to the caller. Under the hood, the function actually uses sockets to

communicate with a remote server, which executes the function and returns the result, again using sockets.

Because RPC provides a function-oriented interface, it is often much easier to use than raw socket programming. RPC is also

powerful enough to be the basis for many client/server applications. Although there are varying incompatible

implementations of RPC protocol, a standard RPC protocol exists that is readily available for most platforms.

OSF Distributed Computing Environment (DCE)

The Distributed Computing Environment (DCE), a set of standards pioneered by the Open Software Foundation (OSF),

includes a standard for RPC. Although the DCE standard has been around for some time, and was probably a good idea, it

has never gained wide acceptance and exists today as little more than an historical curiosity.

Microsoft Distributed Component Object Model (DCOM)

The Distributed Component Object Model (DCOM), Microsoft’s entry into the distributed computing foray, offers

capabilities similar to CORBA. DCOM is a relatively robust object model that enjoys particularly good support on Microsoft

operating systems because it is integrated with Windows 95 and Windows NT. However, being a Microsoft technology, the

availability of DCOM is sparse outside the realm of Windows operating systems. Microsoft is working to correct this

disparity, however, in partnering with Software AG to provide DCOM on platforms other than Windows. At the time this

was written, DCOM was available for the Sun Solaris operating system, with support promised for Digital UNIX, IBM

MVS, and other operating systems by the end of the year. By the time you read this, some or all of these ports will be

available. (More information on the ports of DCOM to other platforms is available at

http://www.softwareag.com/corporat/dcom/default.htm.)

Microsoft has, on numerous occasions, made it clear that DCOM is best supported on Windows operating systems, so

developers with cross-platform interests in mind would be well-advised to evaluate the capabilities of DCOM on their

platform(s) of interest before committing to the use of this technology. However, for the development of Windows-only

applications, it is difficult to imagine a distributed computing framework that better integrates with the Windows operating

systems.

One interesting development concerning CORBA and DCOM is the availability of CORBA-DCOM bridges, which enable

CORBA objects to communicate with DCOM objects and vice versa. Because of the “impedance mismatch” between

CORBA and DCOM objects (meaning that there are inherent incompatibilities between the two that are difficult to

reconcile), the CORBA-DCOM bridge is not a perfect solution, but it can prove useful in situations where both DCOM and

CORBA objects might be used.

Java Remote Method Invocation (RMI)

The tour of exploring CORBA alternatives stops with Java Remote Method Invocation (RMI), a very CORBA-like

architecture with a few twists. One advantage of RMI is that it supports the passing of objects by value, a feature not

(currently) supported by CORBA. A disadvantage, however, is that RMI is a Java-only solution; that is, RMI clients and

servers must be written in Java. For all-Java applications—particularly those that benefit from the capability to pass objects

by value—RMI might be a good choice, but if there is a chance that the application will later need to interoperate with

applications written in other languages, CORBA is a better choice. Fortunately, full CORBA implementations already exist

for Java, ensuring that Java applications interoperate with the rest of the CORBA world.

CORBA History

Now that you know a little bit of CORBA’s background and its reason for existence, it seems appropriate to briefly explore

some of the history of CORBA to understand how it came into being.

Page 22: Overview of Com-Dcom

Introducing the Object Management Group (OMG)

The Object Management Group (OMG), established in 1989 with eight original members, is a 760-plus-member organization

whose charter is to “provide a common architectural framework for object-oriented applications based on widely available

interface specifications.” That’s a rather tall order, but the OMG achieves its goals with the establishment of the Object

Management Architecture (OMA), of which CORBA is a part. This set of standards delivers the common architectural

framework on which applications are built. Very briefly, the OMA consists of the Object Request Broker (ORB) function,

object services (known as CORBA services), common facilities (known as CORBA facilities), domain interfaces, and

application objects. CORBA’s role in the OMA is to implement the Object Request Broker function. For the majority of this

book, you will be concentrating on CORBA itself, occasionally dabbling into CORBA services and CORBA facilities.

CORBA 1.0

Following the OMG’s formation in 1989, CORBA 1.0 was introduced and adopted in December 1990. It was followed in

early 1991 by CORBA 1.1, which defined the Interface Definition Language (IDL) as well as the API for applications to

communicate with an Object Request Broker (ORB). (These are concepts that you’ll explore in much greater detail on Day

2.) A 1.2 revision appeared shortly before CORBA 2.0, which with its added features quickly eclipsed the 1.x revisions. The

CORBA 1.x versions made an important first step toward object interoperability, allowing objects on different machines, on

different architectures, and written in different languages to communicate with each other.

CORBA 2.0 and IIOP

CORBA 1.x was an important first step in providing distributed object interoperability, but it wasn’t a complete

specification. Although it provided standards for IDL and for accessing an ORB through an application, its chief limitation

was that it did not specify a standard protocol through which ORBs could communicate with each other. As a result, a

CORBA ORB from one vendor could not communicate with an ORB from another vendor, a restriction that severely limited

interoperability among distributed objects.

Enter CORBA 2.0. Adopted in December 1994, CORBA 2.0’s primary accomplishment was to define a standard protocol by

which ORBs from various CORBA vendors could communicate. This protocol, known as the Internet Inter-ORB Protocol

(IIOP, pronounced “eye-op”), is required to be implemented by all vendors who want to call their products CORBA 2.0

compliant. Essentially, IIOP ensures true interoperability among products from numerous vendors, thus enabling CORBA

applications to be more vendor-independent. IIOP, being the Internet Inter-ORB Protocol, applies only to networks based on

TCP/IP, which includes the Internet and most intranets.

The CORBA standard continues to evolve beyond 2.0; in September 1997, the 2.1 version became available, followed

shortly by 2.2; 2.3 is expected in early 1998. (The OMG certainly is keeping itself busy!) These revisions introduce

evolutionary (not revolutionary) advancements in the CORBA architecture.

CORBA Architecture Overview

Finally, having learned the history and reasons for the existence of CORBA, you’re ready to examine the CORBA

architecture. You’ll cover the architecture in greater detail on Day 2, but Day 1 provides you with a very general overview—

an executive summary, if you will—of what composes the CORBA architecture.

First of all, CORBA is an object-oriented architecture. CORBA objects exhibit many features and traits of other object-

oriented systems, including interface inheritance and polymorphism. What makes CORBA even more interesting is that it

provides this capability even when used with nonobject-oriented languages such as C and COBOL, although CORBA maps

particularly well to object-oriented languages like C++ and Java.

New Term: Interface inheritance is a concept that should be familiar to Objective C and Java developers. In the contrasting

implementation inheritance, an implementation unit (usually a class) can be derived from another. By comparison, interface

inheritance allows an interface to be derived from another. Even though interfaces can be related through inheritance, the

implementations for those interfaces need not be.

The Object Request Broker (ORB)

Fundamental to the Common Object Request Broker Architecture is the Object Request Broker, or ORB. (That the ORB

acronym appears within the CORBA acronym was just too much to be coincidental.) An ORB is a software component

whose purpose is to facilitate communication between objects. It does so by providing a number of capabilities, one of which

is to locate a remote object, given an object reference. Another service provided by the ORB is the marshaling of parameters

and return values to and from remote method invocations. (Don’t worry if this explanation doesn’t make sense; the ORB is

Page 23: Overview of Com-Dcom

explained in much greater detail on Day 2.) Recall that the Object Management Architecture (OMA) includes a provision for

ORB functionality; CORBA is the standard that implements this ORB capability. You will soon see that the use of ORBs

provides platform independence to distributed CORBA objects.

Interface Definition Language (IDL)

Another fundamental piece of the CORBA architecture is the use of the Interface Definition Language (IDL). IDL, which

specifies interfaces between CORBA objects, is instrumental in ensuring CORBA’s language independence. Because

interfaces described in IDL can be mapped to any programming language, CORBA applications and components are thus

independent of the language(s) used to implement them. In other words, a client written in C++ can communicate with a

server written in Java, which in turn can communicate with another server written in COBOL, and so forth.

One important thing to remember about IDL is that it is not an implementation language. That is, you can’t write applications

in IDL. The sole purpose of IDL is to define interfaces; providing implementations for these interfaces is performed using

some other language. When you study IDL more closely on Day 3, you’ll learn more about this and other assorted facts about

IDL.

The CORBA Communications Model

New Term: CORBA uses the notion of object references (which in CORBA/IIOP lingo are referred to as Interoperable

Object References, or IORs) to facilitate the communication between objects. When a component of an application wants to

access a CORBA object, it first obtains an IOR for that object. Using the IOR, the component (called a client of that object)

can then invoke methods on the object (called the server in this instance).

In CORBA, a client is simply any application that uses the services of a CORBA object; that is, an application that invokes a

method or methods on other objects. Likewise, a server is an application that creates CORBA objects and makes the services

provided by those objects available to other applications. A much more detailed discussion of CORBA clients and servers is

presented on Day 2.

As mentioned previously, CORBA ORBs usually communicate using the Internet Inter-ORB Protocol (IIOP). Other

protocols for inter-ORB communication exist, but IIOP is fast becoming the most popular, first of all because it is the

standard, and second because of the popularity of TCP/IP (the networking protocols used by the Internet), a layer that IIOP

sits on top of. CORBA is independent of networking protocols, however, and could (at least theoretically) run over any type

of network protocols. For example, there are also implementations of CORBA that run over DCE rather than over TCP/IP,

and there is also interest in running CORBA over ATM and SS7.

The CORBA Object Model

In CORBA, all communication between objects is done through object references (again, these are known as Interoperable

Object References, or IORs, if you’re using IIOP). Furthermore, visibility to objects is provided only through passing

references to those objects; objects cannot be passed by value (at least in the current specification of CORBA). In other

words, remote objects in CORBA remain remote; there is currently no way for an object to move or copy itself to another

location. (You’ll explore this and other CORBA limitations and design issues on Day 10.)

Another aspect of the CORBA object model is the Basic Object Adapter (BOA), a concept that you’ll also explore on Day 2.

A BOA basically provides the common services available to all CORBA objects.

CORBA Clients and Servers

Like the client/server architectures, CORBA maintains the notions of clients and servers. In CORBA, a component can act as

both a client and as a server. Essentially, a component is considered a server if it contains CORBA objects whose services are

accessible to other objects. Likewise, a component is considered a client if it accesses services from some other CORBA

object. Of course, a component can simultaneously provide and use various services, and so a component can be considered a

client or a server, depending on the scenario in question.

Stubs and Skeletons

When implementing CORBA application components, you will encounter what are known as client stubs and server

skeletons. A client stub is a small piece of code that allows a client component to access a server component. This piece of

code is compiled along with the client portion of the application. Similarly, server skeletons are pieces of code that you “fill

in” when you implement a server. You don’t need to write the client stubs and server skeletons themselves; these pieces of

code are generated when you compile IDL interface definitions. Again, you’ll soon see all this firsthand.

Page 24: Overview of Com-Dcom

Beyond the Basics: CORBA Services and CORBA Facilities

In addition to the CORBA basics of allowing objects to communicate with each other, recall that the OMA—of which

CORBA is a part—also provides additional capabilities in the form of CORBAservices and CORBAfacilities. As you’ll find

out, CORBAservices and CORBAfacilities provide both horizontal (generally useful to all industries) and vertical (designed

for specific industries) services and facilities. You’ll look at the capabilities provided in greater detail on Day 12, after which

you’ll get the opportunity to use some of this functionality in a CORBA application.

Understanding the CORBA Architecture

The Object Request Broker (ORB)

As one might guess, a fundamental part of the Common Object Request Broker architecture is the Object Request Broker

(ORB). The concept of an ORB is this: When an application component wants to use a service provided by another

component, it first must obtain an object reference for the object providing that service. (How this object reference is

obtained is an issue in its own right—and will be discussed later—but for the purposes of studying the ORB mechanism,

assume for the time being that the object reference is already available.) After an object reference is obtained, the component

can call methods on that object, thus accessing the desired services provided by that object. (The developer of the client

component knows at compile time which methods are available from a particular server object.) The primary responsibility

of the ORB is to resolve requests for object references, enabling application components to establish connectivity with each

other. (See Figure 2.1 for an illustration of these ORB concepts.) As you will see, the ORB has other responsibilities as well.

Figure 2.1. ORB resolution of object requests.

Marshaling

After an application component has obtained a reference to an object whose services the component wants to use, that

component can invoke methods of that object. Generally, these methods take parameters as input and return other parameters

as output. Another responsibility of the ORB is to receive the input parameters from the component that is calling the method

and to marshal these parameters. What this means is that the ORB translates the parameters into a format that can be

transmitted across the network to the remote object. (This is sometimes referred to as an on-the-wire format.) The ORB also

unmarshals the returned parameters, converting them from the on-the-wire format into a format that the calling component

understands. The marshaling process can be seen in Figure 2.2.

Page 25: Overview of Com-Dcom

Figure 2.2. Marshaling parameters and return values.

New Term: Marhsaling refers to the process of translating input parameters to a format that can be

transmitted across a network.

Unmarshaling is the reverse of marshaling; this process converts data from the network to output parameters.

An On-the-wire format specifies the format in which data is transmitted across the network for the marshaling and

unmarshaling processes.

The entire marshaling process takes place without any programmer intervention whatsoever. A client application simply

invokes the desired remote method—which has the appearance of being a local method, as far as the client is concerned—

and a result is returned (or an exception is raised), again, just as would happen with a local method. The entire process of

marshaling input parameters, initiating the method invocation on the server, and unmarshaling the return parameters is

performed automatically and transparently by the ORB.

Platform Independence

A product of the marshaling/unmarshaling process is that, because parameters are converted upon transmission into a

platform-independent format (the on-the-wire format is provided as part of the CORBA specification) and converted into a

platform-specific format upon reception, the communication between components is platform-independent. This means that a

client running on, for instance, a Macintosh system can invoke methods on a server running on a UNIX system. In addition

to independence of operating system used, differences in hardware (such as processor byte ordering, or endianness) are also

rendered irrelevant because the ORB automatically makes these conversions as necessary. In essence, any differences in

platforms—be it operating system, endianness, word size, and so on—are accounted for by the ORB.

Note again that the process of marshaling and unmarshaling parameters is handled completely by the ORB, entirely

transparent to both the client and server. Because the entire process is handled by the ORB, the developer need not concern

himself with the details of the mechanism by which the parameters are marshaled and unmarshaled.

ORB Summary

Because the concept of the ORB is central to an understanding of the CORBA architecture, it is important to make sure that

you grasp the ORB concepts. To summarize the purpose of the ORB, its responsibilities are as follows:

• Given an object reference from a client, the ORB locates the corresponding object implementation (the

server) on behalf of the client. (Note that it is the responsibility of the client to obtain an object reference in

the first place, through a process you’ll learn later.)

• When the server is located, the ORB ensures that the server is ready to receive the request.

Page 26: Overview of Com-Dcom

• The ORB on the client side accepts the parameters of the method being invoked and marshals (see the next

section) the parameters to the network.

• The ORB on the server side unmarshals (again, see the next section) the parameters from the network and

delivers them to the server.

• Return parameters, if any, are marshaled/unmarshaled in the same way.

The major benefit offered by the ORB is its platform-independent treatment of data; parameters can be converted on-the-fly

between varying machine formats as they are marshaled and unmarshaled.

Interface Definition Language (IDL)

If the concept of the Object Request Broker is one cornerstone of the CORBA architecture, the Interface Definition

Language (IDL) is the other. IDL, as its name suggests, is the language used to define interfaces between application

components. Note that IDL is not a procedural language; it can define only interfaces, not implementations. C++

programmers can think of IDL definitions as analogous to header files for classes; a header file typically does not contain any

implementation of a class but rather describes that class’s interface. Java programmers might liken IDL definitions to

definitions of Java interfaces; again, only the interface is described—no implementation is provided.

New Term: The Interface Definition Language (IDL) is a standard language used to define the interfaces used by CORBA

objects. It is covered in great detail on Day 3.

The IDL specification is responsible for ensuring that data is properly exchanged between dissimilar languages. For example,

the IDL long type is a 32-bit signed integer quantity, which can map to a C++ long (depending on the platform) or to a

Java int. It is the responsibility of the IDL specification—and the IDL compilers that implement it—to define such data

types in a language-independent way.

IDL will be covered in great detail in the next chapter. After that, you will use IDL to—what else?--define interfaces for the

examples used throughout this book.

Language Independence

The IDL language is part of the standard CORBA specification and is independent of any programming language. It achieves

this language independence through the concept of a language mapping. The OMG has defined a number of standard

language mappings for many popular languages, including C, C++, COBOL, Java, and Smalltalk. Mappings for other

languages exist as well; these mappings are either nonstandard or are in the process of being standardized by the OMG.

New Term: A language mapping is a specification that maps IDL language constructs to the constructs of a particular

programming language. For example, in the C++ language mapping, the IDL interface maps to a C++ class.

Language independence is a very important feature of the CORBA architecture. Because CORBA does not dictate a

particular language to use, it gives application developers the freedom to choose the language that best suits the needs of their

applications. Taking this freedom one step further, developers can also choose multiple languages for various components of

an application. For instance, the client components of an application might be implemented in Java, which ensures that the

clients can run on virtually any type of machine. The server components of that application might be implemented in C++ for

high performance. CORBA makes possible the communication between these various components.

The CORBA Communications Model

In order to understand CORBA, you must first understand its role in a network of computing systems. Typically, a computer

network consists of systems that are physically connected (although the advent of wireless network technology might force

us to revise our understanding of what “physically connected” means). This physical layer provides the medium through

which communication can take place, whether that medium is a telephone line, a fiber-optic cable, a satellite uplink, or any

combination of networking technologies.

Somewhere above the physical layer lies the transport layer, which involves protocols responsible for moving packets of data

from one point to another. In this age of the Internet, perhaps the most common transport protocol in use is TCP/IP

(Transmission Control Protocol/Internet Protocol). Most Internet-based applications use TCP/IP to communicate with each

other, including applications based on FTP (File Transfer Protocol), Telnet (a host communication protocol), and HTTP

(Hypertext Transport Protocol, the basis for the World Wide Web).

Page 27: Overview of Com-Dcom

Inter-ORB Protocols

So how does CORBA fit into this networking model? It turns out that the CORBA specification is neutral with respect to

network protocols; the CORBA standard specifies what is known as the General Inter-ORB Protocol (GIOP), which

specifies, on a high level, a standard for communication between various CORBA ORBs and components. GIOP, as its name

suggests, is only a general protocol; the CORBA standard also specifies additional protocols that specialize GIOP to use a

particular transport protocol. For instance, GIOP-based protocols exist for TCP/IP and DCE (the Open Software

Foundation’s Distributed Computing Environment protocol). Additionally, vendors can (and do) define and use proprietary

protocols for communication between CORBA components.

New Term: The General Inter-ORB Protocol (GIOP) is a high-level standard protocol for communication between ORBs.

Because GIOP is a generalized protocol, it is not used directly; instead, it is specialized by a particular protocol that would

then be used directly.

For discussion and use of CORBA in this book, your main interest will be the GIOP-based protocol for TCP/IP networks,

known as the Internet Inter-ORB Protocol (IIOP). As of the 2.0 version of the CORBA specification, vendors are required to

implement the IIOP protocol in order to be considered CORBA-compliant (although they might offer their proprietary

protocols in addition to IIOP). This requirement helps to ensure interoperability between CORBA products from different

vendors because each CORBA 2.0-compliant product must be able to speak the same language. Some vendors have gone so

far as to adopt IIOP as their products’ native protocol (the protocol used by default) rather than use a proprietary protocol;

however, an ORB is allowed to support any number of protocols, as long as IIOP is supported (when communicating with

each other, ORBs can negotiate which protocol to use). Additionally, a number of vendors are including IIOP-compliant

ORBs with products ranging from database servers to application development tools to Web browsers. IIOP, as you can see,

is an important key to CORBA interoperability.

New Term: The Internet Inter-ORB Protocol (IIOP) is a specialization of the GIOP. IIOP is the standard protocol for

communication between ORBs on TCP/IP based networks. An ORB must support IIOP (but can support other additional

protocols) in order to be considered CORBA 2.0-compliant.

CORBA and the Networking Model

With all this discussion of inter-ORB protocols, you have yet to see where CORBA fits in with the rest of the networking

model. Figure 2.3 illustrates the network architecture of a typical CORBA application. Essentially, CORBA applications are

built on top of GIOP-derived protocols such as IIOP. These protocols, in turn, rest on top of TCP/IP, DCE, or whatever

underlying transport protocol the network uses. CORBA applications aren’t limited to using only one of these protocols; an

application architecture can be designed to use a bridge that would interconnect, for instance, DCE-based application

components with IIOP-based ones. You can see, then, that rather than supplant network transport protocols, the CORBA

architecture creates another layer—the inter-ORB protocol layer—which uses the underlying transport layer as its

foundation. This, too, is a key to interoperability between CORBA applications, as CORBA does not dictate the use of a

particular network transport protocol.

Figure 2.3. Architecture of a distributed CORBA application.

Page 28: Overview of Com-Dcom

The CORBA Object Model

Every object-oriented architecture features an object model, which describes how objects are represented in the system. Of

course, CORBA, being an object-oriented architecture, has an object model as well. Because CORBA is a distributed

architecture, however, its object model probably differs somewhat from the traditional object models with which most

readers are familiar (such as C++’s or Java’s object model). Three of the major differences between the CORBA object

model and traditional models lie in CORBA’s “semi-transparent” support for object distribution, its treatment of object

references, and its use of what are called object adapters—particularly the Basic Object Adapter (BOA). You will now

explore these concepts in greater depth.

Object Distribution

To a CORBA client, a remote method call looks exactly like a local method call, thanks to the use of client stubs (a concept

you’ll explore later in this chapter). Thus, the distributed nature of CORBA objects is transparent to the users of those

objects; the clients are unaware that they are actually dealing with objects which are distributed on a network.

Actually, the preceding statement is almost true. Because object distribution brings with it more potential for failure (due to a

network outage, server crash, and so on), CORBA must offer a contingency to handle such possibilities. It does so by

offering a set of system exceptions, which can be raised by any remote method. You’ll learn about exceptions more in later

chapters—on Day 3, you’ll see how exceptions are declared in IDL; on Day 7, you’ll add exception handling to a sample

application. For the time being, though, all you need to know is that all operations in all CORBA objects implicitly can raise

a CORBA system exception, which signals a network error, server unavailability, or other such situation. Thus, with the

exception—pun intended—of this additional exception raised by CORBA object methods, a remote method is otherwise

identical to its local counterpart.

Object References

In a distributed application, there are two possible methods for one application component to obtain access to an object in

another process. One method is known as passing by reference, illustrated in Figure 2.4. In this method, the first process,

Process A, passes an object reference to the second process, Process B. When Process B invokes a method on that object, the

method is executed by Process A because that process owns the object. (The object exists in the memory and process space

of Process A.) Process B only has visibility to the object (through the object reference), and thus can only request that

Process A execute methods on Process B’s behalf. Passing an object by reference means that a process grants visibility of

one of its objects to another process while retaining ownership of that object.

New Term: When an object is passed by reference, the object itself remains “in place” while an object reference for that

object is passed. Operations on the object through the object reference are actually processed by the object itself.

Figure 2.4.Passing an object by reference.

Page 29: Overview of Com-Dcom

The second method of passing an object between application components is known as passing by value

and is depicted in Figure 2.5. In this method, the actual state of the object (such as the values of its

member variables) is passed to the requesting component (typically through a process known as

serialization). When methods of the object are invoked by Process B, they are executed by Process B

instead of Process A, where the original object resides. Furthermore, because the object is passed by

value, the state of the original object is not changed; only the copy (now owned by Process B) is

modified. Generally, it is the responsibility of the developer to write the code that serializes and

deserializes objects (although this capability is built into some languages, such as Java).

New Term: When an object is passed by value, the object’s state is copied and passed to its destination, where a new copy of

the object is instantiated. Operations on that object’s copy are processed by the copy, not by the original object.

Serialization refers to the encoding of an object’s state into a stream, such as a disk file or network connection. When an

object is serialized, it can be written to such a stream and subsequently read and deserialized, a process that converts the

serialized data containing the object’s state back into an instance of the object.

Figure 2.5. Passing an object by value.

One important aspect of the CORBA object model is that all objects are passed by reference. (Actually, at

the time of this writing, the OMG has issued an RFP (Request for Proposals) for adding to CORBA the

capability to pass objects by value, so it is likely that this capability will be added to the CORBA standard

in the near future.) In order to facilitate passing objects by value in a distributed application, in addition to

passing the state of the object across the network, it is also necessary to ensure that the component

receiving the object has implementations for the methods supported by that object. (This is not necessary

when objects are passed by reference; recall that method invocations are executed by the component that

owns the actual object.) When the CORBA pass-by-value capability is specified, it will need to address

these issues; readers should stay tuned to OMG announcements for updates on this development. (The

OMG Web site, which makes available a great deal of CORBA-related information and specifications, is

located at http://www.omg.org/.)

There are a few issues associated with passing objects by reference only. Remember that when passing by reference is the

only option, methods invoked on an object are always executed by the component that owns that object (in other words, the

component that has created that object); an object cannot migrate from one application component to another. (However, you

Page 30: Overview of Com-Dcom

can devise methods that simulate this behavior; it simply is not provided by the CORBA architecture itself at this time.) This

also means that all method calls are remote method calls (unless both the calling object and called object are owned by the

same application component). Obviously, if a component invokes a lengthy series of method calls on a remote object, a great

deal of overhead can be consumed by the communication between the two components. For this reason, it might be more

efficient to pass an object by value so the component using that object can manipulate it locally. On Day 10 you’ll explore

this issue in greater detail, but in the meantime, readers should be aware that CORBA’s current lack of pass-by-value

semantics does raise this issue.

Basic Object Adapters (BOAs)

The CORBA standard describes a number of what are called object adapters, whose primary purpose is to interface an

object’s implementation with its ORB. The OMG recommends that new object adapter types be created only when necessary

and provides three sample object adapters: the Basic Object Adapter (BOA), which you will concentrate on, and the Library

Object Adapter and Object-Oriented Database Adapter, both of which are useful for accessing objects in persistent storage.

(The CORBA specification describes these object adapters in greater detail.) Again, you will concern yourself only with the

Basic Object Adapter, by far the most commonly used object adapter.

The BOA provides CORBA objects with a common set of methods for accessing ORB functions. These functions range from

user authentication to object activation to object persistence. The BOA is, in effect, the CORBA object’s interface to the

ORB. According to the CORBA specification, the BOA should be available in every ORB implementation, and this seems to

be the case with most (if not all) CORBA products available.

Server Activation Policies

One particularly important (and useful) feature of the BOA is its object activation and deactivation capability. The BOA

supports four types of activation policies, which indicate how application components are to be initialized. These activation

policies include the following:

• The shared server policy, in which a single server (which in this context usually means a process running

on a machine) is shared between multiple objects

• The unshared server policy, in which a server contains only one object

• The server-per-method policy, which automatically starts a server when an object method is invoked and

exits the server when the method returns

• The persistent server policy, in which the server is started manually (by a user, batch job, system daemon,

or some other external agent)

New Term: A server activation policy indicates how that particular server is intended to be accessed; for example, if there is

a single server used by all clients, or a new instance of the server should be started for each client, and so on.

This variety of activation policies allows an application architect to choose the type of behavior that makes the most sense for

a particular type of server. For instance, a server requiring a length of time to initialize itself might work best as a persistent

server, because the necessary initialization time would adversely affect the response time for that server. On the other hand, a

server that starts up quickly upon demand might work well with the server-per-method policy.

Note:It is worth noting here that the term persistent server has nothing to do with the common use of the

term persistent, which refers to the capability of an object to store its state in some sort of nonvolatile

storage facility such as a database of disk files. A persistent server does not necessarily store its state in

persistent storage (although it could); in this case, the term merely implies that the server runs persistently

or, in other words, continuously.

CORBA Clients and Servers

Traditionally, in a client/server application, the server is the component, or components, that provides services to other

components of the application. A client is a component that consumes services provided by a server or servers. The

architecture of a CORBA application is no different; generally, certain components of an application provide services that are

used by other components of the application. Not surprisingly, the general terms client and server refer to these components

of a CORBA application. When considering a single remote method invocation, however, the roles of client and server can

be temporarily reversed because a CORBA object can participate in multiple interactions simultaneously.

Page 31: Overview of Com-Dcom

In a CORBA application, any component that provides an implementation for an object is considered a server, at least where

that object is concerned. If a component creates an object and provides other components with visibility to that object (in

other words, allows other components to obtain references to that object), that component acts as a server for that object; any

requests made on that object by other components will be processed by the component that created the object. Being a

CORBA server means that the component (the server) executes methods for a particular object on behalf of other

components (the clients).

Multiple Personalities? Being Both a Client and a Server

Frequently, an application component can provide services to other application components while accessing services from

other components. In this case, the component is acting as a client of one component and as a server to the other components

(see Figure 2.6). In fact, two components can simultaneously act as clients and servers to each other. To understand this

situation, consider the following scenario (illustrated in Figure 2.7): The first component, Component A, receives a reference

to an object created by a second component, Component B, and calls a method on that object. Here, Component A acts as a

client and Component B acts as a server. Now assume that as a parameter of the method called, Component A passes a

reference to an object that it has created (and thus provides an implementation for the object). Assume further that

Component B now calls some method on that object. For this particular method invocation, Component A acts as a server,

whereas Component B acts as a client. The two components have not changed their overall roles in the application, but they

have temporarily reversed their roles as client and server. Therefore, from this example you see that in a CORBA application,

the terms client and server might depend on the context of the method being called and in which component that method’s

object resides.

Figure 2.6. Acting as a client and a server.

One last point to consider in the terminology of clients and servers: Although an application component

can function as both a client and a server, it is nevertheless typical to label such a component as one or the

other (not both). In the preceding example, assume that for the most part, Component A calls methods on

objects owned by Component B. As illustrated in the example, some (or even all) of these method calls

can pass object references to Component B, which can then make calls through those object references

back to Component A. Although Component A is acting as a server for these method calls, because the

overall function of the component is to use services provided by Component B, and only provides objects

as arguments to methods in Component B, you might very well refer to Component A as the client and to

Component B as the server. Methods called in this way are generally referred to as client callback

methods, or simply callbacks. Callbacks are especially important given CORBA’s current lack of pass-by-

value capability; the capability to pass objects by value, when it becomes available, will eliminate the

need for many callbacks.

New Term: Client callback method, or simply callback, is a generic term given to a method that is implemented by a client

and called by a server. Callbacks essentially make a client

Page 32: Overview of Com-Dcom

Figure 2.7. A client callback method.

Stubs and Skeletons

After a developer creates component interface definitions using IDL, he or she processes the resulting IDL files with an IDL

compiler. The IDL compiler generates what are known as client stubs and server skeletons. Client stubs and server skeletons

serve as a sort of “glue” that connects language-independent IDL interface specifications to language-specific

implementation code. Client stubs for each interface are provided for inclusion with clients that use those interfaces. The

client stub for a particular interface provides a dummy implementation for each of the methods in that interface. Rather than

execute the server functionality, however, the client stub methods simply communicate with the ORB to marshal and

unmarshal parameters.

New Term: A client stub, which is generated by the IDL compiler, is a small piece of code that makes a particular CORBA

server interface available to a client.

A server skeleton, also generated by the IDL compiler, is a piece of code that provides the “framework” on which the server

implementation code for a particular interface is built.

On the other side, you have server skeletons, providing the framework upon which the server is built. For each method of an

interface, the IDL compiler generates an empty method in the server skeleton. The developer then provides an

implementation for each of these methods. Figure 2.8 illustrates how client stubs and server skeletons fit into a CORBA

application.

Figure 2.8. Client stubs and server skeletons.

You will study the process of building a CORBA client and server in detail on Day 4. There you will find

how to use the IDL compiler, how to build a CORBA client using the client stubs generated by the IDL

Page 33: Overview of Com-Dcom

compiler, and how to build a CORBA server, starting from the server skeletons also generated by the IDL

compiler. Eventually, you will see that you can build CORBA clients without using client stubs at all,

using what is known as the Dynamic Invocation Interface (DII). Rather than being statically linked to

server interfaces, such clients can discover server interfaces dynamically and use services not even

conceived of at the time the clients were built. (However, using the DII significantly increases the

complexity of a client application and is probably best left for a certain niche of applications.) Because

the Dynamic Invocation Interface is considered an advanced topic, you won’t be seeing any more of it

until Day 11.

Beyond the Basics: CORBAservices and CORBAfacilities

Certainly, much can be accomplished using just the basics of CORBA: using IDL to create component interfaces, then

implementing those interfaces and developing clients to exploit the services provided. However, the Object Management

Architecture (which you’ll recall is the Object Management group’s overall architecture which includes CORBA) provides

much more than the basic ORB capabilities in the form of CORBAservices and CORBAfacilities. These capabilities include

event management, licensing, object persistence, naming, security, transactions, user interface management, data interchange,

and much more. The interfaces for using these capabilities are standardized by the OMG, meaning that their usage is (or will

be) consistent across platforms and products. What’s more, the interfaces for CORBAservices and CORBAfacilities are

specified in IDL, meaning that applications can use these services just as they use any other CORBA objects.

You will examine the CORBAservices and CORBAfacilities, both present and future, on Day 12. For the time

being, you should be aware that there is a difference between what services and facilities are specified by the

OMG and what services and facilities are available in various CORBA products. Before deciding to use a

particular service or facility in an application design, you should first ensure that a product actually exists that

implements that functionality. Also note that in order to be considered CORBA 2.0-compliant, a product need not

implement any of the CORBAservices or CORBAfacilities; only the CORBA core functionality is required.

By now you are very familiar with the basic mechanisms provided by CORBA to enable the development of distributed

object-oriented applications. The ORB mechanism facilitates the communication between CORBA objects and enables

objects to locate each other, and the BOA provides the core functionality for all CORBA objects.

The functionality provided by the ORB and the BOA alone is not nearly enough on which to build robust, enterprise-class-

distributed applications. Additional capabilities would definitely be advantageous—such as directory services, persistent

object capability, a transaction mechanism, user interface and presentation facilities, and so on—regardless of the industry in

which they are used. Many industries—such as health care, finance, and telecommunications—require applications that are

especially well-suited to CORBA, so functionality that caters to these vertical markets is a good idea. As it turns out, the

OMG offers such horizontal and vertical functionality in the form of CORBAservices and CORBAfacilities.

You’ve already been introduced, albeit briefly, to CORBAservices and CORBAfacilities. Today you’ll learn about these in

greater detail, as well as get the chance to apply some of the CORBAservices to the Bank application you’ve been

developing.

CORBAservices

The Object Management Architecture (OMA), of which CORBA is a part, defines a number of services that are useful to

applications in general. These services range from the nearly indispensable Naming Service to higher level services such as

the Transaction Service. As with all its specifications (including CORBA), the Object Management Group (OMG) does not

define the implementations for these services but provides the interfaces by which the services are offered. It is up to the

various CORBA product vendors to supply implementations. Note that products implementing CORBAservices are often

provided separately from CORBA ORB products and that implementation of CORBAservices is not necessary for CORBA 2

compliance.

This section briefly describes each of the CORBAservices. In Appendix B, “CORBA Tools and Utilities,” you’ll see which

vendors are currently providing implementations for these services.

Page 34: Overview of Com-Dcom

Concurrency Control Service

The Concurrency Control Service provides an interface for managing concurrency in shared CORBA objects. This is done

through the use of locks, several types of which are supported by the service. For example, readers-writer locks are

supported, as are intention locks. Developers who have worked with multithreaded applications are probably familiar with

the features provided by the Concurrency Control Service.

Event Service

The Event Service provides a mechanism through which CORBA objects can send and receive events. The service includes

such features as these:

• Reliable delivery, which (simply put) ensures that an event will reach its destination(s)

• Support for push and pull models of event delivery

• Anonymous messaging, when suppliers need not know the identities of event consumers, or vice versa

• Event channels, a mechanism similar to publish/subscribe, through which consumers can subscribe to

certain types of events Externalization Service

The Externalization Service provides interfaces for externalizing (that is, serializing) and internalizing objects. When an

object is externalized, it can be internalized within the same process or a different process. In addition, objects can be

externalized into a portable file format (one that is defined with the Externalization Service Specification). One possible

application for the Externalization Service is in a pass-by-value mechanism for CORBA objects.

Licensing Service

The Licensing Service enables the provider to define policies that control the use of services. The service supports three types

of licensing policies:

• Time enables a license to set a start date, expiration date, and duration.

• Value mapping enables licensing based on units (resource usage metering, number of concurrent users, and

so on).

• Consumer assigns services for use by a particular user or machine.

Facilities like those provided by the Licensing Service will become more widely used as concepts such as pay-as-you-go or

rentable software are realized. For example, an occasional user of image editing software might pay per use of a certain

image filter. As a framework for electronic commerce becomes available, it is possible that you’ll see more software made

available in this way.

Life Cycle Service

The Life Cycle Service offers facilities for creating, deleting, copying, and moving CORBA objects. The service also

supports the notion of an object factory, which is a CORBA object that creates other CORBA objects.

Naming Service

The Naming Service enables CORBA objects to register and be located by name. This service uses the notion of a naming

context, which contains a set of unique names. The Naming Service also supports a federated architecture, meaning that

name servers can be distributed across the network and work in conjunction with each other.

You recall that, as a part of the standard bind mechanism, CORBA objects are given names by which other objects can look

them up. Although you can think of this feature as a miniature Naming Service, the actual Naming Service is much more

scalable.

Object Trader Service

The Trader Service, like the Naming Service, enables other objects to locate CORBA objects. Rather than use a name to

locate an object, a client object looks for services based on operation names, parameters, and result types.

The major difference between the Trader Service and the Naming Service is analogous to the difference between the yellow

pages and the white pages of a telephone directory. The Naming Service can be thought of as the white pages, in which you

look up a particular service if you know its exact name. The Trader Service, on the other hand, resembles the yellow pages,

in which you locate a service, based on its location, function, or even name. For example, in the white pages you can look up

“Bob’s Dry Cleaning;” in the yellow pages you can look for all dry cleaning services in, say, Littleton, Colorado. In the

Page 35: Overview of Com-Dcom

Bank example from previous chapters, an application might use the Naming Service to locate a Bank by its name (such as

FirstBank) or use the Trader Service to locate objects by function (such as a bank or an ATM).

Persistent Object Service

The Persistent Object Service provides a set of interfaces for managing the persistence of objects. Typically, implementations

for this service are provided by database vendors.

Persistent objects are objects that persist over a period of time; that is, the lifetime of the object can transcend the lifetime of

any one application. While not in use, the object resides in a persistent store, such as a database or a flat file; the object can

then be retrieved, or resurrected, when needed. For example, a document created by a word processor can be thought of as a

persistent object because the word processor application can be closed and run again later, allowing the document to be

retrieved. In a CORBA application, it will sometimes be useful to provide persistent capability to CORBA objects. For

example, in the sample Bank application, the Bank objects could conceivably be persistent objects. A Bank could be

resurrected as needed, and then when it is no longer processing transactions, it could be put to sleep, meaning that its state

could be stored in a database until the Bank was needed again.

Property Service

The Property Service enables objects to define sets of properties, which are name/value pairs. The name in a pair is simply a

CORBA string; the value is a CORBA any. Access to properties can be restricted. For example, a property can be read-only

or fixed.

The use of properties to describe objects is becoming more widespread, particularly as object models such as JavaBeans gain

momentum. A large application, or set of applications, could define a number of standard properties for its objects, thereby

potentially easing management. For example, if the Bank application defined a location property for each object, the

location of Banks, ATMs, Customers, and other objects could be determined in a uniform way anywhere in the application

code.

Query Service

The Query Service supports the use of queries on objects. Queries can contain predicates that specify objects to act on, based

on attribute values. The service also supports object indexing as well as nested queries. Query capability provides database-

like semantics to CORBA objects. Just as an application can perform queries on tables and rows in a relational database, the

Query Service allows an application to perform queries on CORBA objects.

Relationship Service

The Relationship Service enables the representation of relationships between objects. It provides for full constraint checking

of relationship type and cardinality (one-to-many, one-to-one, and so on) and also works in conjunction with the Life Cycle

Service to copy, move, and remove related objects. Managing relationships between objects is, of course, possible without

the Relationship Service, but this service reduces the complexity of managing complex relationships.

Security Service

The Security Service specifies the interfaces for security features:

• Identification and authentication of users, which verify that a user is who he or she claims to be.

• Authorization and access control determine which users are enabled access to which services or objects.

• Security auditing, which provides records of users’ actions.

• Security of communication, which includes authentication of users to services (and vice versa), integrity

protection, and confidentiality protection.

• Non-repudiation, which provides capabilities similar to those offered by digital signatures; that is, the

origin of data or the receipt of data can be proven irrefutably.

• Administration of various security policies.

Security is a paramount issue in a number of applications; for example, in a production bank application, virtually all aspects

of the system must be made secure, from authentication and identification of customers to security of communication

between banks and ATMs.

Page 36: Overview of Com-Dcom

Time Service

The Time Service enables a user to obtain the current time; it can determine event ordering and can generate events based on

timers.

Transaction Service

The Transaction Service provides the interfaces to support transaction capabilities. It supports flat and nested transaction

models as well as external TP monitors. Transaction services can also interoperate with each other.

Transaction semantics are an integral part of almost every non-trivial application. For example, in the sample Bank

application, to coordinate a transfer between accounts at different banks, a transaction should be initiated that would cause

the banks involved either to both commit the transaction or to both abort the transaction; otherwise, inconsistent data (such as

account balances) would result.

CORBAfacilities

CORBAfacilities cover both horizontal facilities (features useful to all types of CORBA applications across various

industries) and vertical facilities (functionality that is especially useful to applications within particular vertical markets and

industries). Horizontal facilities include user interface and system management facilities because this functionality is useful

to most types of applications, regardless of the industry in which they are used. Vertical facilities might include, for example,

general ledger and amortization functionality for use within the accounting industry, or automated shop floor control

facilities for use in the manufacturing industry. Like CORBAservices, the OMG only specifies the interfaces for these

facilities; the implementations, where applicable, are provided by CORBA vendors. Additionally, some CORBAfacilities

only suggest interfaces to be used for particular services and types of applications.

Horizontal Facilities

The horizontal CORBAfacilities are categorized into four types of facilities: user interface, information management,

systems management, and task management. These categories are further broken down into other facilities (listed in the next

section). Again, horizontal facilities are advantageous to all types of applications, regardless of industry. For example, most

applications require user interfaces, methods of information storage and retrieval, security facilities, workflow and process

management, and so on.

User Interface Common Facilities

The User Interface Common Facilities cover all that relates to user interfaces, from the tools used to develop them to the way

they are presented to the user. CORBAfacilities defines the following components of user interfaces: User Interface Style is

the “look and feel” presented to the user by the application. User Interface Enablers present the user interface to the user.

Enablers are grouped into the following facilities:

• Rendering Management, for abstracting user interface objects

• Compound Presentation, for displaying compound documents

• User Support, for spell checking, online help, and so on

Work Management System maintains a user’s work environment and consists of the user’s desktop, single sign-on to the

system, and information used by the user. Task and Process Automation enables users to write scripts to automate their tasks

and use workflows.

Information Management Common Facilities

The Information Management Common Facilities consist of the following: Information Modeling deals primarily with the

way data is structured.

Information Storage and Retrieval includes databases, information retrieval systems, and repositories.

Information Interchange enables the exchange of data between users and between applications, consisting of the Compound

Interchange Facility, the Data Interchange Facility, and the Information Exchange Facility. Data Encoding and

Representation deals with how information is stored, down to the bit level, if necessary. The primary reason for addressing

this is to enable portability of data between applications, processes, hardware and software architectures, and so on.

Systems Management Common Facilities

The Systems Management Common Facilities provide interfaces for system administration. Policy Management controls the

creation, deletion, and modification of manageable components.

Page 37: Overview of Com-Dcom

Quality of Service Management supports the selection of service levels for availability, performance, reliability, and

recovery.

Instrumentation provides the capability to gather and analyze data regarding system load, object location, system

responsiveness, and so on.

Data Collection includes capabilities such as logging and data archival.

Security provides for the management of security of system resources.

Collection Management enables administrators to deal with collections of objects to be managed.

Instance Management enables objects to be associated with other objects for management purposes.

Scheduling Management enables tasks to be performed in a controlled manner (for example, to occur at a certain time or as a

response to a particular event).

Customization enables objects to be extended dynamically while retaining type safety. Event Management provides for

various manipulations of events in the system.

Task Management Common Facilities

Task Management Common Facilities support the processing of user tasks. Among the Task Management Common

Facilities are the following: Workflow provides management and coordination of objects that are part of a work process, for

example, a purchase process. It supports production-based workflows as well as ad hoc (coordination-based) workflows.

Agent supports both static and mobile agent types. Although the definition and discussion of the use of agents are beyond the

scope of this chapter, the agent-related facilities include the Content Service, the Communication Service, the Message

Service, the Basic Information Services, the Simple Query Services, the Multi-Response Query Services, the Assertion

Services, the Generation Services, the Capability Definition Services, the Notification Services, the Networking Services, the

Facilitation Services, the Database Services, the Adaptation Services, the Error Correction Services, the Automatic Re-

Transmission Services, the Registration Service, Security Services, and Management Services. (The sheer number of services

suggests that the topic of agents is far beyond the scope of this book.)

Rule Management provides for the specification and processing of rules, which in turn are based on events, conditions, and

actions. Automation provides the capability to use scripts and macros to manipulate large-grained CORBA objects.

Vertical Market Facilities

In addition to the horizontal services and facilities offered by the OMA, there are also a number of vertical

CORBAfacilities—facilities intended for the unique requirements of specific markets. Also, the OMG continually adds new

Vertical Market Facilities, depending on the interest in a particular specialty area. The remainder of this section gives a brief

overview of the Vertical Market Facilities specifications available at the time of this writing.

Note:Although now a part of the OMG’s Facilities Architecture, the Vertical Market Facilities are largely

being superceded by work done by the OMG’s various Domain Task Forces. Each of these Task Forces

produces specifications for the vertical application domain to which it is assigned. An overview of the

work completed (or in progress) by the Task Forces at the time of this writing appears in Appendix C,

“What Lies Ahead? The Future of CORBA.”

Imagery supports the access and interchange of imagery and related data.

Information Superhighways consists of a set of networks, protocols, and rules, information repositories connected through

these networks, and a collection of tools for transparent access to this information.

Manufacturing represents the integration of manufacturing functions and resources with other aspects of the business

enterprise.

Distributed Simulation supports distributed simulations of air traffic control, video games and entertainment, and other

needs.

Page 38: Overview of Com-Dcom

Oil and Gas Industry Exploration and Production provides a foundation for defining specifications for exploration and

production (E&P). Requirements for E&P include dealing with large quantities of data, complex algorithms, and long-term

data storage.

Accounting provides an interoperable approach to accounting interfaces and seeks to remove the complexity from accounting

service providers and end users.

Application Development covers the selection, development, building, and evolution of the applications needed to support an

enterprise’s information systems strategy. Mapping provides a cohesive means of manipulating the flow of data from

databases through constructed analysis modules into either presentation tools or secondary data applications.

Enhancing the Bank Example with CORBAservices

Of course, today wouldn’t be complete without a discussion and example of how to integrate CORBAservices and

CORBAfacilities with the Bank example. This section will do just that. First, you’ll examine which CORBAservices are of

use to the Bank application; then, you’ll modify the application to employ those services. There isn’t room in this chapter (or

this book, for that matter) to make use of all the CORBAservices and CORBAfacilities that might be applicable, so you will

focus on just a couple.

Choosing CORBAservices

Now, briefly review the available CORBAservices for a moment and analyze the suitability of each service to the Bank

application:

• The Concurrency Control Service. Because it is quite feasible that objects in the Bank application

(particularly Banks) might be accessed by different objects simultaneously, the use of the Concurrency

Control Service has merit. However, the type of concurrency used might be better serviced by the

Transaction Service.

• The Event Service. If the Bank application were to expand to include messages other than those used by the

account update service added on Day 9, “Using Callbacks to Add Push Capability,” the Event Service

would prove beneficial.

• The Externalization Service. Externalization of objects isn’t a terribly important feature to the Bank

application.

• The Licensing Service. Bank services are generally not licensed, so you can safely overlook the Licensing

Service for the purposes of the Bank application.

• The Life Cycle Service. The Bank application would theoretically benefit from the use of the Life Cycle

Service but is served well enough by the standard CORBA mechanisms for managing object life cycle.

• The Naming Service. If the Bank application were to grow into a highly distributed system, it would benefit

greatly from the use of the Naming Service. Rather than use the standard CORBA bind mechanism, you

could locate Banks through a federated Naming Service.

• The Object Trader Service. Because the Bank application components are well-known and localized, it is

unlikely that components will need to locate objects based on the services they provide. The Trader Service

is geared more towards applications that require richer facilities for locating services. (Had the scope of the

Bank application been more extensive, it might have been worthwhile to provide the capability to look up

Banks based on location, for example.)

• The Persistent Object Service. The Persistent Object Service would be worthwhile, for example, to a Bank

that needs to store customer and account data in persistent storage while the information is not in use.

• The Property Service. Although the Property Service can be used, for example, to represent customer or

account information, it is not particularly advantageous to the Bank application.

• The Query Service. As it stands, the Bank application would not benefit greatly from the Query Service.

However, if reporting tools were developed to work with the Bank application, the Query Service would

prove useful.

• The Relationship Service. For the Bank application, there is little value in using the Relationship Service to

model the relationships between objects (for example, between Banks and Accounts or between

Page 39: Overview of Com-Dcom

Customers and Accounts). However, if new objects were added that might increase the complexity of

relationships, the Relationship Service would be helpful.

• The Security Service. Because a Bank needs to be a highly secure institution, the Security Service is

indispensable to a production Bank application. Numerous aspects of the Security Service can be utilized,

such as user identification and authorization, security auditing, communication security, and non-

repudiation. The Security Service is a perfect choice for the Bank application.

• The Time Service. The Time Service is valuable; it ensures that various Banks are in sync with each other

with respect to time.

• The Transaction Service. The Transaction Service is another service that is highly useful to a Bank

application. In particular, the interoperability with a TP monitor can coordinate transactions between

Accounts and between Banks.

Looking at the CORBAservices from the perspective of what would provide the most utility for the Bank application, the

answer would probably be the Security Service and the Transaction Service. However, looking at the services from the

perspective of what’s readily available (and what space is available in this book) a more practical choice would be the

Naming Service.

Implementing the New Functionality

Deciding where to use the functionality provided by the Naming Service is easy. The Naming Service can replace the use of

the standard CORBA bind mechanism; rather than bind to objects directly by name, CORBA objects can use the Naming

Service to look up other objects. In the Bank application, the only object that is located in this manner is the BankServer;

all other server objects (Banks and ATMs) are located through the BankServer itself. Because these changes aren’t major,

they fit well within the scope of this chapter.

Using the CORBA Naming Service

Rather than bind directly to the BankServer using the CORBA bind mechanism, application components instead bind to a

Naming Context and then use that Naming Context to resolve a BankServer by name. A Naming Context object makes

the functionality of the CORBA Naming Service available to applications. Note that the Naming Context is simply a

CORBA object: Its interface is expressed in IDL, and it is manipulated by an application just as any other CORBA object is.

New Term: A Naming Context is simply a collection of naming structures that associate names with either CORBA object

references or other Naming Contexts. Taken together, these collections of associations form a hierarchical naming structure

that CORBA objects use to locate other objects.

Page 40: Overview of Com-Dcom

CHAPTER 11:-- OBJECT WEB

OBJECT WEB

1. Introduction

Background

Many business and governmental organizations are planning or developing enterprise-wide, open distributed

computing architectures to support their operational information processing requirements. Such architectures

generally employ distributed object middleware technology, such as the Object Management Group's (OMG's)

Common Object Request Broker Architecture (CORBA) [OMG95], as a basic infrastructure.

The use of objects in such architectures reflects the fact that advanced software development increasingly involves

the use of object technology. This includes the use of object-oriented programming languages, class libraries and

application development frameworks, application integration technology such as Microsoft's OLE, as well as

distributed object middleware such as CORBA. It also involves the use of object analysis and design

methodologies and associated tools.

This use of object technology is driven by a number of factors, including:

The desire to build software from reusable components

The desire for software to more directly and more completely reflect enterprise concepts, rather than

information technology concepts

The need to support enterprise processes that involve legacy information systems

The inclusion of object concepts and facilities in key software products by major software vendors

The first two factors reflect requirements for business systems to be rapidly and cheaply developed or adapted to

reflect changes in the enterprise environment, such as new services, altered internal processes, or altered customer,

supplier, or other partner relationships. Object technology provides mechanisms, such as encapsulation and

inheritance that have the potential to support more rapid and flexible software development, higher levels of reuse,

and the definition of software artifacts that more directly model enterprise concepts.

The third factor reflects a situation faced by many large organizations, in which a key issue is not just the

development of new software, but the coordination of existing software that supports key internal processes and

human activities. Mechanisms provided by object technology can help encapsulate existing systems, and unify

them into higher-level processes.

The fourth factor is particularly important. It reflects the fact that, as commercial software vendors incorporate

object concepts in key products, it will become more and more difficult to avoid using object technology. This is

illustrated by the rapid pace at which object technology is being included in software such as DBMSs (including

relational DBMSs) and other middleware, and client/server development environments. Due to this factor,

organizations may be influenced to begin adopting object technology before they would ordinarily consider doing

so.

At the same time, the Internet is becoming an increasingly important factor in planning for enterprise distributed

computing environments. For example, companies are providing information via World Wide Web pages, as well

as customer access via the Internet to such enterprise computing services as on-line ordering or order/service

tracking facilities. Companies are also using Internet technology to create private Intranets, providing access to

enterprise data (and, potentially, services) from throughout the enterprise in a way that is convenient and avoids

proprietary network technology. Following this trend, software vendors are developing software to allow Web

browsers to act as user interfaces to enterprise computing systems, e.g., to act as clients in workflow or general

client/server systems. Products have also been developed that link mainframes to Web pages (e.g., translating

conventional terminal sessions into HTML pages).

Page 41: Overview of Com-Dcom

Organizations perceive a number of advantages in using the Web in enterprise computing. For example, Web

browser software is widely available for most client platforms, and is cheaper than most alternative client

applications. Web pages generally work reasonably well with a variety of browsers, and maintenance is simpler

since the browser and associated software can reduce the amount of distributed software to be managed. In

addition, the Web provides a representation for information which

• Supports interlinking of all kinds of content (text, voice, video, etc.)

• Is easy for end-users to access

• Is easy to create content for using widely-available tools

As the Web Evolves :

The Web is moving from file services to full-blown client/server applicat ions.

Client/Server Interactions on the Object Web

How a Web-based client interacts with its server on the Object Web is pretty simple:

1. Web browser downloads HTML page. In this case, the page includes references to embedded Java

applets.

2. Web browser retrieves Java applet from HTTP server. The HTTP server retrieves the applet and

downloads it to the browser in the form of bytecodes.

3. Web browser loads applet. The applet is first run through the Java run-time security gauntlet and then

loaded into memory.

4. Applet invokes CORBA server objects. The Java applet can include IDL-generated client stubs, which le

t it invoke objects on the ORB server. The session between the Java applet and the CORBA server objects will

persist until either side decides to disconnect. Note that you will need an IIOP-savvy firewall to make this

work. Today, Iona's WonderWall firewall is the only game in town. But by the time you read this, Netscape

might have shipped its own IIOP firewall.

Page 42: Overview of Com-Dcom

5. Server objects can optionally generate the next HTML page for this client. After preparing the next

pages, the server can tell the client what URL to download next. This dynamic HTML generation on the server

side is typically not needed with the Object Web. A client application is packaged as a single HTML page with

embedded components such as applets (or JavaBeans via the Object tag). In contrast to HTTP/CGI, CORBA

lets you instantaneously interact with the server by clicking on any of the components embedded in the HTML

layers without switching out of the page's context to obtain the response.

The technology we just described performs surprisingly well today. However, the Object Web is still under

construction, as we explain next. Some key pieces will have to become available before we can declare the Object

Web ready for mission-critical prime time.

The Three-Tier CORBA/Java Object Web

All new applications on the Object Web will be built and packaged as components. You can use CORBA IDL to

wrapper existing code, written in almost any language, with object interfaces. For example, you could use CORBA

to magically make a million lines of existing COBOL code look like an object (and eventually you might even

masquerade it as a CORBA/Java-Bean). Any IDL-described object can now play on the Object Web in a first-class

manner. This magic works because CORBA -- like Java -- maintains a clean separation between the interface of an

object and its implementation.

Components require a thriving ecosystem to be commercially viable, and the Object Web provides one. The major

computing companies -- including Sun, IBM/Lotus, Netscape, Oracle, Sybase, Novell, and BEA -- are betting their

shops on this killer app. They have chosen both CORBA/IIOP and JavaBeans as the common way to provide a

high level of plug-and-play between their products. To understand what is going on, let's go over the three-tier

client/server architecture of this emerging Object Web.

The Client. The first tier belongs to traditional Web browsers and the new Web-centric desktops (see "The New

User Interface," July BYTE). As opposed to today's static Web pages, the new content will have more of the look-

and-feel of real-world objects -- for example, you'll see places that contain people, things, and other places. This

very dynamic content is provided by ensembles of JavaBeans embedded in mobile containers, such as HTML

pages or Jars, that contain shippable places. You will interact with these objects via drag-and-drop actions and

other forms of direct manipulation. Client Beans will be able to interact with other client Beans in the container as

well as with server Beans. In addition, server Beans will be able invoke methods on client Beans using CORBA

events and callbacks. Note that both IIOP and HTTP can run on the same networks. HTTP is used to download

Web pages, Jars, and images; CORBA is used for Java client-to-server and server-to-client communications.

The Middle Tier. The second tier runs on any server that can service both HTTP and CORBA clients. This

CORBA/HTTP combination is supported on almost every server OS platform -- including Unixes, NT, OS/2,

NetWare, MacOS, OS/400, MVS, and Tandem NonStop Kernel. CORBA objects -- which could eventually be

packaged as Enterprise Java Beans -- act as middle-tier application servers; they encapsulate the business logic.

These objects interact with client JavaBeans via CORBA/IIOP. Less scalable applications can also call these

objects via scripts that run in HTML server pages -- for example, Netscape's Web Application Interface (WAI)

provides such a bridge.

The CORBA objects on the server interact with each other using a CORBA ORB. They can also talk to existing

server applications in the third tier using SQL/Java Database Connectivity (JDBC) or other middleware. You can

even use the CORBA/IIOP server backbone as a general-purpose data bus. This is the technology Oracle is

building for its data plug-ins. JDBC-on-IIOP data backbones are available today from I-Kinetics and Visigenic.

The second tier must also provide a server-side component coordinator -- also known as an object TP monitor.

These component coordinators are TP monitors built on ORBs. Instead of managing remote procedures, they

Page 43: Overview of Com-Dcom

manage objects. The component coordinat or prestarts pools of objects, distributes loads, provides fault tolerance,

and coordinates multicomponent transactions. Without these component coordinators, you cannot manage millions

of server-side objects -- a key requirement of the Object Web. Examples of CORBA-based component

coordinators are IBM's Component Broker and BEA's Tuxedo/Iceberg. But, what is a server-side component? It's a

CORBA server object that also implements a minimum set of component services. A good example of this is the

Oracle Cartridge. Cartridges are named CORBA objects that are also transactional, secure, and capable of emitting

events.

A server component must also be toolable. This means that it must provide introspective interfaces that let you

assemble it using visual tools. This toolable server-side component technology will be provided by CORBAtized

Enterprise Java-Beans. The CORBA/JavaBean technology is being integrated in visual builder tools from

Symantec, Penumbra, ParcPlace, IBM/Taligent, Borland, and Sybase.

In a CORBA/Java Object Web, the second tier also acts as a store of component titles, HTML pages, and

shippable places. These can be stored in shippable Java Jars that are managed by an ODBMS or DBMS.

ODBMSes are better suited for the task.

The Back End. The third tier is almost anything a CORBA object can access. This includes procedural TP

monitors, message-oriented middleware, DBMSes, ODBMSes, Lotus Notes, and e-mail. So the CORBA business

objects replace CGI applications in the middle tier, which is good. Eventually, you will be able to get

CORBA/Java components that encapsulate most of the third-tier functions. This is an area where CORBA's

interlanguage communications capabilities will come in handy. Look at some of the I-Kinetics work to understand

what you can do with these back-end components.

Page 44: Overview of Com-Dcom

Chapter 9:-- EJB

Enterprise Java Beans Enterprise JavaBeans (EJB) technology is the server-side component architecture for the Java 2 Platform, Enterprise Edition (J2EE) platform. EJB technology enables rapid and simplified development of distributed, transactional, secure and portable applications based on Java technology. EJB’s can be considered as middleware components EJB Architecture

Client � EJB Server

� Database

Enterprise beans run in the EJB container, a runtime environment within the J2EE server

Application Server

EJB Container

• •

Beans

• •

The EJB container provides system-level services such as transactions to its enterprise beans. These services enable to quickly build and deploy enterprise beans

� Server - The runtime portion of a J2EE product. A J2EE server provides EJB and Web containers. � Enterprise JavaBeans (EJB) container - Manages the execution of enterprise beans for J2EE

applications. � Web container - Manages the execution of JSP page and servlet components for J2EE applications.

Web components and their container run on the J2EE server. � Application client container - Manages the execution of application client components. Application

clients and their container run on the client.

� Container Services – Containers are the interface between a component and the low-level platform-specific functionality that supports the component.

Benefits of Enterprise Beans

� Enterprise beans simplify the development of large, distributed applications. � EJB container provides system-level services to enterprise beans, the bean developer can

concentrate on solving business problems. � The EJB container developer is responsible for system-level services such as transaction

management and security authorization.

� EJbeans contain the application's business logic, the client developer can focus on the presentation of the client.

� The client developer does not have to code the routines that implement business rules or access databases.

� Enterprise beans are portable components, the application assembler can build new applications from existing beans.

Page 45: Overview of Com-Dcom

When to Use Enterprise Beans

• The application must be scalable. To accommodate a growing number of users, you may need to distribute an application's components across multiple machines.

• The enterprise beans of an application run on different machines, but their location will remain transparent to the clients.

• Transactions are required to ensure data integrity. - Enterprise beans support transactions, the mechanisms that manage the concurrent access of shared objects.

• The application will have a variety of clients. Summary of Enterprise Java Bean Types

Enterprise Bean Type

Purpose

Session Performs a task for a client

Entity Represents a business entity object that exists in persistent storage

Message-Driven

Acts as a listener for the Java Message Service API, processing messages asynchronously

Important Features of EJBs

� remote communication using CORBA � database connectivity � persistence � transactions � concurrency control � events using JMS (Java messaging service). � security

� deployment of components in an application server.

Page 46: Overview of Com-Dcom

JNI – Java Native Interface

The Java Native Interface (JNI) is the native programming interface for Java that is part of the JDK. By writing programs using the JNI, the code is completely portable across all platforms. The JNI allows Java code that runs within a Java Virtual Machine (JVM) to operate with applications and libraries written in other languages, such as C, C++, and assembly. In addition, the Invocation API allows you to embed the Java Virtual Machine into your native applications. Situations when Java can be used

• The standard Java class library may not support the platform-dependent features needed by application.

• You may already have a library or application written in another programming language and you wish to make it accessible to Java applications.

• You may want to implement a small portion of time-critical code in a lower-level programming language, such as assembly, and then have your Java application call these functions.

A native method can create Java objects, including arrays and strings, and then inspect and use these objects to perform its tasks. A native method can also inspect and use objects created by Java application code. A native method can even update Java objects that it created or that were passed to it, and these updated objects are available to the Java application. Thus, both the native language side and the Java side of an application can create, update, and access Java objects and then share these objects between them. The native method, using the JNI framework, can call the existing Java method, pass it the required parameters, and get the results back when the method completes. The JNI enables to use the advantages of the Java programming language from your native method. Catch and throw exceptions from the native method and have these exceptions handled in the Java application. Native methods can also get information about Java classes. By calling special JNI functions, native methods can load Java classes and obtain class information. Native methods can use the JNI to perform runtime type checking.

IUnknown :

IUnknown is the name of the fundamental interface in the Component Object Model (COM). The published COM

specification mandates that COM objects must minimally implement this interface. Furthermore, every other COM

interface must be derived from IUnknown.

IUnknown comprises three functions - QueryInterface, AddRef and Release.

• QueryInterface is used to obtain a pointer to another interface, given a GUID that uniquely identifies that

interface (commonly known as an interface ID, or IID). If the COM object does not implement that

interface, an E_NOINTERFACE error is returned instead.

• AddRef is used by clients to indicate that a COM object is being referenced. This is necessary to ensure

that a COM object is not disposed prematurely.

• Release is used by clients to indicate that they have finished using the COM object. An unreferenced COM

object may be safely disposed.

interface IUnknown

{

virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0;

virtual ULONG AddRef(void) = 0;

virtual ULONG Release(void) = 0;

};

Page 47: Overview of Com-Dcom

The IUnknown interface ID is defined as a GUID with the value of {00000000-0000-0000-C000-

000000000046}.

HRESULT

HRESULT is the data type used to indicate the status of operations in Microsoft's Component Object Model

(COM). An HRESULT value has 32 bits divided into three fields: a severity code, a facility code, and an error

code. The severity code indicates whether the return value represents information, warning, or error. The facility

code identifies the area of the system responsible for the error. The error code is a unique number that is assigned

to represent the exception. Each exception is mapped to a distinct HRESULT. When managed code throws an

exception, the runtime passes the HRESULT to the COM client. When unmanaged code returns an error, the

HRESULT is converted to an exception, which is then thrown by the runtime. HRESULTs are 32 bit values laid

out as follows:

3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1

1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

+-+-+-+-+-+---------------------+-------------------------------+

|S|R|C|N|r| Facility | Code |

+-+-+-+-+-+---------------------+-------------------------------+

where

• S - Severity - indicates success/fail

o 0 - Success

o 1 - Fail (COERROR)

• R - reserved portion of the facility code, corresponds to NT's second severity bit.

• C - reserved portion of the facility code, corresponds to NT's C field.

• N - reserved portion of the facility code. Used to indicate a mapped NT status value.

• r - reserved portion of the facility code. Reserved for internal use. Used to indicate HRESULT values that

are not status values, but are instead message ids for display strings.

• Facility - is the facility code

• Code - is the facility's status code

HRESULT is a 32-bit value, divided into three different fields: a severity code, a facility code, and an error code.

The severity code indicates whether the return value represents information, warning, or error. The facility code

identifies the area of the system responsible for the error. The error code is a unique number that is assigned to

represent the exception. Each exception is mapped to a distinct HRESULT. When managed code throws an

exception, the runtime passes the HRESULT to the COM client. When unmanaged code returns an error, the

HRESULT is converted to an exception, which is then thrown by the runtime.