Portable Object Adapter (POA)

What is the Portable Object Adapter (POA)?

An object adapter is the mechanism that connects a request using an object reference with the proper code to service that request. The Portable Object Adapter, or POA, is a particular type of object adapter that is defined by the CORBA specification. The POA is designed to meet the following goals:

This document presents an introduction to using the POA with the Java 2 Platform, Standard Edition. For a more complete description of the POA, see Chapter 11 of the CORBA 2.3.1 Specification.

Creating and Using the POA

The steps for creating and using a POA will vary according to the specific application being developed. The following steps generally occur during the POA life cycle:

  1. Get the root POA
  2. Define the POA's policies
  3. Create the POA
  4. Activate the POAManager
  5. Activate the servants, which may include activating the Tie
  6. Create the object reference from the POA

Each step is described in more detail in the sections that follow.

Step 1: Get the root POA

The first step is to get the first POA, which is called the rootPOA. The root POA is managed by the ORB and provided to the application using the ORB initialization interface under the initial object name "RootPOA".

An example of code that will get the root POA object and cast it to a POA is:

      ORB orb = ORB.init( args, null );
      POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
Step 2: Define the POA's Policies

The Portable Object Adapter (POA) is designed to provide an object adapter that can be used with multiple ORB implementations with no rewriting needed to deal with different vendors' implementations.

The POA is also intended to allow persistent objects -- at least, from the client's perspective. That is, as far as the client is concerned, these objects are always alive, and maintain data values stored in them, even though physically, the server may have been restarted many times.

The POA allows the object implementer a lot more control over the object's identity, state, storage, and life cycle. You can create a POA without defining any policies and the default values will be used. The root POA has the following policies by default:

The following code snippet shows how policies are set in the RMI-IIOP (with POA) example:

      Policy[] tpolicy = new Policy[3];
      tpolicy[0] = rootPOA.create_lifespan_policy(
        LifespanPolicyValue.TRANSIENT );
      tpolicy[1] = rootPOA.create_request_processing_policy(
        RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY );
      tpolicy[2] = rootPOA.create_servant_retention_policy(
        ServantRetentionPolicyValue.RETAIN);

Each policy is discussed briefly in the following topics. For more information on POA policies, refer to Chapter 11, Portable Object Adapter of the CORBA/IIOP 2.3.1 Specification.

Thread Policy

This policy specifies the threading model used with the created POA. The default is ORB_CTRL_MODEL.

The ThreadPolicyValue can have the following values:

Lifespan Policy

This policy specifies the lifespan of the objects implemented in the created POA. The default is TRANSIENT.

The LifespanPolicyValue can have the following values:

Object Id Uniqueness Policy

This policy specifies whether the servants activated in the created POA must have unique object identities. The default is UNIQUE_ID.

The IdUniquenessPolicyValue can have the following values:

Id Assignment Policy

This policy specifies whether Object Ids in the created POA are generated by the application or by the ORB. The default is SYSTEM_ID.

The IdAssignmentPolicyValue can have the following values:

Servant Retention Policy

This policy specifies whether the created POA retains active servants in an Active Object Map. The default is RETAIN.

The ServantRetentionPolicyValue can have the following values.

Request Processing Policy

This policy specifies how requests are processed by the created POA. The default is USE_ACTIVE_OBJECT_MAP_ONLY.

The RequestProcessingPolicyValue can have the following values:

Implicit Activation Policy

This policy specifies whether implicit activation of servants is supported in the created POA. The default value is IMPLICIT_ACTIVATION.

The ImplicitActivationPolicyValue can have the following values:

Step 3: Create the POA

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 POAs on demand and activate servants). 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. To create a new POA, pass in the following information:

The following code snippet shows how the POA is created in the Hello World: Persistent Server example.

// Create a POA by passing the Persistent Policy
POA persistentPOA = rootPOA.create_POA("childPOA", null, 
   persistentPolicy ); 
Step 4: Activate the POAManager

