Introduction
Many ORBs currently in use support different versions of CORBA and/or the Java
language mapping.
The JBoss Transaction Service only supports the new Portable Object Adapter
(POA) architecture described in the CORBA 2.3 specification as a replacement
for the Basic Object Adapter (BOA). Unlike the BOA, which was weakly specified
and led to a number of different (and often conflicting) implementations, the
POA was deliberately designed to reduce the differences between ORB implementations,
and thus minimise the amount of re-coding that would need to be done when porting
applications from one ORB to another. However, there is still scope for slight
differences between ORB implementations, notably in the area of threading. Note,
instead of talking about the POA, this manual will consider the Object Adapter
(OA).
Because the JBoss Transaction Service must be able to run on a number of different
ORBs, we have developed an ORB portability interface which allows entire applications
to be moved between ORBs with little or no modifications. This portability interface
is available to the application programmer in the form of several Java classes.
The ORB Portability API
Using the ORB
The ORB class provided in the package com.arjuna.orbportability.ORB shown below
provides a uniform way of using the ORB. There are methods for obtaining a reference
to the ORB, and for placing the application into a mode where it listens for
incoming connections. There are also methods for registering application specific
classes to be invoked before or after ORB initialisation.
public class ORB
{
public static ORB getInstance(String uniqueId);
// given the various parameters,this method initialises the ORB and
// retains a reference to it within the ORB class.
public synchronized void initORB () throws SystemException;
public synchronized void initORB (Applet a, Properties p)
throws SystemException;
public synchronized void initORB (String[] s, Properties p)
throws SystemException;
//The orb method returns a reference to the ORB.
//After shutdown is called this reference may be null.
public synchronized org.omg.CORBA.ORB orb ();
public synchronized boolean setOrb (org.omg.CORBA.ORB theORB);
// If supported, this method cleanly shuts down the ORB.
// Any pre- and post- ORB shutdown classes which
//have been registered will also be called.
public synchronized void shutdown ();
public synchronized boolean addAttribute (Attribute p);
public synchronized void addPreShutdown (PreShutdown c);
public synchronized void addPostShutdown (PostShutdown c);
public synchronized void destroy () throws SystemException;
//these methods place the ORB into a listening mode,
//where it waits for incoming invocations.
public void run ();
public void run (String name);
};
Note, some of the methods are not supported on all ORBs, and in this situation,
a suitable exception will be thrown. The ORB class is a factory class which
has no public constructor. To create an instance of an ORB you must call the
getInstance method passing a unique name as a parameter. If this unique name
has not been passed in a previous call to getInstance you will be returned a
new ORB instance. Two invocations of getInstance made with the same unique name,
within the same JVM, will return the same ORB instance.
Using the Object Adapater (OA)
The OA classes shown below provide a uniform way of using Object Adapters (OA).
There are methods for obtaining a reference to the OA. There are also methods
for registering application specific classes to be invoked before or after OA
initialisation. Note, some of the methods are not supported on all ORBs, and
in this situation, a suitable exception will be thrown. The OA class is an abstract
class and provides the basic interface to an Object Adapter. It has two sub-classes
RootOA and ChildOA, these classes expose the interfaces specific to the root
Object Adapter and a child Object Adapter respectively. From the RootOA you
can obtain a reference to the RootOA for a given ORB by using the static method
getRootOA. To create a ChildOA instance use the createPOA method on the RootOA.
As described below, the OA class and its sub-classes provide most operations
provided by the POA as specified in the POA specification.
public abstract class OA
{
public synchronized static RootOA getRootOA(ORB associatedORB);
public synchronized void initPOA () throws SystemException;
public synchronized void initPOA (String[] args) throws SystemException;
public synchronized void initOA () throws SystemException;
public synchronized void initOA (String[] args) throws SystemException;
public synchronized ChildOA createPOA (String adapterName,
PolicyList policies) throws AdapterAlreadyExists, InvalidPolicy;
public synchronized org.omg.PortableServer.POA rootPoa ();
public synchronized boolean setPoa (org.omg.PortableServer.POA thePOA);
public synchronized org.omg.PortableServer.POA poa (String adapterName);
public synchronized boolean setPoa (String adapterName,
org.omg.PortableServer.POA thePOA);
...
};
public class RootOA extends OA
{
public synchronized void destroy() throws SystemException;
public org.omg.CORBA.Object corbaReference (Servant obj);
public boolean objectIsReady (Servant obj, byte[] id);
public boolean objectIsReady (Servant obj);
public boolean shutdownObject (org.omg.CORBA.Object obj);
public boolean shutdownObject (Servant obj);
};
public class ChildOA extends OA
{
public synchronized boolean setRootPoa (POA thePOA);
public synchronized void destroy() throws SystemException;
public org.omg.CORBA.Object corbaReference (Servant obj);
public boolean objectIsReady (Servant obj, byte[] id)
throws SystemException;
public boolean objectIsReady (Servant obj) throws SystemException;
public boolean shutdownObject (org.omg.CORBA.Object obj);
public boolean shutdownObject (Servant obj);
};
Example
The following example illustrates how to use the ORB Portability API to create
import com.arjuna.orbportability.ORB;
import com.arjuna.orbportability.OA;
public static void main(String[] args)
{
try
{
// Create an ORB instance
ORB orb = ORB.getInstance("orb_test");
OA oa = OA.getRootOA( orb ); // Get the root POA
orb.initORB(args, null); // Initialize the ORB
oa.initOA(args); // Initialize the OA
// Do Work
oa.destroy(); // destroy the OA
orb.shutdown(); // Shutdown the ORB
}
catch(Exception e) {}
};
Specifying the ORB to use
If using such a JDK (from its version 1.2.2) in conjunction with another ORB
it is necessary to tell the JVM which ORB to use. This happens by specifying
the org.omg.CORBA.ORBClass and
org.omg.CORBA.ORBSingletonClass properties.
If used, ORB Portability classes will ensure that these properties are automatically
set when required, i.e., during ORB initialisation.
The ORB portability library attempts to detect which ORB is in use, it does
this by looking for the ORB implementation class for each ORB it supports. This
means that if there are classes for more than one ORB in the classpath the wrong
ORB can be detected. Therefore it is best to only have one ORB in your classpath.
If it is necessary to have multiple ORBs in the classpath then the property
com.arjuna.orbportability.orbImplementation
must be set to the value specified in the table below.
ORB
|
Property Value
|
JacORB v2.0 |
com.arjuna.orbportability.internal.orbspecific.jacorb.orb.implementations.jacorb_2_0 |
For additional details on the features provided by the ORB Portability API
refer to the documentation provided by the JBossTS distribution.