Engine Room CORBA

 

 

Overview

Engine Room CORBA is a complete environment for developing and deploying CORBA 2.2 applications. Objects which have been built using Engine Room CORBA are easily accessible by other applications which use the OMG's Internet Inter-ORB Protocol (IIOP). This protocol, which is an Internet version of General Inter-Orb Protocol (GIOP), has become a standard for communication between distributed objects over the Internet.

Engine Room CORBA currently supports four different languages for both client and server development - C, C++, Java and Perl. Each of these languages can be used in either the server or the client side of the distributed object giving a total of sixteen different deployments for you to choose from.

Engine Room CORBA includes a compiler for each language to automatically translate from the OMG's Interface Definition Language (IDL) to the target language. These compilers have all been written in 100% pure Java for maximum portability. An native Object Request Broker (ORB) is provided for each language.

System Requirements

The minimum requirement for Engine Room CORBA is any machine capable of running a Java Virtual Machine. In practice, any machine with less than 32 MB of main memory and a processor less powerful than an Intel 486 66Mhz will be unsuitable for development of CORBA applications. 2 MB of disk space is required for a full installation. A less powerful machine may be used for deployment of C or C++ applications.

Installation

For installation of this product you should have the following tools:

  1. Unzip
  2. Java Virtual Machine (JVM) version 1.1 - 1.2

To run the C/C++ ORB you should have a C/C++ compiler. If you don't have a C compiler then the GNU C compiler is freely available from http://www.gnu.org

To build the C/C++ ORB and the examples you should have a make program. If you don't have a make program then GNU make is freely available from http://www.gnu.org

To run the Perl ORB you should have Perl 5.03. Perl can be obtained from http://www.perl.com - a Win32 version is available from http://www.activestate.com

The full Java Development Kit (JDK) is not required unless you plan to develop Java CORBA objects. Otherwise the Java Runtime Environment (JRE) is sufficient.

To install this product :-

  1. Unzip the distribution file into a temporary directory

  2. Open a shell or DOS prompt and change to that directory

  3. Ensure that a file EngineRoomCORBA.class exists and is accessible from java.Type

    java EngineRoomCORBA


    You will then be prompted for an installation directory into which the product will be installed. If you have any problems using the Java installation you can unzip the file data to a directory of your choice. However, you should use InfoZip with the -a option for best results rather than PKUNZIP.

  4. Change to the directory into which you installed the product.

  5. You should now "source" the environment variables.

    For UNIX Bourne/Korn/Bash shell type
    . ./env.sh

    For UNIX C shell type
    source env.csh

    For NT/Win95 etc. type
    env <dir> where <dir> is the directory in which you installed.

  6. If you wish to develop in C/C++, then you will have to build the DLL or library for your system. This is done from a DOS or UNIX shell using the make program. Depending on your development environment, edit the file gcc.mak for GNU, bc32.mak for Borland C++ or makefile for other UNIX environments. These makefiles are found in the root directory of the distribution. You should examine the first few lines of these files and change the directories and options if necessary. For Visual C++ the root makefile is ms32.mak. However, you will probably not have to edit this. MicroSoft provided a handy batch file for running Visual C++ from make programs - this is called vcvars32.bat a and can be located in the bin sub-directory where Visual C++ was installed. (e.g. this might typically be C:\Programs\Microsoft Visual Studio\MSDev98\bin) You should run this batch file first as it creates environment entries for the PATH, LIB & INCLUDE environment variables which Visual C++ uses to locate its executable, libraries and include files respectively.

    Then change directory to orbsrc.

    For Borland C++ type

    make -f bc32.mak


    For Visual C++ type

    nmake -f ms32.mak


    For GNU C++ type

    make -f gcc.mak

    For UNIX type

    make

    On Win95/98/NT/2000 this will create orb.dll in the bin sub-directory and ORB.LIB in the lib sub-directory. On UNIX this will create liborb.a in the lib sub-directory.

  7. If you wish to use a COS NameServer like tnameserv then you will have to build the client stubs used to communicate with the name server. If you only plan to use C++ then you only have to build this for C++. There is no requirement to build this for Java as they are bundled with the JDK1.2

    i) For C change directory to cos/c

    For Borland C++ type

    make -f bc32.mak

    For Visual C++ type

    nmake -f ms32.mak

    For GNU C type

    make -f gcc.mak

    For UNIX type

    make

    On Win95/98/NT/2000 this will create cosc.lib in the lib sub-directory and on UNIX this will create libcosc.a in the lib sub-directory

    ii) For C++ change directory to cos/cpp

    For Borland C++ type

    make -f bc32.mak

    For Visual C++ type

    nmake -f ms32.mak

    For GNU C++ type

    make -f gcc.mak

    For UNIX type

    make

    On Win95/98/NT/2000 this will create coscpp.lib in the lib sub-directory and on UNIX this will create libcoscpp.a in the lib sub-directory

    iii) For Perl change directory to cos/perl

    type

    make

    On both Win95/98/NT/2000 and UNIX this will Perl modules in the perl sub-directory.

