Developing Client side Java applications using CORBA
Ed Desmond
January 12, 2000
Steps required for a Java client application to invoke a remote method
There are a number of Java helper classes which exist to initialize a Java application and connect to CORBA servers.
These classes are in jar files cutilities.jar and jutilities.jar which are located in $ONLINE_MAIN/classes
Documentation is on the ONCS web page under code_documentation:
Java classes for CORBA and Java helper classes
Initialize the Orb
OrbWrapper class
Gets a reference to the Orb
Sets the default protocol to Orbix Protocol
Options to change the protocol
Provides public member orbRef which is the reference to the ORB.
Part of Package CorbaUtilities
Available in a jar file cutilities in $ONLINE_MAIN/classes/cutilities.jar
OrbWrapper orbwrapper = null
orbwrapper = new OrbWrapper();
orbwrapper.initializeOrb();
// get the reference to the orb
org.omg.CORBA.ORB orb = orbwrapper.orbRef;
Get Initial reference into the system
Get a reference to the Nameserver
The functions of the Nameserver
To provide a name to object reference mapping
Returns list of registered objects
Provides means to bind a name to a reference
Ns.java class
Methods
Connect();
ResolveName(String name, ObjectHolder hObject);
BindName (String name, Object objectRef );
import CorbaUtilities.Ns;
Ns nameserver = null;
nameserver = new Ns(nameServerName,nameServerHostName);
nameserver.connect();
// print out the objects in the nameserver
StringListHolder nl = new StringListHolder(); // a utility class in JUtilities
nameserver.getNsObjectList(nl);
System.out.println("\nNameserver Registered Object List " );
// print the items in the list
int objlength = nl.value.length;
for (int nextobject = 0; nextobject < objlength ; nextobject++)
{
System.out.println(nl.value[nextobject]);
}
Get an initial reference from a different ORB or via IIOP
Use the COS Naming Server
CORBA compliant means for bootstrapping a corba client
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
// NOW NARROW THE OBJECT REFERENCE TO THE DESIRED //CLASS
Dcm dcmRef = DcmHelper.narrow(org.omg.CORBA.Object object) ;
Get Stringified Object Reference
Server creates a string representation of an object reference
Stringname = CORBA:object_to_string(object);
Write the string to a file or database or Web page
Client Application reads the file and converts the string to an object reference
Object objRef = CORBA:string_to_object(stringName );
Narrow the object reference to the derived object of base class CORBA.Object
Invoke the method on the object
Object objRef;
myiiop myiiopRef;
// open the file "iiopref.out"
// convert the string which was read to an object reference
// and then invoke the method getId(long id) on the reference
// open the text file
byte buff[] = new byte[1000];
try {
InputStream fileIn = new FileInputStream("iiopref.out");
int i = fileIn.read(buff);
}
catch (FileNotFoundException e) {
System.out.println("Could not open file fread.out ");
}
catch (IOException e) {
System.out.println("IOException " + e.toString() );
}
// now convert the string to an object reference
// first convert the byte array to a string object
String iiopStrRef = new String(buff);
// convert the string to a reference
objRef = omgOrbRef.string_to_object(iiopStrRef);
// now narrow the reference to a myiiop object
myiiopRef = myiiopHelper.narrow(objRef);
// finally invoke a method on the object
int myid = 0;
org.omg.CORBA.IntHolder intHolder = new IntHolder();
myiiopRef.getId(intHolder);
myid = intHolder.value;
System.out.println("My ID = " + myid );
Compiling IDL files to generate Java proxy code
idlj -I$(IDL_MAIN) -jc -jO. -jQ -m interOp -jP $(PACKAGE) -N testParamsObject.idl
Produces the following files for client side java code
testParamsObject.java
testParamsObjectHelper.java
provides functions to extract objects of this type from type any
testParamsObjectHolder.java
provides wrapper class to return modified versions of this class
required since Java passes arguments by value
pass by values means that a copy of a reference is passed
Passing and returning Data from remote methods
Javademo.java in $ONLINE_DISTRIBUTION/CorbaUtilities/src contains this demo
Get a Reference to an Object by direct bind
testParamsObject testObjectRef = null;
public int getTestObjectReference()
{
try {
testObjectRef =
testParamsObjectHelper.bind(":phoncs/testServer",nameServerHostName);
}
catch ( SystemException ex)
{
System.out.println("Failed to bind to testParamsObject");
return -1;
}
return 0;
} // getTestObjectReference
Sending Strings
try {
testObjectRef.setName(newName);
}
catch(CorbaUtilities.testParamsObjectPackage.reject ex){
System.out.println("Exception during ResolveName");
System.out.println(ex.reason);
}
catch ( SystemException ex)
{
System.out.println("Failed call to setName testParamsObject");
}
Retreiving Strings
// This is a function in Javademo.java
String getString( StringListHolder nl)
{
System.out.println("-- GETSTRING TEST --");
String returnValue = null;
String returnParamValue = null
;int objlength = 1;
nl.value = new String[1];
org.omg.CORBA.StringHolder returnStringHolder = new org.omg.CORBA.StringHolder();
try {
returnValue = testObjectRef.getName( returnStringHolder );
returnParamValue = returnStringHolder.value;
nl.value[0] = returnValue;
}
catch ( SystemException ex)
{
System.out.println("Failed to bind to testParamsObject");
return new String("getString exception ");
}
System.out.println("Return String = " + returnValue );
System.out.println("Return Parameter = " + returnParamValue );
}
Sending and Retreiving sequences of Strings in type Any
String sequences are just arrays of strings
Type Any is a generic self describing data structure
System.out.println("-- SEND SEQ STRING TEST --");
// send a sequence of strings to a remote object
String[] stringSeq = new String[4];
String s1 = new String("johnL");
String s2 = new String("george");
String s3 = new String("Paul");
String s4 = new String("Ringo");
stringSeq[0] = new String("johnL");
stringSeq[0] = s1;
stringSeq[1] = s2;
stringSeq[2] = s3;
stringSeq[3] = s4;
Any myany = omgOrbRef.create_any();
try {
// INSERT THE STRING IN THE ANY DATA STRUCTURE
seqStringHelper.insert(myany,stringSeq);
}catch (SystemException se) {
System.out.println("insert any error\n" + "Unexpected exception:\n" + se.toString ());
return;
}
// EXECUTE THE FUNCTION BY SENDING THE ANY
try {
testObjectRef.setValue(myany);
}
catch (SystemException se) {
System.out.println("set any error\n" + "Unexpected exception:\n"
+ se.toString ());
return;
}
System.out.println(" SUCCESS sending string sequence ");
} // sendStringSeq
Return and Extract an arbitrary data type inserted in a type Any
This example retrieves either a sequence of longs or Strings and determines at run - time
Which type is being returned
int datatype = 0;
String[] namelist = null;
int [] llist ;
int listsize;
// declare any and holder for any
// Any rtnany = ORB.init().create_any();
org.omg.CORBA.AnyHolder seqdataListHolder = new AnyHolder();
Any rtnany = new IE.Iona.OrbixWeb.CORBA.Any(IE.Iona.OrbixWeb._CORBA.IT_ORBIX_OR_KIND);
org.omg.CORBA.TypeCode m_tcString = org.omg.CORBA.ORB.init().get_primitive_tc(org.omg.CORBA.TCKind.tk_string);
org.omg.CORBA.TypeCode m_tcLong = org.omg.CORBA.ORB.init().get_primitive_tc(org.omg.CORBA.TCKind.tk_long);
System.out.println("-- GET SEQ TEST --");
// EXECUTE THE REMOTE MEMBER FUNCTION TO GET THE DATA
try {
testObjectRef.getValue(seqdataListHolder);
}
catch (SystemException se) {
System.out.println("get any error\n" + "Unexpected exception:\n"
+ se.toString ());
return;
}
// extract the any from the anyHolder
try {
rtnany = seqdataListHolder.value;
// first test for a sequence.
// If the type is a sequence then test for
// the required content type of the sequence
if ( rtnany.type().kind().value() == TCKind.tk_sequence.value() )
{
System.out.println(" SUCCESS TEST FOR SEQUENCE ");
try {
// test if the sequence is a sequence of strings
if (rtnany.type().content_type().kind().value() == m_tcLong.kind().value() )
{
// sequence is a sequence of longs so go get them
System.out.println("JC: extract long sequence " );
try {
llist = seqLongHelper.extract (rtnany);
listsize = llist.length;
for (int index = 0 ; index < listsize ; index++ )
{
System.out.println("LL["+index+"] = " + llist[index] );
}
} catch (SystemException se)
{
System.out.println ("Exception on lonsSeq extraction");
System.out.println(se.toString() );
}
} // end seq long test
} catch (org.omg.CORBA.TypeCodePackage.BadKind kse )
{
System.out.println(" bad typecode " );
}
// it is still a sequence now test for a sequence of strings
try {
if (rtnany.type().content_type().kind().value() == m_tcString.kind().value() )
{
System.out.println("JC: extract string seq " );
namelist = seqStringHelper.extract (rtnany);
// print out the returned list of strings
listsize = namelist.length;
for (int index = 0 ; index < listsize ; index++ )
{
System.out.println("NL["+index+"] = " + namelist[index] );
}
} // endif seq string test
} catch (org.omg.CORBA.TypeCodePackage.BadKind kse )
{
System.out.println(" bad typecode " );
}
} // end seq test // see OW pref pg 67 , 252
}catch (SystemException se) {
System.out.println("extract error\n" + "Unexpected exception:\n"
+ se.toString ());
return;
}
} // getStringSeq
Sending Sequence of Structures
Arcnet Example
typedef sequence< octet > seqOctet;
struct ArcnetCommand
{
string node;
string file;
boolean returnResponsePacket;
};
/*
* arcnet Packet
*
struct ArcnetPacket {
string node;
seqOctet thePacket
boolean returnResponsePacket;
}
*/
struct ArcnetStatus
{
string node;
string file;
long status;
string result;
seqOctet returnPacket;
};
typedef sequence< ArcnetStatus > seqArcnetStatus;
typedef sequence< ArcnetCommand > seqArcnetCommand;
System.out.println("\n<--- downloadFiles COMMAND SEQUENCE TEST --->");
int index = 0;
byte[] olist = null;
int listsize = 0;
ArcnetStatus[] returnedArcnetStatus = null;
int nodestatusindex = 0;
java.io.PrintStream output = System.out;
// create a sequence of ArcnetCommand structures
ArcnetCommand [] commandSeq = new ArcnetCommand[2];
// create the individual ArcnetCommand structures
ArcnetCommand command1 = new ArcnetCommand();
ArcnetCommand command2 = new ArcnetCommand();
command1.node = new String("arcnetNode1");
command1.file = new String("arcentfile1.dat");
command1.returnResponsePacket = true;
command2.node = new String("arcnetNode2");
command2.file = new String("arcentfile2.dat");
command2.returnResponsePacket = true;
// fill the array with instances of the structures
commandSeq[0] = command1;
commandSeq[1] = command2;
// create an instance of an ArcnetStatus sequence holder
seqArcnetStatusHolder arcstatusSeqHolder = new seqArcnetStatusHolder();
ArcnetStatusHolder arcstatusHolder = new ArcnetStatusHolder();
ArcnetStatus[] nodestatus = null;
System.out.println("\n execute download files command");
// execute the downloadFiles command
try {
arcnetserverRef.downloadFiles(commandSeq, arcstatusSeqHolder);
} catch ( SystemException ex)
{
output.println("Exception sending command ");
output.println(ex.toString() );
return;
}
output.println(" ARCNET DOWNLOADFILES COMMAND RETURNED STATUS " );
// extract the data from the returned status
nodestatus = arcstatusSeqHolder.value;
// seqArcnetStatus nodestatusSeq = arcstatusSeqHolder.value;
// get the length of the returned status
int returnedSeqLength = nodestatus.length;
for (nodestatusindex = 0; nodestatusindex < returnedSeqLength ; nodestatusindex++ )
{
// now get the status data
output.println("node : " + nodestatus[nodestatusindex].node );
output.println("result : " + nodestatus[nodestatusindex].result );
output.println("status " + Integer.toString(nodestatus[nodestatusindex].status));
Extract the returned sequence of Octets directly
// print out the returned octet sequence
try {
olist = nodestatus[nodestatusindex].returnPacket;
listsize = olist.length;
for (index = 0 ; index < listsize ; index++ )
{
System.out.println("octet["+index+"] = " + olist[index] );
}
} catch (SystemException se)
{
System.out.println ("Exception on octet extraction");
System.out.println(se.toString() );
}
} // end of returned sequence status
Running applications
java is aliased to java -Dorg.omg.CORBA.ORBClass=IE.Iona.OrbixWeb.CORBA.ORB -Dorg.omg.CORBA.ORBSingletonClass=IE.Iona.OrbixWeb.CORBA.singletonORB
Runjava is an alias for runjava.csh
This script contains the classpath for the jar files described.
The global classpath also has these jar files
java -Dorg.omg.CORBA.ORBClass=IE.Iona.OrbixWeb.CORBA.ORB -Dorg.omg.CORBA.ORBSingletonClass=IE.Iona.OrbixWeb.CORBA.singletonORB -classpath .:${JAVAORB}/config:${JAVAORB}/lib/OrbixWeb.jar:${CUTILITIES_LIB}/cutilities.jar:${CUTILITIES_LIB}/jutilities.jar:${CUTILITIES_SRC}:${BORLAND}/jbcl3.0-res-rt.jar:${BORLAND}/jbcl3.0-rt.jar:${BORLAND}/jgl3.1.0.jar ${TARGET}