Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

J2SE 1.4 breathes new life into the CORBA community, Part 2

Gain code portability with the Portable Object Adapter

  • Print
  • Feedback

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.

Servant retention policy



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.


Mapping request to 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.


Implicit vs. explicit activation policy

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.

Activate the servant

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.

Publish the object reference in the naming service

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.

Activate POAs

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.

Wait for requests

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();
    }
      .
      .
      .


Until next time

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.

About the author

Tarak Modi has been architecting scalable, high-performance, distributed applications for more than seven years and is currently a senior specialist with North Highland, a management and technology consulting company. His professional experience includes hardcore C++ and Java programming; working with Microsoft technologies such as COM (Component Object Model), MTS (Microsoft Transaction Server), and COM+; Java-based technologies including J2EE; and CORBA. He is also coauthor of Professional Java Web Services (Wrox Press, 2002; ISBN 1861003757). To find out more about him, visit his personal Website at http://www.tekNirvana.com.
  • Print
  • Feedback

Resources