Topics in this section include:
For a client to invoke a CORBA object operation, both the client and the server (the object implementation) must use a CORBA software component called an ORB (object request broker). ORBs are the common denominators that bridge the differences in location, platform, and programming language that can separate a client and a server. ORBs can contact each other across the network, can create and interpret object references (CORBA object handles), and can marshal parameters into and out of the format used by IIOP. In addition to enabling client/server communication, ORBs provide other services, but they are not described here.
The two ways to invoke an operation on a CORBA object are:
To make a static invocation on a CORBA object, a Java client needs an object reference to the servant that performs the operation. The object reference has two important functions:
OMG IDL is the language in which CORBA object interfaces are
defined. For each OMG IDL module, the idlj compiler
generates a Java package. For each interface Foo
defined
in an OMG IDL module, the generated package contains the following
items of interest to the client programmer:
Foo
, which extends org.omg.portable.IDLEntity, org.omg.CORBA.Object, and the operations interface. The signature interface is used as the signature type in method declarations when interfaces of the specified type are used in other interfaces. From the client's point
of view, an object reference for a CORBA Foo
object
implements this interface.
Note: The Stub implements the Foo
interface, where it
generates code for each method to marshall the arguments,
invoke the method, and then unmarshall the arguments.
FooOperations
, which is used in the server-side mapping and as a mechanism for providing optimized calls for co-located clients and server. The server developer provides implementation for the methods indicated by the operations interface.
FooHelper
, that defines auxiliary
methods, notably narrow()
, which is the CORBA
counterpart of Java casting.
Here's a simple example from the point of view of a client. The full text of the generated files can be viewed from Sample Code for Example.idl.
OMG IDL |
Generated Java |
---|---|
module Example { interface Counter { boolean increment (in long arg); }; }; |
package Example; public interface Counter extends CounterOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { } // interface Counter |
The following Java fragment shows the essentials of declaring and invoking an instance of this CORBA object:
import Example.* // get the interface and helper Counter anInstance = // acquire a reference boolean aResult; int anArg = 10; aResult = anInstance.increment(anArg);
A stub adapts a client to its underlying ORB for a particular CORBA object type. The ORB knows how to marshal an argument, but not which arguments need marshaling for a particular method. The stub, being type-specific, knows which arguments need marshaling for each method. When a client invokes a stub method, the stub tells the client's ORB what to marshal, and then tells the ORB to invoke the CORBA object identified by the object reference. The client's ORB uses the object reference to determine which remote ORB should receive the invocation, passes the marshaled parameters over the network to that ORB, and waits for the result. (For those familiar with remote procedure calls, CORBA object invocation is similar.)
A skeleton is an object server's analog of the client's stub. Skeletons are also generated by IDL compilers. When an ORB receives an invocation for one of its objects, processing is as follows:
To summarize, IIOP ORBs communicate CORBA object invocations across a network in a standardized form. All ORB operations are independent of the type of object being invoked and of the language in which the client and server are written. It's the job of the stub and the skeleton to match clients and servers to their ORBs for a particular type of CORBA object.
CORBA dynamic invocation uses an object called a request to
hold everything pertinent to an invocation: the object reference, the
name of the operation, its parameters, and space for the result. The
client builds a request object describing an operation, then calls
the request's invoke
method, which dispatches the
request just as a stub would. When the invoke method returns, the
result is available in the request object.
The key to dynamic invocation is the ability of requests to hold
self-describing data. This facility enables a request object to
represent any invocation of any operation, regardless of its
parameters. Each self-describing data element has a special type
known in OMG IDL as Any
. An Any
consists of
a typecode (whose values are defined by OMG IDL) and a value; the
typecode specifies the type of the value.
The following example shows the essentials of dynamic invocation. The CORBA object to be invoked has the following OMG IDL interface definition:
import org.omg.CosNaming.*; import org.omg.CORBA.*; public class CounterClient { public static void main(String args[]) { try{ // create and initialize the ORB ORB orb = ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // resolve the Object Reference in Naming NameComponent nc = new NameComponent("Counter", ""); NameComponent path[] = {nc}; Counter counterRef = CounterHelper.narrow(ncRef.resolve(path)); System.out.println("Object Ref: " + orb.object_to_string(counterRef)); // Create a DII request and set the arguments and result org.omg.CORBA.Request r = counterRef._request("increment"); r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long)); org.omg.CORBA.Any inc = r.add_in_arg(); inc.insert_long(1); // increment by 1 for (int i = 0; i < 10; i++) { // call the Hello server object and print results r.invoke(); java.lang.Exception ex = r.env().exception(); if (ex instanceof org.omg.CORBA.UnknownUserException) { org.omg.CORBA.UnknownUserException userEx = (org.omg.CORBA.UnknownUserException) ex; } // extract the result int result; result = r.return_value().extract_long(); System.out.println("Counter: " + result); } } catch (Exception e) { System.out.println("CounterClient : Exception: " + e) ; e.printStackTrace(System.out); } } }
Some web browsers have an ORB built directly into them. This can cause problems if that ORB is not perfectly compliant. In this case, special steps must be taken to initialize the Java IDL ORB specifically. For example, because of missing classes in the installed ORB in Netscape Communicator 4.01, an applet displayed in that browser must contain code similar to the following in its init() method:
import java.util.Properties; import org.omg.CORBA.*; public class MyApplet extends java.applet.Applet { public void init() { // Instantiate the Sun ORB, passing in this applet // so that the ORB can retrieve the applet properties. Properties props = new Properties(); props.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); ORB orb = ORB.init(this, props); ... } }
Clients | Servers | Exceptions | Initialization | Naming
Home |
Fundamentals |
Programming |
References |
Tutorial |