Top Banner
Grosso, [email protected] (C) 1999, all rights re CORBA
101
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

William Grosso, [email protected] (C) 1999, all rights reserved

CORBA

Page 2: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

This LectureCommon Object Request Broker

Architecture (CORBA)Start with Limo example to illustrate

general principles (and IDL syntax)Naming Service

Page 3: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Recall: SocketsStreams-based communication between

any two computers on a networkNo requirement that the both client and

server use Java (language independence)Connection, location, and lifecycle

management written by application programmers

Application programmers must convert data and method calls into and out of stream format (marshalling)

Page 4: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Recall: RMILayer on top of SocketsHas solutions for all the Socket red stuff

Connection management and marshalling is in the stubs

Location management via the registry Lifecycle management via activation

Both client and server must be Java Distributed garbage collection, Can pass (serializable) objects by value

Page 5: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

What is CORBASpecification for distributed object

communications Defined and maintained by the Object

Management Group (www.omg.org) Location transparency and object activation are

fundamental to the specificationLanguage independent and platform

neutralLarge number of extensions (Services and

Facilities) designed by industry working groups

Page 6: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The Object Management GroupIndustry consortiumAt this point, about

800 members Various types of

members;Some voteSome just serve on

task forces

OMG Board

Architecture Board

Task Forces

Page 7: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

History of CORBA1989: OMG founded by 8 members1991: CORBA 1.1

Includes IDL and basic functionality definitions

No real specifications for interoperability1994: CORBA 2.0

Interoperability (GIOP) and the BOA definedCurrently: CORBA 2.4

Minor modifications to 2.0, the definition of the POA, and objects-by-value

Page 8: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Reference Model

Object Request Broker (ORB)

Application Objects

Services

Facilities

Page 9: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Process-Level Schematic

GIOP / IIOP (Wire protocol)

ClientObject

Static Stubs

Dynamic Invocation

Orb Functionality

InterfaceRepository

ImplementationRepository

ServerObject

staticSkeletons

Dyunaic SkeletonInterface

Orb Functionality and Object Adapters

Page 10: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The ORBThe ORB, and the associated object

adapters, define the infrastructure for client-server programming

More conceptual than architectural There is no distinct process you can point to

and say “that’s the orb” It’s a library you link into your code

A client uses an object reference and a method call (in the client language) ORB handles the rest of the networking details

Page 11: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

IIOP ORB IndependenceThe ORB is a message bus that takes

client language message calls and translates them into IIOP invocations

The ORB is a message bus that takes IIOP invocations and translates them into server language method calls

Works across vendors Code can be ported to a different vendor Client and server don’t need to be using

same vendor’s orb

Page 12: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

CORBAServicesIdea: standardize common servers and

design decisionsThese are not things in the environment

(like printers) so much as objects that most developers, across most domains, use

Examples: Naming, Trader, Events, Lifecycle, Transaction, Properties

You can go out and buy an event service and plug it into your orb

Page 13: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

CORBAFacilitiesOriented towards the end-user, rather

than the developerPartially abstractions of standard

environmental features Printing Facility Systems Management Facility

Also contains things like a document model (pretty much OpenDoc) and the Mobile Agent Facility

Page 14: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Interface Definition LanguageRemember-- CORBA wants to be

platform and language independentWhat does this mean ?

You can write a client in one language You can have an already existing server

written in another language CORBA will connect them

The way CORBA achieves this is through IDL

Page 15: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Define Interfaces in IDLRigorously defined language for

specifying an API Method definitions, but no computational

constructsC++ like syntax (and preprocessor)CORBA spec contains a complete

definition of IDL and a set of mappings from IDL to target languages Other groups have proposed additional

mappings

Page 16: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Language Independence ?

Server Interfaces Defined in IDL

Skeleton

StubSkeleton

Stub Stub

Skeleton

Stub

Skeleton

IDL Compilers use mappings togenerate stubs and skeletons in target languages

Page 17: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The CORBA Development CycleWrite IDL definitionsCompile IDL to java

Javasoft has idltojava, Visigenic has idl2java, ...

This will give you stubs and skeletonsWrite the server and client code in JavaUse javac to compile the programs Configure the deployment environment

Page 18: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Recall our Banking ProgramWe had a set of bank account objects,

which could be found by using the owner’s name.

Each object function as a small serverPersistence was handled by a

background threadDeactivation handled by use of

Unreferenced and the activation framework

Page 19: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

BankAccount

public interface BankAccount extends Remote{ public String getOwner() throws RemoteException; public float getBalance() throws RemoteException; public boolean withdrawCash(float amount) throws RemoteException; public boolean depositCash(float amount) throws RemoteException;}

Page 20: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

IDL for a Similar Server

module grosso { module simplebank { exception NegativeAmountException{}; exception OverdraftException { boolean succeeded; }; interface BankAccount{ attribute string owner; readonly attribute float balance; void withdrawCash(in float amount) raises (NegativeAmountException, OverdraftException); void depositCash(in float amount) raises(NegativeAmountException); }; };};

Page 21: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The Structure of IDLAbstract specification languageSyntax derived from C++

