Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 5
USER_ID: Specifies that the application assigns the object IDs.
SYSTEM_ID: This default value specifies that the POA assigns a unique object ID. If the POA is persistent, assigned object IDs must
be unique across all instantiations of the same POA.
This policy specifies whether the created POA retains active servants in an active object map. Think of the active object map as a hash table in which the key is the object ID and the value is the servant. The active object map resembles a pooling mechanism found in modern application servers. This policy can have the following values:
RETAIN: Specifies that the POA will retain active servants in its active object map.
NON_RETAIN: Specifies that the POA will not retain servants.
This policy specifies how the created POA processes requests and can have the following values:
USE_ACTIVE_OBJECT_MAP_ONLY: This default value specifies that if the object ID is not found in the active object map, an OBJECT_NOT_EXIST exception returns to the client. Obviously, the servant retention policy must be set to RETAIN.
USE_DEFAULT_SERVANT: Specifies that if the object ID is not found in the active object map, or if the servant retention policy is set to NON_RETAIN and a default servant has been registered with the POA with the set_servant() method, the request will dispatch to the default servant. I will go into the details of creating a default servant in Part
3.
USE_SERVANT_MANAGER: Specifies that if the object ID is not found in the active object map, or if the servant retention policy is set to NON_RETAIN and a servant manager has been registered with the POA using the set_servant_manager() method, the servant manager is allowed to locate or activate a servant, or raise an exception. Based on the servant retention
policy used, two types of servant managers are available. I will go into the details of creating both types in Part 3.
This policy specifies whether the created POA supports implicit servant activation. It can have the following values:
IMPLICIT_ACTIVATION: This default value indicates that implicit servant activation is supported. The value also requires that you set the object
identifiers assignment policy to SYSTEM_ID and the servant retention policy to RETAIN.
NO_IMPLICIT_ACTIVATION: Indicates that server-side code must explicitly activate servants.
As you can see, certain policies depend on other policy values. If you try to create a POA with incompatible policies, an
InvalidPolicy error will occur during runtime.
As I discussed above, a CORBA object is an abstract entity. The servant performs the real work. Here's Part 1's servant implementation:
class HelloImpl extends HelloPOA {
private ORB orb;
public void setORB(ORB orb_val) {
orb = orb_val;
}
// Implement sayHello() method
public String sayHello() {
return "\nHello world !!\n";
}
// Implement shutdown() method
public void shutdown() {
orb.shutdown(false);
}
}
As you recall from Part 1, the idlj compiler generates the HelloPOA class.
Now look at the code that associates the above servant with a CORBA object in the RootPOA:
.
.
.
// rootPOA is a reference to the Root POA
// Create a servant and register it with the ORB
HelloImpl helloImpl = new HelloImpl();
helloImpl.setORB(orb);
// Get object reference from the servant
org.omg.CORBA.Object ref = rootPOA.servant_to_reference(helloImpl);
Hello href = HelloHelper.narrow(ref);
.
.
.
The servant_to_reference() method on a POA creates an object reference (either transient or persistent, based on the lifetime policy). A client will
use this object reference to invoke methods on the CORBA object.
Now that you have instantiated the servant and created an object reference for an object that will use that servant (or another
instance of that servant class), you must make the object reference available for clients to use. One approach stringifies the reference using the object_to_string() method on the ORB. You would then store this reference in a file or print it on the console, and the client would retrieve
an object using the string_to_object() method on the ORB. A more elegant approach uses the CORBA naming service as shown in this Hello World example:
.
.
.
// Get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
// Use NamingContextExt, which is part of the Interoperable
// Naming Service (INS) specification
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// Bind the Object Reference in Naming
// href is the reference to the Hello Servant
String name = "Hello";
NameComponent path[] = ncRef.to_name( name );
ncRef.rebind(path, href);
.
.
.
Part 4 will explain the naming service in more detail.
Once you've registered all your servants, published the object references, and are ready to start receiving client requests,
you must activate all your POAs via the activate() method on each POA's POAManager, including the RootPOA. The POAManager is the entity that manages the POA's lifecycle. Multiple POAs can share a single POAManager. When you create a POA, you assign it a POAManager. If you don't, then a new POAManager is automatically created and assigned to the POA for you (reads like your Miranda rights). The following code snippet from
the Hello World example activates the RootPOA:
.
.
.
// rootPOA is a reference to the Root POA
// Activate the Root POA via the POAManager
rootPOA.the_POAManager().activate();
.
.
.
Until the POAManager activates, the POA will not process requests and will queue them up. If the maximum limit queues up, the POA will raise a
TRANSIENT error. You can also temporarily deactivate a POA by calling deactivate() on the POAMananger.
The last task is to wait for clients to start sending requests, which this code snippet accomplishes:
.
.
.
System.out.println("HelloServer ready and waiting ...");
// Wait for invocations from clients
orb.run();
}
.
.
.
In Part 2, I covered much POA theory and the differences between transient and persistent objects. In addition, I explained Part 1's sample code. Part 3 will be code intensive; we will create a sample Bank application and exercise our knowledge of servant managers (both servant activators and servant locators) and default servants. We will also learn how to use ORBD to register our servers for persistent object activation.