Configuring the Preprocessor

The IDL compilers do not understand 'C' pre-processor directives such as #define, #include e.t.c. If you require your IDL files pre-processed before processing by the IDL compiler, either do this in a separate step or configure the pre-processor by editing the file idl.properties which is found in the root directory of the distribution. Engine Room will then be able to use the pre-processor which was supplied with your C compiler. If you don't have a C compiler then the GNU C compiler is freely available from http://www.gnu.org

edit the line pp=none to point to one of the other entries i.e. pp=pp-ms if you plan to use Visual C++.

Interoperability

Engine Room CORBA has been tested as interoperable with the following ORB's
  1. ORBacus from Object-Oriented Concepts Inc.
  2. The native ORB supplied with the JDK1.2

In addition Engine Room CORBA is interoperable with the basic ORB supplied with
with Netscape Communicator 4 (specifically Communicator 4.06).

These are the only ORBs with which Engine Room CORBA has been tested. However, as Engine Room CORBA uses the standard IIOP it should interoperate with any other ORB.
 

Interoperability Issues

  1. Engine Room CORBA is based on the CORBA 2.2 specification which uses GIOP 1.1. Consequently, Engine Room CORBA uses this protocol as its native protocol. Some ORBs from other venodrs are still using GIOP 1.0 and will respond with a NO_IMPLEMENT exception upon receiving a request using GIOP 1.1. However, Engine Room CORBA clients will detect that the remote server object is a 1.0 object and reply in that protocol assuming the remote ORB has written its IOR correctly. Correspondingly, Engine Room CORBA server objects will reply in GIOP 1.0 protocol to any client objects which make requests in that protocol.

  2. The Engine Room IDL compiler produces the portable java stubs according to the specification which are (surprisingly) not always portable between the various Java ORBs. Specifically, the idltojava compiler supplied by Sun Microsystems uses deprecated interfaces and older versions of Visibroker handles exceptions in a different manner. Due to these differences, you should generate java stubs and interfaces using the idltojava compiler supplied by the ORB vendor.

  3. There may be subtle differences in the generation of complex type codes so that passing Any values which contain complex types may result in the receiving ORB not recognising the incoming value as one that it can handle. While every effort is made to ensure compatibility, in general you should avoid mixing and matching IDL compilers and stubs and Any values with complex types if interoperability is important.
     

Applets

Remember that due to applet security restrictions, the applet may only open a TCP/IP connection with the machine from which it was loaded.

If you wish to use the Engine Room ORB then it's always possible to replace the ORB supplied with older versions of Netscape Communicator 4 (iiop10.jar) with the one supplied i.e. iiop13.jar. The Netscape version is found under ...\Netscape\Communicator\Program\Java\Classes\iiop10.jar. Delete it and copy iiop13.jar into this location.
 
 

Running with Java 2

Java 2 includes an ORB so to use the Engine Room ORB it is necessary to bypass the native ORB. This can be done in a number of ways.

1. Runtime properties

