Developing Client side Java applications using CORBA

Ed Desmond

January 12, 2000

 

 

Steps required for a Java client application to invoke a remote method

  1. Initialize the ORB
  2. Get a reference into the system

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}