Each POA object has an associated POAManager object that controls the processing state of the POAs with which it is associated, such as whether requests to the POA are queued or discarded. The POAManager can also deactivate the POA. A POA Manager may be associated with one or more POA objects.

The POAManager can have the following states:

The POAManagerOperations javadocs contain more information on these states.

POA Managers are not automatically activated when they are created. The following code snippet shows how the POAManager is activated in the Hello World: Persistent Server example. If the POA Manager is not activated in this way, all calls to the Servant will hang because, by default, the POA Manager is in the HOLD state.

            // Activate PersistentPOA's POAManager. Without this step,
            // all calls to Persistent Server will hang because POAManager
            // will be in the 'HOLD' state.
            persistentPOA.the_POAManager().activate( );

Step 5: Activate the servants

The following information is quoted from section 11.2.5 of the CORBA Specification.

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.

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.

When using RMI-IIOP technology, your implementations use delegation (known as the Tie model) to associate your implementation with the interface. When you create an instance of your implementation, you also need to create a Tie object to associate it with a CORBA interface. The following code snippet shows how to activate the Tie, if the POA policy is USE_ACTIVE_OBJECT_MAP_ONLY. This sample code is from the RMI-IIOP with POA example.

_HelloImpl_Tie tie = (_HelloImpl_Tie)Util.getTie( helloImpl );
String helloId = "hello";
byte[] id = helloId.getBytes();
tPOA.activate_object_with_id( id, tie );

The CORBA Specification discusses creating object references (section 11.2.4), activating objects (section 11.2.5), and processing requests (section 11.2.6) in more detail than is done in this document. Please refer to the CORBA 2.3.1 Specification for more information.

Step 6: Create the object reference

Object references are created in servers. Once created, they may be exported to clients. Object references encapsulate object identity information and information required by the ORB to identify and locate the server and the POA with which the object is associated. References are created in the following ways:

Once an reference is created in the server, it can be made available to clients. For more information on creating object references and exporting to clients, refer to section 11.2.4 of the CORBA 2.3.1 Specification for more information.

Adapter Activators

An adapter activator is optional. You would use an adapter activator if POAs need to be created during request processing. If all needed POAs are created when the application is executed, an adapter activator is not required.

An adapter activator supplies a POA with the ability to create child POAs on demand, as a side-effect of receiving a request that names the child POA (or one of its children), or when the find_POA method is called with an activate parameter value of TRUE. 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.

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

For more information on Adapter Activators, refer to section 11.3.3 of the CORBA 2.3.1 Specification or the AdapterActivatorOperations API documentation.

Servant Managers

Servant Managers are optional. You would use a servant manager to allow the POA to activate servants on demand when a request for an inactive object is received. If your server loads all objects when it starts up, you do not need a servant manager.

A servant manager is a callback 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 reference (as characterized by its Object Id value) with a particular servant, and for determining whether an object reference exists or not. Each servant manager type contains two operations, the first called to find and return a servant and the second to deactivate a servant. The operations differ according to the amount of information usable for their situation.

To use servant managers, the USE_SERVANT_MANAGER policy must be set. Once set, the type of servant manager used in a particular situation depends on other policies in the POA. The two types of servant managers are:

For more information on Servant Managers, refer to section 11.3.4 of the CORBA 2.3.1 Specification.

POA Q&A

Is POAManager.activate() required for a newly created POA?

POAManager.activate() is required for a newly created POA if a null is passed for the POAManager parameter to POA::createPOA . If null is passed, a new POAManager is created and associated with the created POA. In this case, POAManager.activate() is needed.

To control several POAs with the same POAManager, you would:

  1. Create a POA or use the rootPOA
  2. Obtain the POA's manager via POA::the_POAManager
  3. Pass the POAManager to subsequent createPOA calls

There is no implicit relationship between the Root POA's POAManager and other POAs unless explicitly programmed by the programmer as shown above.

For more information, read section 11.3.2 of the CORBA specification, formal/99-10-07.

For more information

For more information about the Portable Object Adapter, read Chapter 11 of the CORBA/IIOP v.2.3.1 Specification from the Object Management Group's website.

Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.