Inititialize the Java ORB by the following code :-
    System.setProperty( "org.omg.CORBA.ORBClass", "com.engroom.CORBA.ERORB" ) ;
    System.setProperty( "org.omg.CORBA.ORBSingletonClass", "com.engroom.CORBA.ORBSingleton" ) ;
    org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( args, null ) ;

2. orb.properties

Create a file called orb.properties containing the following lines
        org.omg.CORBA.ORBClass=com.engroom.CORBA.ERORB 
        org.omg.CORBA.ORBSingletonClass=com.engroom.CORBA.ORBSingleton
and put the file in jre/lib sub-directory of where java was installed. This ensures that all CORBA objects created in that JVM are created with the Engine Room ORB. Don't use this option if you plan to use any java applications which use Sun's ORB - e.g. the name server tnameserv

3. Override the boot class path

This is done by the -Xbootclasspath parameter when running the program. In addition, it is necessary to include the path of interface files so that incoming IOR's can be narrowed.

For example, say you wish to run a file client.class
You installed Engine Room CORBA into directory c:\erc
Your Java Runtime library is in c:\jdk1.3\jre\lib\rt.jar
The files you generated from the IDL are in the same directory as client.class i.e. the dot directory . 

Run with the following command

java -Xbootclasspath:c:\erc\iiop13.jar;c:\jdk1.3\jre\lib\rt.jar;. client

For your convenience there is a batch file runjava.bat or UNIX shell program runjava in the bin subdirectory.

The IDL Compiler


The IDL compiler is used to generate stubs, interfaces and skeletons in the target programming language from IDL. The compiler is invoked as follows :-

    java -DERCORBAD="%ERCORBAD%" idl [ languages ] [ -d directory ][-syntax] [-help] 
        [ -o opfile ] -D"prop=val" [-client-] [-server-] [-w-] inputfile 

The construct -DERCORBAD="‹loc›" sets an environment variable within the Java Virtual Machine (JVM). This is the preferred method on the Java 2 environment. For your convenience, a batch file idlc.bat on Win32 or a shell file idlc on UNIX has been created. (You may have to modify the UNIX file if your Bourne shell is not /bin/sh) Normally the ‹loc› tag should be set to the environment variable %ERCORBAD% on Win32 ($ERCORBAD on UNIX). This is to enable the IDL compiler to find its properties file idl.properties. However, if you wish to use different properties files for different projects this may point to wherever the location of idl.properties is. Throughout this manual you will normally see the idlc command being used rather than the longhand version.

The [ languages ] parameter is the output language. Only one of these should be present each time the compiler is run.

This may be :-

-c Output in the 'C' programming language
-c++
Output in the C++ programming language
-namespace Generate namespace code. By default, modules are generated as namespaces. If this flag is set, namespace contstructs are used. Older compilers may not support this.
-namespace- Generate modules as classes
-vc Generate Visual C++ code.

 

-perl Output in the Perl programming language
-java Output in the Java programming language
-vc++ Visual C++ (equivalent to -cpp -vc)

 

The -d parameter indicates the directory to which output files are written. The directory name may follow the -d parameter with or without an intervening space. Both DOS (\) and UNIX (/) file separators may be used.

e.g. -d\tmp , -d /tmp and -d \tmp are equivalent.

The -syntax parameter indicates that the IDL file is to be checked for syntax only. If an output langauge has been chosen it will be ignored.

The -help parameter prints the help screen on the console and then the program exits.

The -o parameter sets the base file name when generating 'C' code. This parameter is deprecated.

The -client- parameter inhibits generation of client code in C/C++ generation

The -server- parameter inhibits generation of server code in C/C++ generation

The -w- option stops warning from being printed and -w2000 stops warning 2000 from being printed. The default for this parameter is -w which prints all warnings.

The last parameter on the command line is the name of the IDL file to be processed. If no file name is given, input is read from standard input.

Files Produced By The IDL compiler

The purpose of the IDL compiler is to produce files to manage the connection and execution of operations on distributed objects. Each different language binding produces files depending on the structure of the language.

Files Produced By 'C' Generation