C++ style comments All declarations end in semicolons Standard preprocessor commands (#ifdef,

#define, #include, #pragma)Case sensitive but with an exclusionary rule

Two constructs cannot upper-case to the same string

All identifiers start with a letter

Page 22: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Basic Types in IDLData Type Definition Definition[unsigned] short 16 bit, specified via 2’s complement unsigned short trade_balance;

short number_of_legs;[unsigned] long 32 bit, specified via 2’s complement unsigned long height_in_millimeters;

long nanoseconds_until_equinox;[unsigned] long long 64 bit long long atoms_in_universe;float 16 bit, IEEE standard float grade_point_average;double 32 bit, IEEE standard double temperature;long double 64 bit precision long double pi;char ISO Latin-1 character char monogram_initial;wchar Unicode 16 bit representation wchar name_in_swedish_characters

boolean two values: TRUE and FALSE boolean alive;

string variable length sequence of characters string first_name;

wstring variable length sequence of wchars wstring first_name;octet 8 bits, completely uninterpreted octet identifying_bits;enum enumerated type, boils down to named

integersenum color_list {red, blue, green, mauve};

any Generic type, similar to void * with reflectionadded. Can represent any IDL type (basic orconstructed, object or non-object)

any foo;

Page 23: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

StructsDeclared using the keyword structCan contain any other types (including

structs and objects)

struct BugDescription { species bug_species; string first_name; string last_name; unsigned short number_of_legs; unsigned short calories_when_used_as_salad_topping;};

struct Species{ kingdom kingdom; // an enumerated type defined earlier phylum phlya; // an enumerated type defined earlier string formal_name;};

Page 24: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

ExceptionsAlmost exactly like structsAlso define typesCan be passed as arguments or

returned as valuesCan also be raised by methods

enum Rationale { bug_never_existed, bug_escaped, bob_ate_it};

exception BugNotFound{ bug_description the_bug; rationale why_missing;};

Page 25: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Template TypesSequences and arrays are the standard

containers

Usually typedef’d as well (must be typedef’d to be used as argument or return types in a method call)

sequence <type[, max length]> variable_nametype[int][int] variable_name

typedef sequence<Book, 30> BookShelf;typedef Book[30] BookShelf;typedef sequence <Book> UnboundedBookShelf;

typedef LastName string<30>

Page 26: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

TypedefsTypes are frequently aliased and

renamed in IDL.This is especially true for structs and

template types

typedef old_type_name new_type_name;

typedef template_definition new_type_name ;

Page 27: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

AttributesAn attribute is simply shorthand for

declaring an accessor/mutator pair

Nice part of this: exact syntax of accessor/mutator is specified in the language mapping (according to the local idiom)

Attributes can be readonly

attribute string food;attribute long height, width, depth;

readonly attribute string food;

Page 28: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Method CallsGeneral syntax is a little more complex

than in Javadelivery-style return-type method-name

(comma delimited sequence of arguments)raises (comma delimited sequence of exceoptions);

Page 29: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Delivery StyleIf omitted, defaults to synchronous

delivery Has at-most-once semantics Caller blocks until method returns or exception

is thrownCan be specified as oneway

best-effort semantics Cannot have any return values or raise

exceptions Message is sent and client immediately

continues processing

Page 30: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

ArgumentsEvery argument must have a

directional indicator in: this argument is sent to the server, but

need not be sent back out: this argument is, in essence, a return

value inout: this argument is sent to the server.

The server will also send back a value for this argument to assume

Page 31: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

InterfacesInterfaces define Servers.

They define “object” in CORBA Interfaces are like objects that extend

Remote in RMISupport multiple inheritance

interface BankAccount { attribute string owner; readonly attribute float balance; void withdrawCash(in float amount)

raises (NegativeAmountException, OverdraftException); void depositCash(in float amount) raises(NegativeAmountException); };

Page 32: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

ModulesA module is a grouping mechanism,

much like a package in JavaModules can contain other modulesScoping of references is done with

the :: operator containing-module::inner-

module::interface

Page 33: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Event Channel IDL// CosEventComm.idl

#pragma prefix "omg.org"

module CosEventComm { exception Disconnected {}; interface PushConsumer { void push(in any data) raises(Disconnected); void disconnect_push_consumer(); }; interface PushSupplier { void disconnect_push_supplier(); }; interface PullSupplier { any pull() raises(Disconnected); any try_pull(out boolean has_event) raises(Disconnected); void disconnect_pull_supplier(); }; interface PullConsumer { void disconnect_pull_consumer(); };};

Page 34: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Event Channel IDL II// CosEventChannelAdmin.idl

#include "CosEventComm.idl"

#pragma prefix "omg.org"

module CosEventChannelAdmin {

exception AlreadyConnected {}; exception TypeError {}; interface ProxyPushConsumer : CosEventComm::PushConsumer { void connect_push_supplier(in CosEventComm::PushSupplier push_supplier) raises(AlreadyConnected); }; interface ProxyPullSupplier : CosEventComm::PullSupplier { void connect_pull_consumer(in CosEventComm::PullConsumer pull_consumer) raises(AlreadyConnected); }; interface ProxyPullConsumer : CosEventComm::PullConsumer { void connect_pull_supplier(in CosEventComm::PullSupplier pull_supplier) raises(AlreadyConnected); }; interface ProxyPushSupplier : CosEventComm::PushSupplier { void connect_push_consumer(in CosEventComm::PushConsumer push_consumer) raises(AlreadyConnected); };

Page 35: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Event Channel IDL IIIinterface ConsumerAdmin { ProxyPushSupplier obtain_push_supplier(); ProxyPullSupplier obtain_pull_supplier(); };

interface SupplierAdmin { ProxyPushConsumer obtain_push_consumer(); ProxyPullConsumer obtain_pull_consumer(); };

interface EventChannel { ConsumerAdmin for_consumers(); SupplierAdmin for_suppliers(); void destroy(); };

interface EventChannelFactory {

exception AlreadyExists {}; exception ChannelsExist {}; EventChannel create(); EventChannel create_by_name(in string name) raises(AlreadyExists); EventChannel lookup_by_name(in string name); void destroy() raises(ChannelsExist);

};};

Page 36: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Limos Revisited

Remote

RemoteObject

UnicastRemoteObject Dispatcher Limo

DispatcherImpl LimoImpl

DriverLocationPassenger

Serializable

RemoteServer

Page 37: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Limo in IDLmodule grosso{ module corbalimo{ struct Location { short x; short y; }; struct Passenger{ Location starting_location; Location destination; }; struct Driver{ string name; };

interface Limo; // Forward declaration to break compiler // circularity

interface Dispatcher{ Limo hailLimo(in Passenger new_passenger); void limoAvailable(in Limo limo); void limoUnavailable(in Limo limo); };

Page 38: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Limo in IDL

//....

interface Limo { attribute Dispatcher current_ispatcher; readonly attribute Location current_location; readonly attribute Driver current_driver; boolean getIsCarryingPassenger(out Passenger current_passenger);

/* multiple return values */ boolean wantPassenger(in Passenger possible_passenger); boolean pickupPassenger(in Passenger new_passenger); }; };};

Page 39: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The CORBA Development CycleWrite IDL definitionsCompile IDL to java

Javasoft has idltojava, Visigenic has idl2java, ...

This will give you stubs and skeletonsWrite the server and client code in JavaUse javac to compile the programs Configure the deployment environment

Page 40: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Break Time

Page 41: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Compiling is SimpleORB vendors are required to provide

an IDL to Java compiler that implements the standard mapping Input: IDL Output: Java source code

Warning: vendors frequently implement other mappings as well

idl2java BankAccount.idl -strict -portable -VBJvmflag ”-Xbootclasspath:%CLASSPATH_WITHOUTINTERBASE%"

idltojava -fno-cpp -ftie limo.idl

Page 42: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The Mapping is more Complicated

Page 43: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Conceptual Mappings

IDL Concept Java Concept Discussionmodule package Modules inside other modules map to

subpackagesexception class which extends

org.omg.CORBA.UserExceptionMust be caught in client code

in argument ordinary java argumentout argument “holder” class, related to the type declared in

the IDLOut, and inout, arguments are impossible todirectly handle in Java. Instead, we use awrapper class whose value can be set.

attributes reader/writer methods These, alas, do not conform to beans names.Instead, they simple overload the attributesname.

Page 44: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Mapping Basic Types

IDL Basic Type Java Type Discussion[unsigned] short short[unsigned] long int

[unsigned] long long longfloat floatdouble doublelong double NONE YET As the spec evolves, this will probably map

to java.math.BigDecimalchar charwchar char

boolean boolean

string java.lang.Stringwstring java.lang.Stringoctet byteany the Java class org.omg.CORBA.Any

Page 45: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Mapping Constructed Types

IDL Constructed Type Java Type Discussionsequence array Not to Collections classes at all. But simply

to arrays. This preserves strong typing, but issomewhat foreign to Java.

array array Not to Collections classes at all. But simplyto arrays. This preserves strong typing, but issomewhat foreign to Java.

struct A Java class in the appropriate package Actually, three classes are defined for structsand enums. Namely, the base class, a helperclass, and a holder class.

enum A Java class in the appropriate package andwith the same name as the enumerated type

typedef Automatically translated to original nameinterface An interface in the appropriate package. Also has a helper and a holder.

Page 46: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

HoldersProblem: out, and inout, arguments do

not correspond to anything in the java language

Solution: Wrap the value in a holder class which can read and write the argument to a stream

Method calls which have out, or inout, arguments take a holder class instead of the original type Additional complexity for client side developer

Page 47: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

public interface Limo extends org.omg.CORBA.Object { public void current_ispatcher(grosso.corbalimo.Dispatcher current_ispatcher); public grosso.corbalimo.Dispatcher current_ispatcher(); public grosso.corbalimo.Location current_location(); public grosso.corbalimo.Driver current_driver(); public boolean getIsCarryingPassenger(grosso.corbalimo.PassengerHolder

current_passenger ); public boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger); public boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger );}

