CORBA – Implementing Objects

April 30, 2008 at 3:21 am (CORBA) ()

Object Implementations

NOTE: the previous section discussed the client’s view of CORBA, that is, how a Java client issues a request on a CORBA object. The client’s view is standard across most CORBA products. Basically, the standard worked and there are only minor differences. Unfortunately, the same is not the case for the implementation view of CORBA. As such, some of the details given here might not match a particular CORBA product. Notes on different CORBA products appear as appendices.

This section describes what you need to know to implement a simple CORBA object in the Java programming language. It examines the Java server-side language binding for IDL, implementing objects and servers, implementation packaging issues, and CORBA object adaptors. After completing this section, you should be able to write a simple CORBA object and server in the Java programming language. Again, the stock example is used to illustrate the implementation model of CORBA.

CORBA object implementations are completely invisible to their clients. A client can only depend on the IDL interface. In the Java programming language, or C++, this is not the case. The user of an object declares variables by a class name; doing so makes the code depend on much more than just the interface. The client depends on the object implementation programming language, the name of the class, the implementation class hierarchy, and, in C++, even the object layout.

The complete encapsulation for CORBA objects means the object implementor has much more freedom. Object implementations can be provided in a number of supported programming languages. This is not necessarily the same one the clients are written in. (Of course, here everything is in the Java programming language, but CORBA does notrequire this.)

The same interface can be implemented in multiple ways. There is no limit. In the stock example, the following are possible implementations of the Stock interface:

  • A stock implementation class written in the Java programming language that obtains values from a commercial feed
  • A stock implementation class written in C++ that accesses a database on the Internet
  • A stock implementation written in Smalltalk that guesses stock prices

Providing an Implementation

Recall that given an IDL file, the IDL compiler generates various files for a CORBA client. In addition to the files generated for a client, it also generates a skeleton class for the object implementation. A skeleton is the entry point into the distributed object. It unmarshals the incoming data, calls the method implementing the operation being requested, and returns the marshaled results. The object developer need only compile the skeleton and not be concerned with the insides of it. The object developer can focus on providing the implementation of the IDL interface.

To implement a CORBA object in the Java programming language, the developer simply implements a Java class that extends the generated skeleton class and provides a method for each operation in the interface. In the example, the IDL compiler generates the skeleton class _StockImplBase for the Stock interface. A possible implementation of the Stock interface is:

public class StockImpl extends
      StockObjects._StockImplBase {

  private Quote _quote=null;
  private String _description=null;

  public StockImpl(
    String name, String description) {
    super();
    _description = description;
  }

  public Quote get_quote() throws Unknown {
    if (_quote==null) throw new Unknown();
    return _quote;
  }

  public void set_quote(Quote quote) {
    _quote = quote;
  }

  public String description() {
    return _description;
  }
}

Interface versus Implementation Hierarchies

Notice that there are two separate hierarchies: an interface hierarchy and an implementation hierarchy. Recall that the interface hierarchy for the example of a ReportingStock is:

In IDL this is represented as:

interface ReportingStock: Reporting, Stock {
};

Now suppose there is an implementation of a ReportingStock, named ReportingStockImpl, that inherits the IDL generated skeletons _ReportingStockImplBase, delegates some of its stock methods to StockImpl, and implements the Reporting operations directly. Graphically:

In the Java programming language, this class hierarchy is represented as:

class ReportingStockImpl
           implements ReportingStock
  extends _ReportingStockImplBase {
    ...
}

Since the Java programming language only supports single inheritance of implementation classes, implementations often create an instance of another class and delegate to it. In the above example, the ReportingStockImpl delegates to the StockImpl class for the implementation of some of its methods.

Other class hierarchies implementing the same interface hierarchy are possible. Furthermore, if you need to change the class hierarchy of the implementation in some way, the clients are not affected.

Implementation Type Checking

Just as type checking is done at the client for the request to a distributed object, type checking is also done for the object implementation.

The IDL compiler for the Java programming language generates object skeletons and Java code to represent all of the IDL interfaces and data types used in the interface definition. The implementation code thus depends on the generated Java code.

If there are any type errors in the object implementation, the Java compiler, not the IDL compiler, catches the errors at compile time. Thus, in the example, suppose the developer erroneously implemented the get_quote() operation to return a double instead of the structure that is declared in the IDL:

Quote StockImpl.get_quote() {
  double price = ...;
  return price;
}

The Java compiler would detect this error at compile time.

Implementing a Server Using the Java 2 ORB