The 'C' generator produces two header files for each IDL file, two header files for each interface contained in a file, a 'C' file for each IDL files, three 'C' files for each interface and one skeleton file for each interface. Therefore for a file myidl.idl containing an interface called iface1 the following files will be produced.

myidl.h Header file for types in the global module
myidl_i.h Internal Header file
myidl.c 'C' file for types in the global module
iface1.h Header file for types and operations in the interface
iface1_i.h Internal Header file
iface1.c 'C' file for types in types in the interface
iface1_c.c Client side operations and attributes to be linked with the user's client program
iface1_s.c Server side operations and attributes to be linked with the user's server implementation program
iface1.skl A skeleton implementation which may be used for first development of the implementation

 

Files Produced By C++ Generation

The C++ generator produces two header files and three C++ files for each IDL file. Therefore for a file myidl.idl containing an interface called iface1 the following files will be produced.

myidl.h Header file for types in the global module
myidl_i.h Internal Header file
myidl.cpp C++ file for types in the IDL file
myidl_c.cpp Client side operations and attributes to be linked with the user's client program
myidl_s.cpp Server side operations and attributes to be linked with the user's server implementation program
iface1.skl A skeleton implementation which may be used for first development of the implementation

 

Files Produced By Java Generation

The Java generator produces three files for every distinct type defined in the IDL file (including interfaces). Types which are defined in modules are put into a subdirectory (and Java package) of the same name as the module. Each distinct type T will generate a file T.java, a holder file THolder.java and a helper file THelper.java. A distinct type is a type which will not "unwind" into a basic type or previously defined type. So -

typedef short myShort ;       // not a distinct type

struct myStruct { short a ; long b ; } ;     // a distinct type

typedef myStruct t_myStruct ;       // not a distinct type

An interface type IF will also produce a stub class _IFStub.java for the client side and server dispatch class _IFImplBase.java. Therefore for a file myidl.idl containing an interface called iface1 and a distinct type T, the following files will be produced.

T.java Class file for type T
THolder.java Class to assist in passing out and inout parameters of type T
THelper.java Class to read/write instances of type T
iface1.java Class file for type T
iface1Holder.java Class to pass out and inout parameters of type iface1
iface1Helper.java Class to read/write instances of type iface1
_iface1Stub.java Stub class for the client on which to invoke operations
_iface1ImplBase.java Server side object which must be extended by the users implementation class.

 

Files Produced By Perl Generation

The Perl generator produces a file MyIDL_main.pm for the IDL MyIDL.idl file, and a Perl module is generated for each IDL type defined. For each interface IF defined in the IDL file, a server object _IFImplBase.pm is also produced.

Therefore for a file myidl.idl containing an interface called iface1 and a distinct type T, the following files will be produced.

T.pm Perl Module for type T
iface1.pm Perl Module for interface iface1
_iface1ImplBase.pm Server side object which must be extended by the users implementation class.
myidl_main.pm Global level Perl Module. This should be used by both client and server.

 

 

Getting Started

Let's started with a simple example to illustrate CORBA in action. This section assumes that you have installed the product under c:\ercorba. This is an example of a client-server banking application.

In our example application we can create new, or open existing accounts and deposit or withdraw from these accounts. How this is modelled on the server side is immaterial to CORBA. It may use a permanent store to a relational database or load and store to flat files. CORBA is only interested in the interface. The interface is presented below -

interface Account ;

exception NoAccountExists { } ;

exception AccountExists { } ;

interface Bank {
     Account getAccount( in unsigned long accountNum )
        raises( NoAccountExists ) ;
     Account createAccount( in unsigned long accountNum )
        raises( AccountExists ) ;
}
;

exception NotAuthorized {

   string<100> reason ; short code ;
} ;

interface Account {
     readonly attribute long balance ;
     long deposit( in unsigned long val ) ;
     long withdraw( in unsigned long val ) raises( NotAuthorized ) ;
} ;

The first thing to notice about the IDL is that there are two interfaces in it - Account and Bank. IDL Interfaces correspond to the objects we wish to model, in this case a Bank object and an Account object.

Within each interface/object there are a number of operations defined. For the bank object two operations are defined.

  1. createAccount is an operation which will create a new account and accepts one input parameter - the account number by which the new account will be known. Further examination of the operation reveals that it will either raise the exception AccountExists or will return an instance of an Account object. In our implementation it will raise AccountExists if this account number already exists otherwise it will return an instance of an Account object. This is however implementation dependent and it would be possible to perform the opposite action although this would be counter-intuitive.

  2. getAccount is an operation which will return a reference to an existing account and accepts one input parameter - the account number of the account. Further examination of the operation reveals that it will either raise the exception NoAccountExists or will return an instance of an Account object. In our implementation it will raise NoAccountExists if this account does not exist. Otherwise it will return an instance of an Account object.

For the Account object there are two operations and one attribute defined.

  1. The readonly attribute balance can only be read - not set. In our application it will represent the balance of the account.

  2. The operation deposit accepts one input parameter and returns a long value. In our application the input parameter will be the amount to be deposited and the returned value will be the new balance of the account.

  3. The operation withdraw accepts one input parameter and returns a long value. In our application the input parameter will be the amount being withdrawn and the return value will be the new balance of the account. In addition, this operation can raise the NotAuthorized exception. In our application this will occur when there are insufficient funds in the account.

Making and Running the 'C' Programs

The 'C' programs are in the sample/banking/c subdirectory.

Change directory to this location and build the programs by typing

    make -f bc32.mak         (Borland)
  or
    nmake -f ms32.mak        (Microsoft VC++)
  or
    make -f gcc.mak            (GNU C++)  
or
    make                   (Other UNIX)

This should create two executable files client and server (client.exe and server.exe for Win32)

To run the programs you require two shells or MS-DOS prompts in the directory. Type "server" in one and "client" in the other. You should see a bank account being created on the server and then deposits and withdrawals being made.

 

Making and Running the C++ Programs

The C++ programs are in the sample/banking/cpp subdirectory.

Change directory to this location and build the programs by typing :-

    make -f bc32.mak         (Borland)
  or
    nmake -f ms32.mak        (Microsoft VC++)
  or
    make -f gcc.mak            (GNU C++)  
or
    make                   (Other UNIX)

This should create two executable files client and server (client.exe and server.exe for Win32)

To run the programs you require two shells or MS-DOS prompts in the directory. Type "server" in one and "client" in the other. You should see a bank account being created on the server and deposits and withdrawals being made.

Making and Running the Java Programs

The Java programs are in the sample/banking/java subdirectory.

Change directory to this location and depending on whether you have the make program or the nmake program build the programs by typing :-

    make
or
    nmake

This should create a number of Java class files - specifically client.class and server.class

To run the programs you require two shells or MS-DOS prompts in the directory.

If you are using JDK1.1 type "java server" in one and "java client" in the other. If you are using JDK1.2 you have to set the -Xbootclasspath to point to Engine Room CORBA's ORB rather than the native one supplied with the JDK. See the file bin/runjava(.bat) for details of how to do this.

You should see a bank account being created on the server and deposits and withdrawals being made.

On some systems it may be necessary to set the port on which the server listens for incoming object requests. Pass the command line parameter e.g. -ORBport=5000 to set the port used to be 5000. For C/C++ and Perl it is also possible to set the environment variable ER_ORB_PORT to the desired port.

e.g.

java server -ORBport=3500

 

Making and Running the Perl Programs

The Java programs are in the sample/banking/perl subdirectory.

Change directory to this location and depending on whether you have the make program or the nmake program build the programs by typing :-

    make
or
    nmake

This should generate a number of Perl modules.

To run the programs you require two shells or MS-DOS prompts in the directory.

Type perl server.pl in one and perl client.pl in the other. You should see a bank account being created on the server and then deposits and withdrawals being made.

Programming Your Own Objects

To program your own objects you should

  1. Write a description of your interface in IDL

  2.  
  3. Generate the client stubs and servers for the language of your choice.
  4. Type idlc to find out the compiler options.

    i.e, c:>idlc -c -d\tmp myidl

    will write 'C' language client and server stubs into the directory \tmp

    c:>idlc -java -d\tmp myidl

    will write Java client and server stubs into the directory \tmp
     

  5. Write a program to implement the server 

  6. Write a client program to communicate with the server 

  7. For 'C'/C++ programs link your program with orblib.a (UNIX) or orb.lib (Win95/98/NT)
     
  8. Run the server

  9.  
  10. Run the client

ORB Configuration

There are a number of parameters that can be used to configure the ORB. If these parameters are typed in from the command line they should be prefixed with '-'. If they are used in Java property files the leading hyphen is not necessary. These parameters are :-

ORBport Set the port number that the ORB listens on. e.g. -ORBport=5677
ORBhost Set the host name that the ORB will use in any IOR's- This may be a name string or an IP number. This might be used in circumstances where the client of an ORB cannot resolve the default host name of the server. Obviously, the name it is set to must be resolvable by the client for communication to be established. e.g. -ORBhost=localhost
ORBuseipno

Use the default IP number rather than the default hostname in any IOR's. e.g. -ORBuseipno

The effect of this option is undefined when used with the ORBhost option. i.e. don't do it.

ORBtimeout A client will wait indefinitely for a server to respond. Setting this option means that the client ORB will raise a COMM_FAILURE system exception after the specified timeout has expired. e.g. -ORBtimeout=40
ORBInitialHost

This parameter specifies the location of the bootstrap service provider which is called when the ORB::list_initial_services pesudo operation is called. e.g. -ORBInitialHost=www.initserve.com

The default value of this parameter is localhost

ORBInitialPort This parameter specifies the port of the bootstrap service provider which is called when the ORB::list_initial_services pesudo operation is called. e.g. -ORBInitialPort=8010

The default port (and value of this parameter) for this service is 900

Using a Name Server

Java 2 includes a transient name server tnameserv which you can use to manage connections between clients and servers. Example code of how to communicate with this server can be found in the samples/bank2 sub-directory. Make the example programs in the same manner as the bank examples.

1. Run The Name Server

Open a DOS window or UNIX terminal window and run the name server with the following command

    tnameserv -ORBInitialPort 8921

This starts the initial bootstrap server on port 8921. If you miss off the optional -ORBInitialPort parameter the this defaults to port 900

2. Run the server

Open a DOS window or UNIX terminal window in samples/bank2 subdirectory and change directory to c, cpp, java or perl depending on which language you are going to use. All Engine Room ORBs assume that the initial bootstrap server are on port 900 on localhost. However, assuming that the name server was started on a machine called fred on port 8921 then the following commands will start the servers
        java server -ORBInitialHost=fred -ORBInitialPort=8921

for java or

        server -ORBInitialHost=fred -ORBInitialPort=8921

for C and C++ and

        perl server.pl -ORBInitialHost=fred -ORBInitialPort=8921

for Perl

2. Run the client

Open a DOS window or UNIX terminal window in samples/bank2 subdirectory and change directory to c, cpp, java or perl depending on which language you are going to use. Assuming, as before, that the name server was started on a machine called fred on port 8921 then the following commands will start the clients
        java client -ORBInitialHost=fred -ORBInitialPort=8921

for java or

        client -ORBInitialHost=fred -ORBInitialPort=8921

for C and C++ and

        perl client.pl -ORBInitialHost=fred -ORBInitialPort=8921

for Perl

CORBA Programming

The Interoperable Object Reference (IOR)

The IOR is a sequence of characters which uniquely identifies an object. It is used by the client to request a connection to an object. In IIOP the IOR consists of the objects type id, the host name or IP address on which the object can be found, the port on which the object is located and an object key to distinguish it from other objects of the same type which may be present at the same location.

Support and Bug Reporting

Check that the problem still exists in the latest release. The latest release is available from http://www.engroom.com

Check release.txt and the bug list at http://www.engroom.com to make sure that the problem has not already been reported.If the bug is still there then e-mail a short description together with a small piece of code exhibiting the problem if possible to support@engroom.com.

Please state the hardware, operating sysyem and compiler version you're using.
 
 

Copyright © 2000-2001 Engine Room Software Ltd