Holders in Limo interface Limo { attribute Dispatcher current_ispatcher; readonly attribute Location current_location; readonly attribute Driver current_driver; boolean getIsCarryingPassenger(out Passenger current_passenger);

/* multiple return values */ boolean wantPassenger(in Passenger possible_passenger); boolean pickupPassenger(in Passenger new_passenger); };

becomes

Page 48: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

PassengerHolderpackage grosso.corbalimo; final public class PassengerHolder implements org.omg.CORBA.portable.Streamable { public grosso.corbalimo.Passenger value; public PassengerHolder() { } public PassengerHolder(grosso.corbalimo.Passenger value) { this.value = value; } public void _read(org.omg.CORBA.portable.InputStream input) { value = grosso.corbalimo.PassengerHelper.read(input); } public void _write(org.omg.CORBA.portable.OutputStream output) { grosso.corbalimo.PassengerHelper.write(output, value); } public org.omg.CORBA.TypeCode _type() { return grosso.corbalimo.PassengerHelper.type(); }}

Page 49: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

AnyGeneric type, similar to void * with

reflection added. Can represent any IDL type (basic or constructed, object or non-object)

Used in IDL as a typeCorresponds to org.omg.CORBA.Any

Page 50: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Any Methodsboolean equal(Any a) ;

Any extract_any() ;boolean extract_boolean(); char extract_char() ;char extract_wchar(); String extract_string(); String extract_wstring(); BigDecimal extract_fixed(); double extract_double(); float extract_float() ;short extract_short() ; short extract_ushort(); int extract_long(); int extract_ulong(); long extract_longlong(); long extract_ulonglong(); Object extract_Object(); byte extract_octet(); TypeCode extract_TypeCode(); TypeCode type() ;void type(TypeCode t);

insert_any(Any a); insert_boolean(boolean b); insert_char(char c) ;insert_wchar(char c); insert_string(String s); insert_wstring(String s); insert_fixed(BigDecimal bD); insert_double(double d); insert_float(float f); insert_short(short s); insert_ushort(short s); insert_long(long l) ;insert_ulong(long l); long insert_longlong(long l); insert_ulonglong(long l) ;insert_Object(Object o); insert_Object(Object o, TypeCode t);insert_octet(byte b);

Page 51: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

HelpersEvery constructed type has an

associated Helper class as wellHelpers extend the CORBA type system

to deal with your object definitionsThey have static methods to

Insert and extract instances from an Any Get typecodes Perform narrowing (down-casting)

operations

Page 52: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Helpers and NarrowingInterfaces in IDL have an inheritance

hierarchyJava is a single (implementation)

inheritance languageSuppose FastLimo was a sub-class of

Limo in our IDL

Page 53: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The FastLimo Hierarchy

_LimoImplBase

org.omg.CORBA.DynamicImplementation

_LimoStub

Limo

_LimoOperations

_LimoTie

org.omg.CORBA.Object

FastLimo

_FastLimoImplBase_FastLimoStub

_FastLimoOperations

_FastLimoTie

Page 54: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Back to our Generated Files

Page 55: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Interfaces in IDL compile into 7 different objects

Limo compiles into_LimoImplBase_LimoOperations_LimoTie_LimoStubLimoLimoHelperLimorHolder

Servers

_LimoImplBase

org.omg.CORBA.DynamicImplementation

_LimoStub

Limo

LimoHelper

LimoHolder

_LimoOperations_LimoTie

org.omg.CORBA.Object

Page 56: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Ties versus BasesServers can be built by inheriting from

an abstract superclass which knows about IIOP and how to send messages / marshall data over the wire _xxxImplBase has a set of template

methods that you can implement in a subclass in order to build a server

You can also build them by aggregating out the “real server functionality” to a servant class.

Page 57: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Base Approachpublic abstract class _LimoImplBase extends org.omg.CORBA.DynamicImplementation

implements grosso.corbalimo.Limo { // Constructor public _LimoImplBase() { super(); } // Type strings for this class and its superclases private static final String _type_ids[] = { "IDL:grosso/corbalimo/Limo:1.0" };

public String[] _ids() { return (String[]) _type_ids.clone(); }

private static java.util.Dictionary _methods = new java.util.Hashtable(); static { _methods.put("_get_current_dispatcher", new java.lang.Integer(0)); _methods.put("_set_current_dispatcher", new java.lang.Integer(1)); _methods.put("_get_current_location", new java.lang.Integer(2)); _methods.put("_get_current_driver", new java.lang.Integer(3)); _methods.put("getIsCarryingPassenger", new java.lang.Integer(4)); _methods.put("wantPassenger", new java.lang.Integer(5)); _methods.put("pickupPassenger", new java.lang.Integer(6)); }

Page 58: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Base Approach IIpublic void invoke(org.omg.CORBA.ServerRequest r) { switch (((java.lang.Integer) _methods.get(r.op_name())).intValue()) { case 0: // grosso.corbalimo.Limo.current_dispatcher { org.omg.CORBA.NVList _list = _orb().create_list(0); r.params(_list); grosso.corbalimo.Dispatcher ___result = this.current_dispatcher(); org.omg.CORBA.Any __result = _orb().create_any(); grosso.corbalimo.DispatcherHelper.insert(__result, ___result); r.result(__result); } break; case 1: // grosso.corbalimo.Limo.current_dispatcher { org.omg.CORBA.NVList _list = _orb().create_list(0); org.omg.CORBA.Any _arg = _orb().create_any(); _arg.type(grosso.corbalimo.DispatcherHelper.type()); _list.add_value("arg", _arg, org.omg.CORBA.ARG_IN.value); r.params(_list); grosso.corbalimo.Dispatcher arg; arg = grosso.corbalimo.DispatcherHelper.extract(_arg); this.current_dispatcher(arg); org.omg.CORBA.Any a = _orb().create_any(); a.type(_orb().get_primitive_tc(org.omg.CORBA.TCKind.tk_void)); r.result(a); } break;

Page 59: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Base Approach IIIcase 2: // grosso.corbalimo.Limo.current_location { org.omg.CORBA.NVList _list = _orb().create_list(0); r.params(_list); grosso.corbalimo.Location ___result = this.current_location(); org.omg.CORBA.Any __result = _orb().create_any(); grosso.corbalimo.LocationHelper.insert(__result, ___result); r.result(__result); } break; case 3: // grosso.corbalimo.Limo.current_driver { org.omg.CORBA.NVList _list = _orb().create_list(0); r.params(_list); grosso.corbalimo.Driver ___result = this.current_driver(); org.omg.CORBA.Any __result = _orb().create_any(); grosso.corbalimo.DriverHelper.insert(__result, ___result); r.result(__result); } break;

// and so on ...

Page 60: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Tie Approachpackage grosso.corbalimo;public class _LimoTie extends grosso.corbalimo._LimoImplBase { public grosso.corbalimo._LimoOperations servant; public _LimoTie(grosso.corbalimo._LimoOperations servant) { this.servant = servant; } public grosso.corbalimo.Dispatcher current_dispatcher() { return servant.current_dispatcher(); } public void current_dispatcher(grosso.corbalimo.Dispatcher arg) { servant.current_dispatcher(arg); } public grosso.corbalimo.Location current_location() { return servant.current_location(); } public grosso.corbalimo.Driver current_driver() { return servant.current_driver(); } // and so on ... }

Page 61: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The Operations Class_LimoOperations still unexplainedBasically, the Limo interface without

any extra funcitonality Unlike Limo, which inherits from

org.omg.CORBA.Object

package grosso.corbalimo;public interface _LimoOperations { grosso.corbalimo.Dispatcher current_dispatcher(); void current_dispatcher(grosso.corbalimo.Dispatcher arg); grosso.corbalimo.Location current_location(); grosso.corbalimo.Driver current_driver(); boolean getIsCarryingPassenger(grosso.corbalimo.PassengerHolder current_passenger); boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger); boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger);}

Page 62: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Fundamental TruthThe code we just went through did three

things: The client connected to the server The client sent a request The client got a response

All methods for distributed programming, at their core, must handle these three things.

The way to understand an architecture is to make the above sequence into questions

Page 63: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The CORBA Development CycleWrite IDL definitionsCompile IDL to java

Javasoft has idltojava, Visigenic has idl2java, ...

This will give you stubs and skeletonsWrite the server and client code in JavaUse javac to compile the programs Configure the deployment environment

Page 64: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Break Time

Page 65: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

SimpleClient GUI is the Same

Page 66: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Most SimpleClient code is identical too

private class ButtonAction implements ActionListener{ public void actionPerformed(ActionEvent e){ try{ Dispatcher dispatcher = CorbaLimoProperties.getDispatcher(); Limo limo = dispatcher.hailLimo(getPassenger()); if (null!=limo){ Driver driver = limo.current_driver(); _reportsBack.append("Limo is driven by " + driver.name +"\n"); } else{ _reportsBack.append("No limos available \n"); } } catch (Exception ee){} }

90% of the code is identical to the RMI code

Only difference is in the Button’s listener

Page 67: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

CorbaLimoPropertiespublic class CorbaLimoProperties { private static Properties _properties; public static Properties getProperties() { if (null==_properties) { _properties = new Properties(); _properties.put("org.omg.CORBA.ORBInitialPort", "3500"); _properties.put("org.omg.CORBA.ORBInitialHost", "localhost"); _properties.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); } return _properties; } public static Dispatcher getDispatcher(){ try{ Properties properties = CorbaLimoProperties.getProperties(); ORB orb = ORB.init((String[]) null, properties); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext nameServer = NamingContextHelper.narrow(objRef); NameComponent ourComponent = new NameComponent("Dispatcher", ""); NameComponent path[] = {ourComponent}; org.omg.CORBA.Object dispatcherRef = nameServer.resolve(path); return DispatcherHelper.narrow(dispatcherRef); } catch (Exception e){ e.printStackTrace(); } return null; }}

Page 68: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Properties used by JavaIDLJavaIDL is the free CORBA

implementation Supplied by Javasoft Not really intended for industrial-strength

use (no real support for servers or object adapters)

4 properties can be set

Property Defined by Purposeorg.omg.CORBA.ORBClass OMG Name of a java class which implements

org.omg.CORBA.ORB. Instances of this arecreated in response toorg.omg.CORBA.ORB.init(....)

org.omg.CORBA.ORBSingletonClass OMG Also the name of a java class which implements ....This one is used to respond toorg.omg.CORBA.ORB.init() [no arguments to init].In essence, it provides some ORB functionalitywithout actually having a network presence

org.omg.CORBA.ORBInitialHost SUN Machine running tnameserv (defaults to localhost)org.omg.CORBA.ORBInitialPort SUN Port that tnameserv is listening on (defaults to 900)

Page 69: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Using Inheritance to build ServersWe’re going to separate out the

launchers from the servers again (just like in the RMI case)

We’ll build Limo_Inheritance as a subclass of _LimoBaseImpl

We’ll build Dispatcher_Inheritance as a subclass of _DispatcherBaseImpl

Page 70: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Limo_Inheritancepublic class Limo_Inheritance extends _LimoImplBase { private boolean _havePassenger; private Dispatcher _dispatcher; private Location _currentLocation; private Driver _driver; private Passenger _passenger; public Limo_Inheritance (Dispatcher dispatcher, Driver driver) { _havePassenger = false; _dispatcher = dispatcher; _driver = driver; dispatcher.limoAvailable(this); } public grosso.corbalimo.Dispatcher current_dispatcher() { return _dispatcher; }

Page 71: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Limo_Inheritance II

public void current_dispatcher(grosso.corbalimo.Dispatcher arg) { if ((false==_havePassenger) &&(null!=_dispatcher)) { _dispatcher.limoUnavailable(this); if(null!=arg) { arg.limoAvailable(this); } } _dispatcher = arg; }

public grosso.corbalimo.Location current_location() { return _currentLocation; }

public grosso.corbalimo.Driver current_driver(){ return _driver; }

Page 72: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Limo_Inheritance III public boolean getIsCarryingPassenger(grosso.corbalimo.PassengerHolder current_passenger){ if (null!=_passenger) { current_passenger.value = _passenger; // using a Holder class } return _havePassenger; }

public boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger) { return (false ==_havePassenger); // a very simple model of // cabbie decision making }

public boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger) { if (true==_havePassenger) { return false; } _dispatcher.limoUnavailable(this); _passenger = new_passenger; _currentLocation=new_passenger.destination;// in theory we'd drive around for a while now _passenger=null; _dispatcher.limoAvailable(this); return true; }}

Page 73: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Dispatcher_Inheritance public class Dispatcher_Inheritance extends _DispatcherImplBase { private ArrayList _availableLimos;

public Dispatcher_Inheritance () { _availableLimos= new ArrayList(); }

public grosso.corbalimo.Limo hailLimo(grosso.corbalimo.Passenger new_passenger) { Collections.shuffle(_availableLimos); Iterator i = _availableLimos.iterator(); while(i.hasNext()) { Limo limo = (Limo) i.next(); if (limo.pickupPassenger(new_passenger)){ return limo; } } return null; } public void limoAvailable(grosso.corbalimo.Limo limo) { if (false==_availableLimos.contains(limo)) { _availableLimos.add(limo); } }

Page 74: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Dispatcher_Inheritance II

public void limoUnavailable(grosso.corbalimo.Limo limo) { _availableLimos.remove(limo); }}

Page 75: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

public class Launcher_Dispatcher { public static void main(String[] args) { try { Properties properties = CorbaLimoProperties.getProperties(); ORB orb = ORB.init(args, properties); Dispatcher_Inheritance dispatcher = new Dispatcher_Inheritance(); orb.connect(dispatcher); // This is pretty much a JavaIDL hack

// JavaIDL doesn't really support servers well org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext nameServer = NamingContextHelper.narrow(objRef); NameComponent ourComponent = new NameComponent("Dispatcher", ""); NameComponent path[] = {ourComponent}; nameServer.rebind(path, dispatcher); (new SelfCleaningFrame("Dispatcher Server")).show(); //hack to keep JVM alive

//because JavaIDL uses Daemon threads } catch (Exception e){ e.printStackTrace(); } }}

Launcher_Dispatcher

Page 76: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Launcher_Limospublic class Launcher_Limos { public static void main(String[] args) {// In reality, we'd probably do something a little cleverer // here (use more command line args or use a factory server)

try {// first we find the dispatcher Dispatcher dispatcher = CorbaLimoProperties.getDispatcher(); for (int currentTaxiDriver=0; currentTaxiDriver < args.length;

currentTaxiDriver++) { Driver driver = new Driver(args[currentTaxiDriver]); Limo currentLimo = new Limo_Inheritance(dispatcher, driver); } (new SelfCleaningFrame("Limos Server")).show(); //hack to keep JVM alive

//because JavaIDL uses daemon threads

} catch (Exception e){ e.printStackTrace(); } }}

Page 77: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Running the ApplicationLaunch the

nameserverLaunch the

dispatcherLaunch the limos

Run the client

start java grosso.corbalimo.Launcher_Dispatcher

start tnameserv -ORBInitialPort 3500

start java grosso.corbalimo.Launcher_Limos Bob Fred Alice

java grosso.corbalimo.SimpleClient.java

Page 78: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Infrastructure in CORBAThe org.omg.CORBA.ORB class provides

basic infrastructure for object management Creation of CORBA types Stringifying and destringifying object references

All xxxBaseImpl objects implement org.omg.CORBA.Object Extra methods that can be called on the object

reference (but which are handled locally)Defined using pseudo-idl (the //PIDL

comment)

Page 79: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

org.omg.CORBA.ORB

As usual, defined in IDLLots of functionality (cf: Chapter 4 of

the CORBA spec)interface ORB { string object_to_string(in Object obj); Objecxt string_to_object(in string str);

//....

The ORB object is the interface to those functions which do not depend on which object adapter is used. These operations are the same for all ORBs and all object implementations and can be performed either by clients of the objects or by implementations

Page 80: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Stringifying ReferencesThe ORB provides basic object

management functionalityOne important piece of functionality is

stringifying object references Any CORBA object reference may be stringified The string can be converted back to an object

reference String format defined by OMG, encodes all the

information needed to connect to serverEnables bootstrapping of systems

Page 81: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Useful ORB FunctionalityString[] list_initial_services()

Object resolve_initial_references(String object_name)

String object_to_string(Object obj)

Object string_to_object(String str)

shutdown(boolean wait_for_completion)

Lists the CORBAServices that are available

Takes a canonical name (returned from list_initial_services or known in advance) and returns an object reference

Stringifies an object reference

Destringifies an object reference

Shuts the ORB down. Rarely called on the client side

Page 82: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

org.omg.CORBA.ObjectObject _duplicate() boolean _non_existent() void _release()

Request _create_request(Context ctx, String operation, NVList arg_list, NamedValue result) Request _create_request(Context ctx, String operation, NVList arg_list, NamedValue result, ExceptionList exclist,

ContextList ctxlist) Request _request(String operation)

DomainManager[] _get_domain_managers()

Object _get_interface_def() boolean _is_a(String repositoryIdentifier) boolean _is_equivalent(Object other) int _hash(int maximum)

Object _set_policy_override(Policy[] policies, SetOverrideType set_add) Policy _get_policy(int policy_type)

Page 83: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Example use of Requestspublic class _LimoStub extends org.omg.CORBA.portable.ObjectImpl implements grosso.corbalimo.Limo {

//...

// IDL operations // Implementation of attribute ::current_dispatcher public grosso.corbalimo.Dispatcher current_dispatcher() { org.omg.CORBA.Request r = _request("_get_current_dispatcher"); r.set_return_type(grosso.corbalimo.DispatcherHelper.type()); r.invoke(); grosso.corbalimo.Dispatcher __result; __result = grosso.corbalimo.DispatcherHelper.extract(r.return_value()); return __result; } public void current_dispatcher(grosso.corbalimo.Dispatcher arg) { org.omg.CORBA.Request r = _request("_set_current_dispatcher"); org.omg.CORBA.Any _current_dispatcher = r.add_in_arg(); grosso.corbalimo.DispatcherHelper.insert(_current_dispatcher, arg); r.invoke(); }

Page 84: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

More _LimoStub // Implementation of ::grosso::corbalimo::Limo::wantPassenger public boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger) { org.omg.CORBA.Request r = _request("wantPassenger"); r.set_return_type(org.omg.CORBA.ORB.init().get_primitive_tc(org.omg.CORBA.TCKind.tk_boolean)); org.omg.CORBA.Any _possible_passenger = r.add_in_arg(); grosso.corbalimo.PassengerHelper.insert(_possible_passenger, possible_passenger); r.invoke(); boolean __result; __result = r.return_value().extract_boolean(); return __result; } // Implementation of ::grosso::corbalimo::Limo::pickupPassenger public boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger) { org.omg.CORBA.Request r = _request("pickupPassenger"); r.set_return_type(org.omg.CORBA.ORB.init().get_primitive_tc(org.omg.CORBA.TCKind.tk_boolean)); org.omg.CORBA.Any _new_passenger = r.add_in_arg(); grosso.corbalimo.PassengerHelper.insert(_new_passenger, new_passenger); r.invoke(); boolean __result; __result = r.return_value().extract_boolean(); return __result; }

Page 85: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Servers in JavaIDLAll the above code is generic (either

works or can easily be modifed to work with any CORBA 2.x ORB)

But there’s a remarkably large and unspecified piece in the middle of it What is the following code really doing ?

Dispatcher dispatcher = CorbaLimoProperties.getDispatcher(); for (int currentTaxiDriver=0; currentTaxiDriver < args.length;

currentTaxiDriver++) { Driver driver = new Driver(args[currentTaxiDriver]); Limo currentLimo = new Limo_Inheritance(dispatcher, driver); }

Page 86: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Real Questions ?It’s clearly creating a bunch of server

objectsThey’re probably in a single JVM

Probably in the same JVM as the code that creates them

How many sockets have been allocated ?How many threads are listening at the

sockets ?What’s the request handling policy ?

Page 87: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Object AdaptersRecall our previous (from slide 10) picture:

The Object Adapter is a server-side layer, living between the skeletons and the ORB, that helps to answer these questions.

GIOP / IIOP (Wire protocol)

ServerObject

staticSkeletons

Dyunaic SkeletonInterface

Orb Functionality and Object Adapters

Page 88: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Common Threading PoliciesThread-per-request

Thread-per-client

General thread pool

Spawns a new thread for each incoming request

A different thread is used for each client connection.

Has a single thread pool for all the client requests that come in

Page 89: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

This decision is made in the Object AdapterThe Object Adapter is a layer between

the ORB and the skeletons. ORB does “generic CORBA stuff” like

unmarshalling parameters and passes the method call along to the Object Adapter

Object Adapter does “server-side specific” stuff and then passes the request along to the skeletonsSo it has a chance to check security, or spawn

a thread or ....

Page 90: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The State of Object AdaptersJavaIDL doesn’t provide an

implementationThe OMG has specified two different

Object Adapters BOA: Basic Object Adapter.

Every commercial vendor has this right now

POA: Portable Object Adapter. Basically, the next generation of BOA

• Fixes some loopholes in the spec • Includes support for common server-side idioms and

activation

Page 91: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

The Naming ServiceDefined as “white pages” for object

systems If you know the name, you can contact the

server Supports notion of tree-like directory structures

Runs as a server, with an IDL specification If you have the object reference, you can talk to

any vendor’s Naming ServiceFinding a naming service can be vendor

specific

Page 92: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Finding the Naming ServiceOne way to find the Naming Service is

to have a pointer to it already Stringified IIOR can be very useful for this

Getting an original reference to a naming service is more problematic You use the reserved name and hope that

the ORB can find it

org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

Page 93: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

How ORB finds Naming Service is vendor specificRecall CorbaLimoProperties if (null==_properties) { _properties = new Properties(); _properties.put("org.omg.CORBA.ORBInitialPort", "3500"); _properties.put("org.omg.CORBA.ORBInitialHost", "localhost"); _properties.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); } return _properties; }

public static Dispatcher getDispatcher() { try { Properties properties = CorbaLimoProperties.getProperties(); ORB orb = ORB.init((String[]) null, properties); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

Sun specific

OMG defined

Page 94: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

IDL for the Naming Service#pragma prefix "omg.org"

module CosNaming {

typedef string Istring; struct NameComponent { Istring id; Istring kind; }; typedef sequence<NameComponent> Name;

enum BindingType { nobject, ncontext }; struct Binding { Name binding_name; BindingType binding_type; }; typedef sequence<Binding> BindingList;

interface BindingIterator; // forward declaration

Page 95: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Naming Service IDL (NamingContext Interface)

interface NamingContext {

enum NotFoundReason { missing_node, not_context, not_object }; exception NotFound { NotFoundReason why; Name rest_of_name; }; exception CannotProceed { NamingContext cxt; Name rest_of_name; }; exception InvalidName {}; exception AlreadyBound {}; exception NotEmpty {};

void bind(in Name n, in Object obj) raises(NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind(in Name n, in Object obj) raises(NotFound, CannotProceed, InvalidName); void bind_context(in Name n, in NamingContext nc) raises(NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind_context(in Name n, in NamingContext nc) raises(NotFound, CannotProceed, InvalidName); Object resolve(in Name n) raises(NotFound, CannotProceed, InvalidName); void unbind(in Name n) raises(NotFound, CannotProceed, InvalidName); NamingContext new_context(); NamingContext bind_new_context(in Name n) raises(NotFound, CannotProceed, InvalidName, AlreadyBound); void destroy() raises(NotEmpty); void list(in unsigned long how_many, out BindingList bl, out BindingIterator bi);};

Page 96: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

org.omg.COSNamingpublic interface NamingContext { public void bind_context(NameComponent[] n, NamingContext nc) ; public NamingContext bind_new_context(NameComponent[] n) ; public void bind(NameComponent[] n, Object obj); public void destroy() ; public void list(int how_many, BindingListHolder bl, BindingIteratorHolder bi); public NamingContext new_context() ; public void rebind_context(NameComponent[] n, NamingContext nc); public void rebind(NameComponent[] n, Object obj) ; public Object resolve(NameComponent[] n) ; public void unbind(NameComponent[] n);}

public class NameComponent { public String id public String kind public NameComponent() public NameComponent(String __id, String __kind) }

Page 97: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

Naming Service IDL III interface BindingIterator { boolean next_one(out Binding b); boolean next_n(in unsigned long how_many,

out BindingList b); void destroy(); };

interface NamingContextFactory { NamingContext create_context(); oneway void shutdown(); };

// The Extended factory contains a root context which allows // clients to bootstrap to a particular factory through // resolve_initial_references()

interface ExtendedNamingContextFactory : NamingContextFactory { NamingContext root_context(); };

Page 98: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

org.omg.COSNaming in UML

Binding

BindingHelper

BindingHolder

BindingIteratorHelper

BindingIteratorHolder

BindingTypeHelper

BindingTypeHolder

NameComponent

NameComponentHelper

NameComponentHolderNamingContextHelper

NamingContextHolder

BindingIterator

NamingContext

BindingType

IDLEntity

Interface

_BindingIteratorImplBase

_BindingIteratorStub

_NamingContextImplBase

_NamingContextStub

org.omg.CORBA.portable.ObjectImpl.

Page 99: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

ReferencesHenning and Vinoski, Advanced CORBA

Programming with C++ (Addison Wesley) A Great Book. Period. Of the 1,000 pages, 400 are C++ specific. The

rest constitute the best possible 600 page overview of the CORBA standard

Vogel and Duddy, Java Programming with CORBA (Wiley) A good book; we’ve covered most of it though. Java specific

Page 100: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.

HomeworkChange the limo example so that the

limos launch first and insert themselves into the naming service (under the NamingContext “Limos”)

When the dispatcher is launched, it finds all the limos and calls current_dispatcher on them (with itself as argument)

From then on, the application is identical

Page 101: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA.