Teach Yourself CORBA In 14 Days

·

Day 1Getting Familiar with CORBA
The Purpose of This Book
Background: History of Distributed Systems
The Beginning: Monolithic Systems and Mainframes
The Revolution: Client/Server Architecture
The Evolution: Multitier Client/Server
The Next Generation: Distributed Systems
Why CORBA?
Exploring CORBA Alternatives
CORBA History
Introducing the Object Management Group (OMG)
CORBA 1.0
CORBA 2.0 and IIOP
CORBA Architecture Overview
The Object Request Broker (ORB)
Interface Definition Language (IDL)
The CORBA Communications Model
The CORBA Object Model
CORBA Clients and Servers
Stubs and Skeletons
Beyond the Basics: CORBAservices and CORBAfacilities
Summary
Q&A
Workshop
Quiz
The Purpose of This Book
Certainly, this isn’t the first book to be written on the subject of the Common Object Request Broker Architecture (CORBA)–not by a long shot. However, among CORBA books currently on shelves, it might be unique in its approach. At the time this book was written, few, if any, texts were available that covered CORBA at an introductory level. This book attempts to fill that gap.
CORBA is not a subject for the fainthearted, to be sure. Although development tools that hide some of the complexity of CORBA exist, if you embark on a project to develop a reasonably sophisticated CORBA application, chances are that you will experience some of CORBA’s complexities firsthand. However, though there might be a steep learning curve associated with CORBA, a working knowledge of CORBA fundamentals is well within the grasp of any competent programmer.
For the purposes of this book, it is assumed that you already have a good deal of programming experience. CORBA is a language-independent architecture, but because C++ and Java are the principal languages used to develop CORBA applications, it would be preferable if you had experience with one of these languages. (Most of the examples are written in C++, with a healthy dose of Java thrown in for good measure.) It wouldn’t hurt if you were familiar with object-oriented analysis and design concepts either, but just in case you need a refresher, this book will help you review these concepts.
Operating under the assumption that learning CORBA is a surmountable (if daunting) goal for most programmers, this book begins teaching the fundamentals of CORBA, starting with an overview of the architecture. You’ll then move on to a primer on the Interface Definition Language (IDL), a cornerstone on which most CORBA applications are based. After that, you’ll start building CORBA applications, and before you know it, you’ll be exposed to advanced concepts and design issues, along with other useful things such as CORBAservices, CORBAfacilities, and the Dynamic Invocation Interface, or DII (don’t worry–you’ll learn what all this means, in due time). All this–and more–in a mere 14 days.
What this book does not do–indeed, cannot do–is make you a CORBA expert overnight (or even in 14 days, for that matter). It does put you well on your way to mastering CORBA. Keep in mind that CORBA is a complex architecture, full of design issues and tradeoffs as well as implementation nuances. As such, it can only be mastered through experience–something you will gain only by designing and developing CORBA applications. Perhaps this book does not make you an expert in all things CORBA, but it does put you on the right track toward achieving that goal.
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 CORBAservices), common facilities (known as CORBAfacilities), 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 CORBAservices and CORBAfacilities.
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: CORBAservices and CORBAfacilities
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.
Summary
Today you had a very brief overview of the CORBA architecture, along with a history of business application development and where CORBA fits in. You now know what you can expect to get out of this book–you won’t become a CORBA expert overnight, but you will gain valuable exposure to the process of designing and developing CORBA-based applications.
In the next few days, you’ll explore the CORBA architecture in much greater detail, learn more than you ever wanted to know about IDL, and you’ll be well on your way to developing CORBA applications.
Q&A
Q I’m still not very clear on why I would want to use CORBA as opposed to some other method of interprocess communication.A There are a few areas where CORBA really shines. For applications that have various components written in different languages and/or need to run on different platforms, CORBA can make a lot of sense. CORBA takes care of some potentially messy details for you, such as automatically converting (through the marshaling process) number formats between different machines. In addition, CORBA provides an easily understood abstraction of distributed applications, consisting of object-oriented design, an exception model, and other useful concepts. But where CORBA is truly valuable is in applications used throughout an enterprise. CORBA’s many robust features–as well as those provided by the OMA CORBAservices and CORBAfacilities–and especially CORBA’s scalability, make it well suited for enterprise applications.Q What is IDL and why is it useful?
A IDL, or Interface Definition Language, will be covered in greater detail over the next two Days. For now, it is useful to understand that the value in IDL comes from its abstraction of various language, hardware, and operating system architectures. For example, the IDL long type will automatically be translated to the numeric type appropriate for whatever architecture the application is run on. In addition, because IDL is language-independent, it can be used to define interfaces for objects that are implemented in any language.
Workshop
The following section will help you test your comprehension of the material presented today and put what you’ve learned into practice. You’ll find the answers to the quiz in Appendix A. On most days, a few exercises will accompany the quiz; today, because no real “working knowledge” material was presented, there are no exercises.
Quiz
1. What does IIOP stand for and what is its significance?2. What is the relationship between CORBA, OMA, and OMG?3. What is a client stub?4. What is an object reference? An IOR?
Day 2Understanding the CORBA Architecture
Overview
The Object Request Broker (ORB)
Marshaling
Platform Independence
ORB Summary
Interface Definition Language (IDL)
Language Independence
The CORBA Communications Model
Inter-ORB Protocols
CORBA and the Networking Model
The CORBA Object Model
Object Distribution
Object References
Basic Object Adapters (BOAs)
CORBA Clients and Servers
Multiple Personalities? Being Both a Client and a Server
Stubs and Skeletons
Beyond the Basics: CORBAservices and CORBAfacilities
Summary
Q&A
Workshop
Quiz
Overview
On the first day, you learned about CORBA’s history and saw how the CORBA architecture fits into the world of client/server application development. You were also presented with a brief overview of the CORBA architecture. By the end of this Day, you will have a deeper understanding of the CORBA architecture and its components. These are the major aspects covered in this chapter:
The Object Request Broker (ORB), one of the cornerstones of the CORBA architecture
The Interface Definition Language (IDL), the other CORBA architectural cornerstone
The CORBA communications model, how CORBA objects fit within the network architecture
The CORBA object model, including object references and Basic Object Adapters (BOAs)
The definition and roles of clients and servers in the CORBA architecture
The use of client stubs and server skeletons to build CORBA applications
An overview of CORBAservices and CORBAfacilities, which provide additional functionality to CORBA applications
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 clientFigure 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.
Summary
In this chapter, you first discovered the two cornerstones of the CORBA architecture: the Object Request Broker (ORB), which manages the communication of CORBA objects with each other, and the Interface Definition Language (IDL), which defines application component interfaces upon which CORBA applications are built. You explored the CORBA object model, where you learned about inter-ORB protocols (particularly IIOP), CORBA’s use of object references, and the concept of the Basic Object Adapter. You defined the terms client and server in the context of CORBA and saw that a single application component can simultaneously act as both a client and a server. You also saw how IDL definitions create client stubs and server skeletons, which in turn implement CORBA clients and servers. Finally, you were introduced to CORBAservices and CORBAfacilities, which provide additional functionality for CORBA applications.
Now that you have developed an understanding of the overall CORBA architecture, you will move on to the basics of IDL, starting with simple data types and working up to more complex IDL constructs. You will find this knowledge of IDL necessary to design and implement CORBA applications.
Q&A
Q Why would the capability to pass objects by value eliminate the need for many callbacks?A In many cases, a client might only need to pass a simple object to a server method. Because objects cannot be passed by value, the server must use callbacks to the client to manipulate the object (even if it only wants to read the object’s state). If the object can be passed by value, the server can operate on a local copy of the object, eliminating the need for client callbacks. (Of course, in some cases the client will want to retain ownership of the object and will want the server to make callbacks; in such cases, the callback paradigm would be retained.)Q Client stubs seem too restrictive for my application; do I need to use DII?A For an overwhelming majority of applications, if you think DII is necessary, you might want to reconsider. Due to the complexity and overhead of using DII, it is almost always best to avoid it. (See Chapter 11 for more information on when the use of DII might be appropriate.)Q Why are language mappings a necessary part of CORBA?A Because CORBA object interfaces are specified in IDL, which is independent of any implementation language, it is necessary to specify a methodology for converting IDL data types to data types of the implementation language(s) chosen. The language mapping for a particular implementation language describes this methodology. Furthermore, language mappings for many common languages are standardized, meaning that an application written to use one CORBA product can be made to work with a different product with little or no modification (as long as the application uses only features of the standard language mapping).
Workshop
The following section will help you test your comprehension of the material presented today and put what you’ve learned into practice. You’ll find the answers to the quiz in Appendix A. On most days, a few exercises will accompany the quiz; today, because no real “working knowledge” material was presented, there are no exercises.
Quiz
1. Earlier in the chapter, you claimed that the capability to pass objects by value, when it becomes available, will eliminate the need for many callbacks. Why is this true?2. An architect of a CORBA application wants to include two server components in the application. The first component has a single method that simply returns the time of day. The second component, when initialized, performs a lengthy calculation on a large database table; it features a single method that returns the precalculated result. Which server activation policies will the architect want to use for these two components, and why?3. Can you think of a drawback to the use of client stubs in a CORBA client application? (Hint: What potentially useful capability does the Dynamic Invocation Interface (DII) provide?)4. Why are language mappings a necessary part of CORBA?

Enter your email address: