Note: This section contains excerpts from the POA specification.
This chapter describes the Portable Object Adapter, or POA. It presents the design goals, a description of the abstract model of the POA and its interfaces, followed by a detailed description of the interfaces themselves.
The POA is designed to meet the following goals:
Allow programmers to construct object implementations that are portable between different ORB products.
Provide support for objects with persistent identities. More precisely, the POA is designed to allow programmers to build object implementations that can provide consistent service for objects whose lifetimes (from the perspective of a client holding a reference for such an object) span multiple server lifetimes.
Provide support for transparent activation of objects.
Allow a single servant to support multiple object identities simultaneously.
Allow multiple distinct instances of the POA to exist in a server.
Provide support for transient objects with minimal programming effort and overhead.
Provide support for implicit activation of servants with POA-allocated Object Ids.
Allow object implementations to be maximally responsible for an object's behavior. Specifically, an implementation can control an object's behavior by establishing the datum that defines an object's identity, determining the relationship between the object's identity and the object's state, managing the storage and retrieval of the object's state, providing the code that will be executed in response to requests, and determining whether or not the object exists at any point in time.
Avoid requiring the ORB to maintain persistent state describing individual objects, their identities, where their state is stored, whether certain identity values have been previously used or not, whether an object has ceased to exist or not, and so on.
Provide an extensible mechanism for associating policy information with objects implemented in the POA.
Allow programmers to construct object implementations that inherit from static skeleton classes, generated by OMG IDL compilers, or a DSI implementation.
The POA interfaces described in this chapter imply a particular abstract computational model. This section presents that model and defines terminology and basic concepts that will be used in subsequent sections.
This section provides the rationale for the POA design, describes some of its intended uses, and provides a background for understanding the interface descriptions.
The abstract model supported by the POA has the following components:
Client A client is a computational context that makes requests on an object through one of its references.
Server A server is a computational context in which the implementation of an object exists. Generally, a server corresponds to a process. Note that client and server are roles that programs play with respect to a given object. A program that is a client for one object may be the server for another. The same process may be both client and server for a single object.
Object In this discussion, we use object to indicate a CORBA object in the abstract sense, that is, a programming entity with an identity, an interface, and an implementation. From a client's perspective, the object's identity is encapsulated in the object's reference. This specification defines the server's view of object identity, which is explicitly managed by object implementations through the POA interface.
Servant A servant is a programming language object or entity that implements requests on one or more objects. Servants generally exist within the context of a server process. Requests made on an object's references are mediated by the ORB and transformed into invocations on a particular servant. In the course of an object's lifetime it may be associated with (that is, requests on its references will be targeted at) multiple servants.
Object Id An Object Id is a value that is used by the POA and by the user-supplied implementation to identify a particular abstract CORBA object. Object Id values may be assigned and managed by the POA, or they may be assigned and managed by the implementation. Object Id values are hidden from clients, encapsulated by references. Object Ids have no standard form; they are managed by the POA as uninterpreted octet sequences.
Object Reference An object reference in this model is the same as in the CORBA object model. This model implies, however, that a reference specifically encapsulates an Object Id and a POA identity.
POA A POA is an identifiable entity within the context of a server. Each POA provides a namespace for Object Ids and a namespace for other (nested or child) POAs. Policies associated with a POA describe characteristics of the objects implemented in that POA. Nested POAs form a hierarchical name space for objects within a server.
Policy A Policy is an object associated with a POA by an application in order to specify a characteristic shared by the objects implemented in that POA. This specification defines policies controlling the POA's threading model as well as a variety of other options related to the management of objects. Other specifications may define other policies that affect how an ORB processes requests on objects implemented in the POA.
POA Manager A POA manager is an object that encapsulates the processing state of one or more POAs. Using operations on a POA manager, the developer can cause requests for the associated POAs to be queued or discarded. The developer can also use the POA manager to deactivate the POAs.
Servant Manager A servant manager is an object that the application developer can associate with a POA. The ORB will invoke operations on servant managers to activate servants on demand, and to deactivate servants. Servant managers are responsible for managing the association of an object (as characterized by its Object Id value) with a particular servant, and for determining whether an object exists or not. There are two kinds of servant managers, called ServantActivator and ServantLocator; the type used in a particular situation depends on policies in the POA.
Adapter Activator An adapter activator is an object that the application developer can associate with a POA. The ORB will invoke an operation on an adapter activator when a request is received for a child POA that does not currently exist. The adapter activator can then create the required POA on demand.
This section describes the architecture of the abstract model implied by the POA, and the interactions between various components. The ORB is an abstraction visible to both the client and server. The POA is an object visible to the server. User-supplied implementations are registered with the POA (this statement is a simplification; more detail is provided below). Clients hold references upon which they can make requests. The ORB, POA, and implementation all cooperate to determine which servant the operation should be invoked on, and to perform the invocation.

Figure 1: Abstract POA Model.
The figure above shows the detail of the relationship between the POA and the implementation. Ultimately, a POA deals with an Object Id and an active servant. By active servant, we mean a programming object that exists in memory and has been presented to the POA with one or more associated object identities. There are several ways for this association to be made.
If the POA supports the RETAIN policy, it maintains a map, labeled
Active Object Map, that associates Object Ids with active
servants, each association constituting an active object. If the POA has
the USE_DEFAULT_SERVANT policy, a default servant may be registered
with the POA. Alternatively, if the POA has the USE_SERVANT_MANAGER
policy, a user-written servant manager may be registered with the POA.
If the Active Object Map is not used, or a request arrives for an object
not present in the Active Object Map, the POA either uses the default servant
to perform the request or it invokes the servant manager to obtain a servant
to perform the request. If the RETAIN policy is used, the servant
returned by a servant manager is retained in the Active Object Map. Otherwise,
the servant is used only to process the one request.
An object is active in a POA if the POA's Active Object Map contains an entry that associates an Object Id with an existing servant.

Figure 2: POA Architecture.
To implement an object using the POA requires that the server application obtain a POA object. A distinguished POA object, called the Root POA, is managed by the ORB and provided to the application using the ORB initialization interface under the initial object name "RootPOA." The application developer can create objects using the root POA if those default policies are suitable. The root POA has the following policies.
Thread Policy: ORB_CTRL_MODEL
Lifespan Policy: TRANSIENT
Object Id Uniqueness Policy: UNIQUE_ID
Id Assignment Policy: SYSTEM_ID
Servant Retention Policy: RETAIN
Request Processing Policy: USE_ACTIVE_OBJECT_MAP_ONLY
Implicit Activation Policy: IMPLICIT_ACTIVATION
The developer can also create new POAs. Creating a new POA allows the application developer to declare specific policy choices for the new POA and to provide a different adapter activator and servant manager (these are callback objects used by the POA to activate objects and nested POAs on demand). Creating new POAs also allows the application developer to partition the name space of objects, as Object Ids are interpreted relative to a POA. Finally, by creating new POAs, the developer can independently control request processing for multiple sets of objects.
A POA is created as a child of an existing POA using the create_POA operation on the parent POA. When a POA is created, the POA is given a name that must be unique with respect to all other POAs with the same parent.
POA objects are not persistent. No POA state can be assumed to be saved by the ORB. It is the responsibility of the server application to create and initialize the appropriate POA objects during server initialization or to set an AdapterActivater to create POA objects needed later.
Creating the appropriate POA objects is particularly important for persistent objects, objects whose existence can span multiple server lifetimes. To support an object reference created in a previous server process, the application must recreate the POA that created the object reference as well as all of its ancestor POAs. To ensure portability, each POA must be created with the same name as the corresponding POA in the original server process and with the same policies. (It is the user's responsibility to create the POA with these conditions.)
A portable server application can presume that there is no conflict between its POA names and the POA names chosen by other applications. It is the responsibility of the ORB implementation to provide a way to support this behavior.
Object references are created in servers. Once they are created, they may be exported to clients.
From this model's perspective, object references encapsulate object identity information and information required by the ORB to identify and locate the server and POA with which the object is associated (that is, in whose scope the reference was created.) References are created in the following ways:
The server application may directly create a reference with the
create_reference and create_reference_with_id
operations on a POA object.
These operations collect the necessary information to constitute the reference,
either from information associated with the POA or as parameters to the
operation. These operations only create a reference. In doing so, they
bring the abstract object into existence, but do not associate it with
an active servant.
The server application may explicitly activate a servant, associating it
with an object identity using the activate_object or
activate_object_with_id
operations. Once a servant is activated, the server application can map
the servant to its corresponding reference using the servant_to_reference
or id_to_reference operations.
The server application may cause a servant to implicitly activate itself.
This behavior can only occur if the POA has been created with the
IMPLICIT_ACTIVATION
policy. If an attempt is made to obtain an object reference corresponding
to an inactive servant, the POA may automatically assign a generated unique
Object Id to the servant and activate the resulting object. The reference
may be obtained by invoking servant_to_reference with an
inactive servant, or by performing an explicit or implicit type conversion
from the servant to a reference type in programming language mappings that
permit this conversion.
Once a reference is created in the server, it can be made available to
clients in a variety of ways. It can be advertised through the OMG Naming
and Trading Services. It can be converted to a string via ORB::object_to_string
and published in some way that allows the client to discover the string
and convert it to a reference using ORB::string_to_object.
It can be returned as the result of an operation invocation.
Once a reference becomes available to a client, that reference constitutes the identity of the object from the client's perspective. As long as the client program holds and uses that reference, requests made on the reference should be sent to the "same" object.
The states of servers and implementation objects are opaque to clients. The POA deals primarily with the view of the ORB from the server's perspective.
At any point in time, a CORBA object may or may not be associated with an active servant.
If the POA has the RETAIN policy, the servant and its associated Object
Id are entered into the Active Object Map of the appropriate POA. This
type of activation can be accomplished in one of the following ways.
The server application itself explicitly activates individual objects (via
the activate_object or activate_object_with_id operations).
The server application instructs the POA to activate objects on demand
by having the POA invoke a user-supplied servant manager. The server application
registers this servant manager with set_servant_manager.
Under some circumstances (when the IMPLICIT_ACTIVATION policy is
also in effect and the language binding allows such an operation), the
POA may implicitly activate an object when the server application attempts
to obtain a reference for a servant that is not already active (that is,
not associated with an Object Id).
If the USE_DEFAULT_SERVANT policy is also in effect, the server
application instructs the POA to activate unknown objects by having the
POA invoke a single servant no matter what the Object Id is. The server
application registers this servant with set_servant.
If the POA has the NON_RETAIN policy, for every request, the
POA may use either a default servant or a servant manager to locate an
active servant. From the POA's point of view, the servant is active only
for the duration of that one request. The POA does not enter the servant-object
association into the Active Object Map.
A request must be capable of conveying the Object Id of the target object as well as the identification of the POA that created the target object reference. When a client issues a request, the ORB first locates an appropriate server (perhaps starting one if needed) and then it locates the appropriate POA within that server.
If the POA does not exist in the server process, the application has
the opportunity to re-create the required POA by using an adapter activator.
An adapter activator is a user-implemented object that can be associated
with a POA. It is invoked by the ORB when a request is received for a non-existent
child POA. The adapter activator has the opportunity to create the required
POA. If it does not, the client receives the OBJECT_NOT_EXIST exception.
Once the ORB has located the appropriate POA, it delivers the request to that POA. The further processing of that request depends both upon the policies associated with that POA as well as the object's current state of activation.
If the POA has the RETAIN policy, the POA looks in the Active
Object Map to find if there is a servant associated with the Object Id
value from the request. If such a servant exists, the POA invokes the appropriate
method on the servant.
If the POA has the NON_RETAIN policy or has the RETAIN
policy but didn't find a servant in the Active Object Map, the POA takes
the following actions:
If the POA has the USE_DEFAULT_SERVANT policy, a default servant
has been associated with the POA so the POA will invoke the appropriate
method on that servant. If no servant has been associated with the POA,
the POA raises the OBJ_ADAPTER system exception.
If the POA has the USE_SERVANT_MANAGER policy, a servant manager
has been associated with the POA so the POA will invoke incarnate or preinvoke
on it to find a servant that may handle the request. (The choice of method
depends on the NON_RETAIN or RETAIN policy of the POA.) If
no servant manager has been associated with the POA, the POA raises the
OBJ_ADAPTER system exception.
If the USE_OBJECT_MAP_ONLY policy is in effect, the POA raises the
OBJECT_NOT_EXIST system exception.
If a servant manager is located and invoked, but the servant manager is not directly capable of incarnating the object, it (the servant manager) may deal with the circumstance in a variety of ways, all of which are the application's responsibility. Any system exception raised by the servant manager will be returned to the client in the reply. In addition to standard CORBA exceptions, a servant manager is capable of raising a ForwardRequest exception. This exception includes an object reference. The ORB will process this exception as stated below.
A POA can be created with a policy that indicates that its
objects may be implicitly activated. This policy, IMPLICIT_ACTIVATION,
also requires the SYSTEM_ID and RETAIN policies. When a POA
supports implicit activation, an inactive servant may be implicitly activated
in that POA by certain operations that logically require an Object Id to
be assigned to that servant. Implicit activation of an object involves
allocating a system-generated Object Id and registering the servant with
that Object Id in the Active Object Map. The interface associated with
the implicitly activated object is determined from the servant.
The operations that support implicit activation include:
The servant_to_reference operation, which takes a servant
parameter and returns a reference.
The servant_to_id operation, which takes a servant parameter
and returns an Object Id.
If the POA has the UNIQUE_ID policy, then implicit activation will
occur when any of these operations are performed on a servant that is not
currently active (that is, it is associated with no Object Id in the POA's
Active Object Map). If the POA has the MULTIPLE_ID policy, the
servant_to_reference
and servant_to_id operations will always perform implicit
activation, even if the servant is already associated with an Object Id.
The POA supports location transparency for objects implemented using the POA. Unless explicitly stated to the contrary, all POA behavior described in this specification applies regardless of whether the client is local (same process) or remote. For example, like a request from a remote client, a request from a local client may: cause object activation if the object is not active; may block indefinitely if the target object's POA is in the holding state; may be rejected if the target object's POA is in the discarding or inactive states; may be delivered to a thread-unaware object implementation; or may be delivered to a different object if the target object's servant manager raises the ForwardRequest exception. The Object Id and POA of the target object will also be available to the server via the Current object, regardless of whether the client is local or remote.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.