field-theory.org
the blog of wolfram schroers

Using foreign clients/ORBs

The source code can be downloaded as a gzipped .tar-file.

This is the third part of the CORBA tutorial which implements a distributed object system. This example expands the previous example number two and demonstrates the way in which programs in different languages with different ORBs interact.

The source code has been developed and tested using the mico ORB on MacOS X. This tutorial also uses the Orbit2 ORB (for binding to C) and the Java SDK ORB (for binding to Java). To use either, these two ORBs need to be installed separately. On most MacOS X machines, the Java SDK will be installed with the developer tools so if you got this far chances are good that you do not need to take further action. Orbit2 still needs to be installed which can be done by systems like Fink. On other operating systems, the Makefile(s) may need to be adjusted. The files can also be downloaded on the software section of this site.

Table of contents:

Previously in this tutorial
Implementing the C client
Implementing the Java client
Running the system

Previously in this tutorial

In part two we have defined and implemented an enterprise-wide logging facility using the mico ORB in C++. Now we stay with the very same design, but use clients in different languages and with different ORBs to access the server we have written before.

Technically, the Makefile for the client and the server has been split up into two parts now: Makefile which is solely responsible for the server and Makefile.mico which only compiles the client. The other files that implement the server and the client (protocol.idl, protocol_impl.cc, protocol_impl.h, server.cc and client.cc) are almost unchanged. The only change is a cosmetic renaming of the module to emphasize that we are no longer limited to the mico ORB. Thus, compilation of the previous part is now done via:

  $ make
  $ make -f Makefile.mico

At this point we have a working server and client, both written in C++ using the mico ORB.

Implementing the C client

The C client is named client_orbit2.c and is compiled with Makefile.orbit2:

  $ make -f Makefile.orbit2

Note that the IDL compiler again generates client stubs, but that these are clashing with the ones generated by the C++ IDL compiler. The code compilation is similar later on.

An important caveat exists for the compilation of C and C++ clients in the same directory: the IDL compiler will generate a file named protocol.h in either case which is to be included by the corresponding code. However, these files will usually differ since they are written for different languages. Thus, I had to add some code to the Makefile to make sure that the IDL compiler will always run when the make command is triggered. A different (and somewhat cleaner) solution would be to use separate subdirectories.

When studying the source code client_orbit2.cc it is apparent that it looks similar in structure to the C++ client.cc with some boilerplate initialization code at the top, and a few extra lines of release code at the bottom. The core part with the application logic is again similar.

However, several constructs from C++ don't exist in C. Examine, for example, the following call to the getter method of counter:

 88 fprintf(stdout, "Logging message number #%d\n",
 89         ORBExample_Protocol__get_counter(proto, ev));

The method calls to remote objects have become function calls with rather lengthy names. There is no exception handling and thus no try/catch block. All results from interactions with the remote objects need to be checked manually for exceptions, making the code somewhat more complex and harder to read.

Still, the functionality is all the same even though we are exposed to a slightly lower level of abstraction than in the case of C++.

Implementing the Java client

The Java client is named client_java.java. Compilation proceeds through the corresponding Makefile.java via

  $ make -f Makefile.java

The Java client looks much more similar to the C++ client. All calls are object method invocations and we have explicit try/catch blocks to handle exceptions. The initialization code at the beginning is even a little more concise than in C++ and there is no cleanup at the end because Java has garbage collection. The only difference is that the binary needs to be run with the command interpreter java instead of directly.

Running the system

With the other two clients compiled we can immediately proceed to run all three of them with the server and see for ourselves that the interaction poses no problem and is done very smoothly:

Using CORBA example code 3

This is one of the strongest selling points of CORBA — it is possible to be interoperable not only on the source-code level, but even on the binary level without worrying about differences of the systems that interact.

As an advanced exercise I encourage the reader to try this out using different operating system and even on different hardware. There is no competitor to CORBA that can meet the same degree of power and flexibility while maintaining the level of abstraction in the source code!

Now you can proceed to the final example in part four.