prompt> idltojava -fno-cpp Count.idl
If you need a preprocessor (to process directives like #include, #pragma, etc.), then you need to note the following.
idltojava is hard-coded to use a default preprocessor. On Solaris machines, it uses the path /usr/ccs/lib/cpp when looking for the preprocessor. On Wintel machines, it is hard-coded to use the MS Visual C++ preprocessor.
You can change the preprocessor that idltojava uses by setting two environment variables:
Windows 95 --in your autoexec.bat file, type something like the following:
prompt> set CPP=\usr\share\lib\cpp prompt> set CPPARGS=/nologo
For Borland C++ compiler, the following will do:
prompt> set CPP=\BC5\bin\cpp32.exe prompt> set CPPARGS=-P- -oCONNT --go to Control Panel-->System and click on the Environment tab; then set the environment variables
Examples for Solaris users:
C shell --in your .cshrc file, type something like
prompt> setenv CPP /usr/ccs/lib/cpp prompt> setenv CPPARGS -BCYBourne or Korn shells --in your .profile file, type something like
prompt> CPP=/usr/ccs/lib/cpp prompt> export CPP prompt> CPPARGS=-BCY prompt> export CPPARGSIn the example above, B tells the preprocessor to support C++ style comments (// to indicate that the rest of the line is a comment), C tells the preprocessor to leave comments in the preprocessed file, and Y tells the preprocessor not to bother looking at standard input files (such as /usr/include) since they are mostly C header files.
When you run idltojava with these two environment variables
set, and the flag -fcpp is ON, idltojava will automatically
use the preprocessor you specified in CPP and pass it the arguments
you put in CPPARGS.
package Counter;
public interface Count
extends org.omg.CORBA.Object
{
int sum();
void sum(int arg);
void increment(int val)
;
}
prompt> javac *.java Counter/*.java
The Nameservice stores object references by name in a tree structure
similar to a file directory. A client may lookup or resolve object
references by name.
The Nameservice implements two CORBA objects: NamingContext (nc), which
is analagous to a directory, and BindingIterator(bi), which is
analagous to a file. Each BindingIterator instance represents a name/object
reference pair.
Note that NamingContexts and BindingIterators are transient objects
themselves and that the entire directory structure is lost each time
tnameserv stops running.
To resolve a name is to determine the object associated with the name in a given context. To bind a name is to create a name binding in a given context. A name is always resolved relative to a context -- there are no absolute names.
Because a context is like any other object, it can also be bound to a name in a naming context. Binding contexts in other contexts creates a naming graph (as in a file system, inserting directories in directories creates a naming graph). A naming graph allows more complex names to reference an object. Given a context in a naming graph, a sequence of names can reference an object. This sequence of names (called a compound name) defines a path in the naming graph to navigate the resolution process.
A name with a single component is called a simple name; a name with multiple components is called a compound name. Each component except the last is used to name a context; the last component denotes the bound object. The notation:
< component1 ; component2 ; component3 >indicates the sequences of components.
Note: The semicolon (;) characters are simply the notation used in this document and are not intended to imply that names are sequences of characters separated by semicolons.
A name component consists of two attributes: the identifier attribute and the kind attribute. Both the identifier attribute and the kind attribute are represented as IDL strings.
Note: When the Java IDL name server evaluates a name, it examines both the identifier and kind attributes. Both must match for a name match to result.
The kind attribute adds descriptive power to names in a syntax-independent way. Examples of the value of the kind attribute include c_source, object_code, executable, postscript, or " ". The naming system does not interpret, assign, or manage these values in any way. Higher levels of software may make policies about the use and management of these values. This feature addresses the needs of applications that use syntactic naming conventions to distinguish related objects. For example, UNIX uses suffixes such as .c and .o. Applications (such as the C compiler) depend on these syntactic conventions to make name transformations (for example, to transform foo.c to foo.o).
The lack of name syntax is especially important when considering internationalization issues. Software that does not depend on the syntactic conventions for names does not have to be changed when it is localized for a natural language that has different syntactic conventions -- unlike software that does depend on the syntactic conventions (which must be changed to adopt to new conventions).
To avoid issues of differing name syntax, the Naming Service always deals with names in their structural form (that is, there are no canonical syntaxes or distinguished meta characters). It is assumed that various programs and system services will map names from the representation into the structural form in a manner that is convenient to them.
If the version for JDK 1.1.x is used, then nameserv.bat should be used instead of tnameserv to start the name server.
If another port is needed, then the following sequence of commands can be used:
prompt> start tnameserv -ORBInitialPort 1050
prompt> start java HelloServer -ORBInitialPort 1050
prompt> java HelloClient -ORBInitialPort 1050
The programs use org.omg.CORBA.InitialPort property to indicate the port to the ORB.
A dynamic client can be used as well:
prompt> start tnameserv
prompt> start java CountServer
prompt> java CountClientDII
There is also a server that uses Dynamic Skeleton Interface (DSI), which can be used with both static and dynamic clients. An additional client CountClientDIIDSI obtains object reference from a file written by the server:
prompt> start tnameserv
prompt> start java CountDSIServer
prompt> java CountClient
[...]
prompt> java CountClientDII
[...]
prompt> java CountClientDIIDSI
[...]
module Counter
{
interface Count
{
attribute long sum;
void increment(in long val);
};
};
// CountImpl.java: The Count Implementation
import Counter.*;
public class CountImpl extends _CountImplBase
{
private int sum;
// Constructor
CountImpl()
{
System.out.println("Count Object Created");
sum = 0;
}
// get sum
public int sum()
{
return sum;
}
// set sum
public void sum(int val)
{
sum = val;
}
// increment method
public void increment(int step)
{
sum = sum + step;
}
}
import Counter.*;
// The package containing our stubs.
import org.omg.CosNaming.*; // CountClient will use the naming
service.
import org.omg.CORBA.*; // All CORBA
applications need these classes.
public class CountServer {
public static void main(String args[])
{
try
{
// create
and initialize the ORB
ORB orb
= ORB.init(args, null);
// create
servant and register it with the ORB
CountImpl
countRef = new CountImpl();
orb.connect(countRef);
// get the
root naming context
org.omg.CORBA.Object
objRef = orb.resolve_initial_references("NameService");
NamingContext
ncRef = NamingContextHelper.narrow(objRef);
// bind the
Object Reference in Naming
NameComponent
nc = new NameComponent("Count", "");
NameComponent
path[] = {nc};
ncRef.rebind(path,
countRef);
// wait for
invocations from clients
java.lang.Object
sync = new java.lang.Object();
synchronized
(sync)
{
sync.wait();
}
}
catch (Exception e)
{
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}
}
import Counter.*;
// The package containing our stubs.
import org.omg.CosNaming.*; // CountClient will use the naming
service.
import org.omg.CORBA.*; // All CORBA
applications need these classes.
public class CountClient
{
public static void main(String args[])
{
try
{
// Initialize the ORB
System.out.println("Initializing
the ORB");
ORB orb = ORB.init(args, null);
// Bind to the Count Object
System.out.println("Initializing
naming services");
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
System.out.println("Obtaining naming
context");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
System.out.println("Binding the
Count object");
NameComponent nc = new NameComponent("Count",
"");
NameComponent path[] = {nc};
Count counter = CountHelper.narrow(ncRef.resolve(path));
// Set sum to initial value of 0
System.out.println("Setting sum
to 0");
counter.sum((int)0);
// Calculate Start time
long startTime = System.currentTimeMillis();
// Increment 1000 times
System.out.println("Incrementing");
for (int i = 0 ; i < 1000 ; i++
)
{
counter.increment((int)5);
}
// Calculate stop time; print out
statistics
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f) + " msecs");
System.out.println("Sum = " + counter.sum());
}
catch(Exception e)
{
System.out.println("ERROR
: " + e);
e.printStackTrace(System.out);
}
}
}
// CountClientDII.java: The DII Count Client main program
import Counter.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
import java.io.*;
public class CountClientDII
{
public static void main(String args[])
{
try
{
// create and initialize the ORB
System.out.println("Initializing
the ORB");
ORB orb = ORB.init(args, null);
System.out.println("Listing initial
services");
String[] listOfServices = orb.list_initial_services();
for (int i = 0; i < listOfServices.length;
i++)
System.out.println(listOfServices[i++]);
// get the root naming context
System.out.println("Resolving initial
references");
org.omg.CORBA.Object objRef = orb.resolve_initial_references(listOfServices[0]);
NamingContext ncRef = NamingContextHelper.narrow(objRef);
// resolve the Object Reference in
Naming
System.out.println("Resolving object
reference");
NameComponent nc = new NameComponent("Count",
"");
NameComponent path[] = {nc};
Count counterRef = CountHelper.narrow(ncRef.resolve(path));
/* Here we could use CORBA interface introspection to discover
the interface of the object:
org.omg.CORBA.InterfaceDef interface = counterRef._get_interface();
org.omg.CORBA.InterfaceDefPackage.FullInterfaceDescription
descr = interface.describe_interface()
FullInterfaceDescription includes the following fields:
attributes
base_interfaces
defined_in
id
name
operations
type
version
The fields could be used to construct subsequent requests.
*/
// Create a DII set request and
set the arguments
org.omg.CORBA.Request r = counterRef._request("_set_sum");
r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
Any setVal = r.add_in_arg();
setVal.insert_long(999); // set
to 999
// call the Count server object
r.invoke();
// Create a DII increment request
and set the return value
r = counterRef._request("increment");
r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
//set the parameter
setVal = r.add_in_arg();
setVal.insert_long(4); // increment
by 4
// Calculate Start time
long startTime = System.currentTimeMillis();
// Increment 1000 times
System.out.println("Incrementing");
for (int i = 0 ; i < 1000 ; i++
)
{
// call the Count server
object
r.invoke();
}
// Calculate stop time; print out
statistics
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f) + " msecs");
// get the value of the sum
r = counterRef._request("_get_sum");
r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long));
r.invoke();
// extract the result
int result = r.return_value().extract_long();
System.out.println("Sum: " + result);
}
catch (Exception e)
{
System.out.println("CountClient
: Exception: " + e) ;
e.printStackTrace(System.out);
}
}
}
// CountClientDII.java: The DII Count Client main program
import Counter.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
import java.io.*;
public class CountClientDIIDSI
{
public static void main(String args[])
{
try
{
// create and initialize the ORB
System.out.println("Initializing
the ORB");
ORB orb = ORB.init(args, null);
System.out.println("Listing initial
services");
String[] listOfServices = orb.list_initial_services();
for (int i = 0; i < listOfServices.length;
i++)
System.out.println(listOfServices[i++]);
// get the root naming context
System.out.println("Resolving initial
references");
org.omg.CORBA.Object objRef = orb.resolve_initial_references(listOfServices[0]);
NamingContext ncRef = NamingContextHelper.narrow(objRef);
// Read IOR from file
byte[] iorBytes = new byte[1024];
InputStream f = new FileInputStream(
System.getProperty("user.home") +
System.getProperty("file.separator") + "DSI.ior") ;
DataInputStream in = new DataInputStream(f)
;
int bytesRead = in.read(iorBytes)
;
in.close();
String ior = new String(iorBytes,
0, bytesRead);
System.out.println("Object Ref:
" + ior);
Count counterRef = CountHelper.narrow(orb.string_to_object(ior));
org.omg.CORBA.Request r;
Any setVal;
// Create a DII set request and set
the arguments
r = counterRef._request("_set_sum");
r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
setVal = r.add_in_arg();
setVal.insert_long(999); // set
to 999
// call the Count server object
r.invoke();
// Create a DII increment request
and set the return value
r = counterRef._request("increment");
r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
//set the parameter
setVal = r.add_in_arg();
setVal.insert_long(4); // increment
by 4
// Calculate Start time
long startTime = System.currentTimeMillis();
// Increment 1000 times
System.out.println("Incrementing");
for (int i = 0 ; i < 1000 ; i++
)
{
// call the Count server
object
r.invoke();
}
// Calculate stop time; print out
statistics
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f) + " msecs");
// get the value of the sum
r = counterRef._request("_get_sum");
r.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long));
r.invoke();
// extract the result
int result = r.return_value().extract_long();
System.out.println("Sum: " + result);
}
catch (Exception e)
{
System.out.println("CountClient
: Exception: " + e) ;
e.printStackTrace(System.out);
}
}
}
This bridging application would use DSI to convert a CORBA client request to a format understood by a COM server. And it would use DII to convert a COM client request to a format understood by a CORBA server. The application programmer writes all the code to perform this work.
Contrast this with a typical static object invocation. The server has access to the compiled skeletons for the interfaces being invoked upon. These skeletons are generated by compiling the IDL interface definitions with the idltojava compiler. When the ORB receives a request, it uses the skeleton code to build the operation arguments on the server side and to send back any result.
// Dynamic servant class implementation
class CountDSIServantImpl extends DynamicImplementation {
private int sum;
// Store the repository ID for the interface implemented
static String[] myIds = {"IDL:Counter/Count:1.0"};
// Create a reference to the ORB
ORB orb;
CountDSIServantImpl(ORB orb)
{
System.out.println("Count Object Created");
sum = 0;
this.orb = orb;
}
// Implementation of invoke() for handling dynamic requests
public void invoke(ServerRequest request) {
try
{
// System.out.println("DSI: invoke
called, op = "+ request.op_name());
// Create an NVList to hold the parameters
NVList nvlist = orb.create_list(0);
// An auxiliary object for obtaining
parameters
Any any;
// Check the type of the operation
if (request.op_name().equals("increment")
== true)
{
// Add first argument
to NVList
any = orb.create_any();
any.insert_long((int)0);
nvlist.add_value("val",
any, ARG_IN.value);
request.params(nvlist);
int step = nvlist.item(0).value().extract_long();
// System.err.println("Argument:
In value: step = " + step);
sum = sum + step;
// Set the return value
TypeCode result_tc =
orb.get_primitive_tc(TCKind.tk_void);
Any result_any = orb.create_any();
result_any.type(result_tc);
request.result(result_any);
}
else if (request.op_name().equals("_set_sum")
== true)
{
// Add first argument
to NVList
any = orb.create_any();
any.insert_long((int)0);
nvlist.add_value("val",
any, ARG_IN.value);
request.params(nvlist);
sum = nvlist.item(0).value().extract_long();
// System.err.println("Argument:
In value: " + sum);
// Set the return value
TypeCode result_tc =
orb.get_primitive_tc(TCKind.tk_void);
Any result_any = orb.create_any();
result_any.type(result_tc);
request.result(result_any);
}
else if (request.op_name().equals("_get_sum")
== true)
{
// this is always required
- if no parameters, then use empty nvlist
request.params(nvlist);
System.err.println("Sum: " + sum);
// Set the return value
Any result_any = orb.create_any();
TypeCode result_tc =
orb.get_primitive_tc(TCKind.tk_long);
result_any.type(result_tc);
result_any.insert_long((int)sum);
request.result(result_any);
}
}
catch ( Exception ex ) {
ex.printStackTrace();
System.out.println("CountDSIServer:
Exception thrown: " + ex);
}
}
// Implement the _ids() method to return repository ID of
interface
public String[] _ids() {
return myIds;
}
}
public class CountDSIServer {
public static void main(String[] args)
{
try
{
// Access and initialize the ORB
org.omg.CORBA.ORB orb = ORB.init(args,
null);
// Create an instance of the dynamic
implementation
CountDSIServantImpl countRef = new
CountDSIServantImpl(orb);
// Register the dynamic servant with
the ORB
orb.connect(countRef);
String ior = orb.object_to_string(countRef)
;
System.out.println("IOR is " + ior)
;
// Write IOR into file
// It can be read by a client and
used to re-create object reference
OutputStream f = new FileOutputStream(
System.getProperty("user.home") +
System.getProperty("file.separator") + "DSI.ior") ;
DataOutputStream out = new DataOutputStream(f)
;
out.writeBytes(ior) ;
out.close();
// Alternate code using name services
to pass the object reference
// This lets connect the clients
that use the naming service
// get the root naming context
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
// bind the Object Reference in Naming
NameComponent nc = new NameComponent("Count",
"");
NameComponent path[] = {nc};
ncRef.rebind(path, countRef);
// Wait for requests from client
java.lang.Object sync = new java.lang.Object();
synchronized(sync){
sync.wait();
}
}
catch (Exception ex) {
ex.printStackTrace();
System.err.println("DSIServer: Exception
thrown: " + ex);
}
}
}