This chapter introduces the JacORB Interface Repository and tells you how to run and use it.
The Interface Repository (IR) is a runtime component in the ORB architecture and used to dynamically obtain information on IDL types, e.g. object interfaces. This kind of information is necessary when a client wants to use the Dynamic Invocation Interface (DII) to construct requests dynamically, i.e. without static knowledge about another object's type.
In this case, when there is no stub available for a CORBA object, the Interface Repository can be queried to return information about the object's operations and the parameters necessary to invoke them. Using this information, a client can determine how to dynamically construct a request to the object.
ORBs can also use the IR for runtime type checks when narrowing object references to a particular type, i.e. to determine whether an object's type really matches a local type definition. An ORB might consider this necessary when receiving a reference to an object that is managed by another ORB.
The JacORB Interface Repository is just another CORBA object that can be accessed as soon as its reference is known, e.g. after retrieving it from the ORB using the resolve_initial_references() call with an argument string "InterfaceRepository". This reference can then be used to query the IR for type definitions. Write operations on the IR, i.e. modifications, are not supported in JacORB.
There is also another way to contact the IR. Every CORBA object reference allows a client to call the _get_interface() operation, which will return an object of type InterfaceDef that describes the object most derived type. InterfaceDef objects are managed by the IR, and every _get_interface() call will actually contact the IR and retrieve the InterfaceDef from its contents.
As the IR is actually a CORBA object, a separate process must be started for the IR to be available. To start the JacORB Interface Repository, simply type
$ ir <IR_location_file> [ <classpath> ]
to run a shell script or
$ ir.bat <IR_location_file> [ <classpath> ]
for a DOS batch file. You can also start the Java interpreter explixitly by typing
java jacorb.Orb.IR.ir <IR_location_file> [ <classpath> ]
In these examples, <IR_location_file> is a file name and the optional <classpath> argument is a Java CLASSPATH. The usage of a file to store the Repository's object reference so that it can be retrieved by the ORB is analogous to the way the name server uses such files, i.e. it must be able to read the file using the URL configured in Config.java.
The <classpath> argument determines the contents of the Repository, i.e. the set of repository defintions retrievable from the IR. If it is not explicitly given, the class path is taken from the environment.
In JacORB, the IR does not keep any persistent data of its own. Rather, it uses the Java .class files accessible in the class path that was given as an argument to the IR process. The JacORB IR employs Java reflection to derive IDL meta data like InterfaceDef objects on demand, i.e. when this information is needed.
This design has a number of consequences for users. First of all, you need not worry about IDL compiler switches or anything of that kind in order to make sure that the IR will know about the types you are working with. The IR will know as soon as there are java classes representing the IDL types -- and these classes are necessary anyway and therefore generated by the IDL compiler without any intervention from your side. So, as soon as as you compile an IDL file and then compile the generated Java classes, this information is accessible to the IR -- provided its class path is properly configured.
In the future, the IR will be able to accept Java classes as input that were written manually, so it will be possible to derive IDL meta information from classes that never originated from or represent IDL types! This will support the development of CORBA objects in Java only -- without ever writing a single line of IDL!
Another consequence of this IR design is the fact that the JacORB IDL compiler does not accept the #pragme prefix directive in IDL files. This directive can be used to set the repository identifier for IDL types. The JacORB IR relies on the equivalence of Java class names and repository identifiers, so naming these apart by using the #pragme prefix directive cannot not be allowed.
The only exception to this is the "built-in" prefix "omg.org" which is specified for the whole CORBA package. JacORB does of course manage repository IDs so that classes in the org.omg package have identifiers that begin with "omg.org" rather than "org/omg".
When providing a class path as an argument to the IR process, a few things need to be considered. First of all, the IR cannot presently handle class archives like .zip, .jar or .cab files. Secondly, providing a class path made up of directories where one is actually a subdirectory of another will lead to confusion. E.g., a class path like /home/jim/JacORB:/home/jim/JacORB/classes will lead to such problems.
Basically, there are two ways to access the Interface Repository, as was already pointed out above. Let's look at two examples for contacting the IR.
In the following code fragment a client wishes to obtain interface information about some object reference it has just received from the name server. It retrieves the InterfaceDef object and prints out its ID:
org.omg.CORBA.Object obj = NameServer.locate("SomeUnknownServer")); // get the server object's interface definition // in the Interface Repository InterfaceDef i_def = obj._get_interface(); if( i_def != null ) System.out.println("ID: " + i_def.id() );
The InterfaceDef object describing a particular IDL interface type contains enough information about the type to, e.g. reconstruct the textual IDL definition, so the client could do the following:
// print it to the screen using the IdlWriter class // (with an indentation of 2) IdlWriter idlw = new IdlWriter(System.out); idlw.printInterface( i_def, 2 );
This will print the IDL defintion of the object's interface to the screen.
The IR can also be queried directly, using operations to lookup names and return collections describing the IR contents. This canbe done from any client program that holds a reference to the IR.
JacORB also comes with a little utility program qir that allows to lookup repository identifiers from the command line and display the corresponding IDL definition on the terminal:
$ qir "IDL:omg.org/GIOP/LocateStatusType:1.0"
will print:
enum LocateStatusType {UNKNOWN_OBJECT,OBJECT_HERE,OBJECT_FORWARD};
The Java code for this little program is given below. The program retrieves the reference to the IR using a proprietary JacORB API. It could also have used the standard operation orb.resolve_initial_reference("InterfaceRepository").
It then looks up the ID given on the command line and prints the result using the JacORB IdlWriter class.
package jacorb.Orb.IR; import java.io.*; import org.omg.CORBA.Contained; import org.omg.CORBA.Repository; public class QueryIR { public static void main( String[] args ) { if( args.length != 1 ) { System.err.println("Usage: qir <RepositoryID>"); System.exit(1); } try { Repository ir = jacorb.Orb.IR.Repository.getRepository(); Contained c = ir.lookup_id( args[0] ); if( c != null ) { IdlWriter idlw = new IdlWriter(System.out); idlw.printContained( c, 2 ); } else System.out.println( args[0] + " not found in IR."); } catch ( Exception e){ e.printStackTrace(); } } }