Sunteți pe pagina 1din 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
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.
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
class FastString
#include “faststring.h” • C++ libraries have been distributed in
FastString::FastString( char *psz)
{ { m_psz=new char[strlen(psz)+1];
source code form.
char *m_psz ;
public:
strcpy(m_psz,psz) ; } • Recompile the executable code of the
FastString::~FastString()
FastString( char *psz); { delete[] m_psz ; } library would be bundled as part of
~FastString();
int Length(void) ;
int FastString::Length(void) the overall client application.
{ return strlen(m_psz); }
int Find(char *psz); int FastString::Find(char *psz) • The generated machine code occupies
}; { //Code to find } 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.
class __declspec (dllexport) FastString #include “faststring.h” • All the methods of X will be added to the
{ FastString::FastString( char *psz)
char *m_psz ; { m_psz=new char[strlen(psz)+1] ;
exports list of the X DLL, allowing
public: strcpy(m_psz,psz) ; runtime resolution of each method name
FastString( char *psz); }
~FastString(); FastString::~FastString()
to its address in memory. The linker will
int Length(void) ; { delete[] m_psz ; produce an import library. The import
int Find(char *psz); }
}; int FastString::Length(void)
library simply contains references to the
{ return strlen(m_psz); } file name of the DLL and the names of
int FastString::Find(char *psz)
{ //Code to find }
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.
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
Interface Implementation
• The data types actual implementation as the
• A Pointer • Data members Diagram other class called as the implementation class
• Method decl of public funcs • Member funcs • Interface class to be kept constant whereas
• No data members
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
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.
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.
Interfaces and IDL [attribute1, attribute2, ….]
The IDL interface keyword is used to begin the definition of the interface. interface IThisInterface :
The Interface definition has four components IBaseInterface
1) the interface name {
2) interface body typedef1;
3) base interface name typedef2;
4) interface attributes. …
Every COM interface must have two IDL attributes. The [object] attribute is method1;
required to indicate that the interface is a COM interface & not a DCE - style method2;
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.
GUIDs Interfaces o 32 hexadecimal digit represent 128 bit physical name called as GUID
(128- ---------- IIDs (24 bytes)
bit) ---------- o UUID means Universally Unique Identifier (DCE RPC)
CLSIDs o In case of Classes GUID is called as CLSID
Implementations 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 VB does not require clients to
the Type-Cast type-cast, when an interface
public void pointer is assigned to a type-
TryToSnoreAndIgnore( Object j incompatible var, the VB VM
) silently calls QueryInterface on
{ behalf of the client.
IPug pug;
try { Sub TryToSnoreAndIgnore( Obj
pug = (IPug)obj ; // VM calls as Object )
QueryInterface On Error Resume Next ‘ignore
pug.Snore( ); errors
} catch(Throwable ex) { Dim pug as IPug
// Ignore method or QI Set pug = obj; ‘VM calls
failure QueryInterface
} If Not( pug is Nothing) Then
ICat cat; pug.Snore
try { End if
cat = (ICat)obj ; // VM calls Dim cat as ICat
QueryInterface Set cat = obj; ‘VM calls
cat.IgnoreMaster( ); QueryInterface
} catch(Throwable ex) { If Not( cat is Nothing) Then
// Ignore method or QI cat.IgnoreMaster
failure 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
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.
Severity Reserved Facility Information
code Code code
31 30-29 28-16 15-0

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 VB Microsoft Java
C++
Small Char Unsupported Char
Short Short Integer Short
Long Long Long Int
Base Float Float Single Float
Types Double double Double Double
Enum Enum Enum Int
Interface Pointer Interface Interface Interface Ref.
Pointer Ref.
VARIANT VARIANT Variant Ms.com.Variant
Extended
BSTR BSTR String Lava.lang.String
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.
BSTR All BSTRs are allocated from a COM-managed memory
allocator.
4 0 0 0 ‘H’ 0 ‘i’ 0 ‘i’ 0
 Length Prefix  Character Data  Terminal Null 
“Hi” as BSTR

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.
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
HRESULT CreateChimp( Iape *rpApe ) { As seen in the above example to perform one
extern const CLSID CLSID_Chimp ; operation three sub operations are required i.e.,
rpApe = 0 ; CoGetClassObject, CreateInstance and Release
IClassFactory *pcf = 0 ; operations are called to instantiate a object
HRESULT hr = CoGetClassObject( If the server is in-process server then this is not
CLSID_Chimp,CLSCTX_ALL,0,IID_IClassFactory, a big issue, but if it is a out-process remote
(void **) &pcf ); server then each of these operations will require
if(SUCCEEDED(hr)) { a round trip between the client and the server
hr = pcf->CreateInstance(0, IID_IApe,(void process and therefore is an expensive operation
**)&rpApe ) ; COM provides an API function
pcf ->Release() ; CoCreateInstanceEx that subsumes the
} return hr ; 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
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

Optimizations
CoCreateInstanceEx CoGetClassObject
REFCLSID rclsid REFCLSID rclsid
IUnknown *pUnkOuter DWORD dwClsCtx
DWORD dwClsCtx COSERVERINFO *pc
COSERVERINFO *pc REFIID riid
ULONG cmqi void **ppv
MULTI_QI *prgmqi
CreateInstance
IUnknown *pUnkOuter
prgmqi[0].pIID REFIID riid
prgmqi[0].pItf void **ppv
prgmqi[0].hr
prgmqi[1].pIID QueryInterface
prgmqi[1].pItf REFIID riid
prgmqi[1].hr void **ppv

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.
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

IUnknown 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
ICar Object
type B on the same object must never fail
IPlane
Which means that if QI(A)->B is true, then QI(QI(A)->B)->A
must be true as well

QueryInterface is Transitive
IUnknown
IF QI request for interface B is satisfied through an
interface pointer A and a second QI for interface C is
ICar Object satisfied through the pointer of type B, then a QI request
IPlane for interface C through the original pointer of type A
IBoat must succeed.
Which means that if QI(QI(A->B))->C is true, then
QI(A)->C must be true as well.

QueryInterface is Reflexive
IUnknown
QI request through an interface pointer must always
succeed if the requested type matches the type of pointer
ICar Object
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.
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.
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.
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.
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
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
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.


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,
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.
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.
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
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.
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.
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.
• 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).
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.


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.


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
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.
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
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
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.
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
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.
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.
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.
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
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.
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).
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.
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
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.
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  Database
Server
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.
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 Purpose
Bean Type
Session Performs a task for a client
Represents a business entity object that exists in persistent
Entity
storage
Message- Acts as a listener for the Java Message Service API,
Driven 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.
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;
};
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.

S-ar putea să vă placă și