You previously saw how to provide an implementation of a CORBA object in the Java programming language. The remaining task is to define a server that when run makes the services of its objects available to clients. A server that will run with the Java 2 ORB needs to do the following:

  • Define a main method
  • Initialize the ORB
  • Instantiate at least one object
  • Connect each object to the orb
  • Wait for requests

The server must instantiate at least one object since objects are the only way to offer services in CORBA systems.

Here’s an implementation of the stock objects server. This code depends on the Java 2 ORB.

public class theServer {
  public static void main(String[] args) {
    try {
      // Initialize the ORB.
      org.omg.CORBA.ORB orb =
        org.omg.CORBA.ORB.init(args,null);

      // Create a stock object.
      StockImpl theStock =
        new StockImpl("GII",
               "Global Industries Inc.");

      // Let the ORB know about the object
      orb.connect(theStock);

      // Write stringified object
      //reference to a file
      PrintWriter out =
         new PrintWriter(new BufferedWriter(
                   new FileWriter(args[0])));
      out.println(
            orb.object_to_string(theStock) );
      out.close();

      // wait for invocations from clients
      java.lang.Object sync =
                     new java.lang.Object();
      synchronized (sync) {
        sync.wait();
      }
    } catch (Exception e) {
      System.err.println(
            "Stock server error: " + e);
      e.printStackTrace(System.out);
    }
  }
}

Notice that the server does a new on the StockImpl class implementing the Stock interface and then passes it to the ORB using the connect() call, indicating that the object is ready to accept requests. Finally, the server waits for requests.

Implementing a Server Using VisiBroker 3.x

You previously saw how to provide a server using the Java 2 ORB. If you are using Inprise’s VisiBroker 3.x for Java ORB you need to do the following:

  • Define a main method
  • Initialize the ORB and the BOA (basic object adapter)
  • Instantiate at least one object
  • Let the BOA know that the object is ready to provide service
  • Let the BOA know that the server is ready

The server must instantiate at least one object since objects are the only way to offer services in CORBA systems.

Here’s an implementation of the stock objects server. This code depends on VisiBroker 3.x:.

public class theServer {
  public static void main(String[] args) {
    try {
      // Initialize the ORB.
      org.omg.CORBA.ORB orb =
        org.omg.CORBA.ORB.init(args,null);

      // Initialize the BOA.
      org.omg.CORBA.BOA boa =
        ((com.visigenic.vbroker.orb.ORB)orb)
                                .BOA_init();

      // Create a stock object.
      StockImpl theStock =
          new StockImpl("
             GII","Global Industries Inc.");

      // Write stringified object
      //reference to a file
      PrintWriter out =
          new PrintWriter(new BufferedWriter(
                     new FileWriter(args[0])));
      out.println(
           orb.object_to_string(theStock) );
      out.close();

      // Tell the BOA that the object
      //is ready to
      // receive requests.
      boa.obj_is_ready(theStock);

      // Tell the boa that the
      //server is ready.  This
      // call blocks.
      boa.impl_is_ready();
    } catch (Exception e) {
      System.err.println("
        Stock server error: " + e);
      e.printStackTrace(System.out);
    }
  }
}

Notice that the server does a new on the StockImpl class implementing the Stock interface and then passes it to the BOA, indicating that the object is ready to accept requests. Finally, the server calls the BOA to indicate that it is ready. At this point, the implementation will be called when requests arrive.

Differences Between Server Implementations

The following summarizes the differences between implementing a transient CORBA server using the Java 2 ORB and implementing a transient server using Inprise’s VisiBroker 3.x:

Java 2 ORB VisiBroker 3.x for Java
Initialization Just initialize the ORB Initialize both the ORB and the BOA
Object export orb.connect(theStock) boa.obj_is_ready(theStock)
Indicate server ready for requests Suspend main thread doing a wait() boa.impl_is_ready()

These are the only differences for transient object servers. There are further API differences of CORBA products due to persistence and automatic activation of servers.

Packaging Object Implementations

As illustrated above, you should separate the implementations of your objects from the implementation of the server. This allows you to mix and match object implementations in a server. The object implementation does not depend on the server. The server, of course depends on the object implementations that it contains.

Another advantage of carefully isolating object implementation code from server code is portability. Most of the product-specific code exists in the server, not in the object implementation.

A good strategy is to package an object implementation with its generated stubs and skeletons as a JavaBean component. This allows the implementation to be manipulated by JavaBean design tools.

Post a Comment

You must be logged in to post a comment.