<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
               "http://docbook.org/xml/4.2/docbookx.dtd"
	       [
	       <!ENTITY copyright SYSTEM "copyright.xml">
	       ]>

<chapter title="CORBA and Jini" id="18"> 
<title>
CORBA and Jini
</title>

<tocchap>
<title>
Contents
</title>

<toclevel1>
<tocentry>
  <ulink url="#CORBA">CORBA</ulink>
</tocentry>
<tocentry>
  <ulink url="#CORBA to Java Mapping">CORBA to Java Mapping</ulink>
</tocentry>
<tocentry>
  <ulink url="#Jini Proxies">Jini Proxies</ulink>
</tocentry>
<tocentry>
  <ulink url="#Simple Example">Simple Example</ulink>
  <toclevel2>
  <tocentry>
    <ulink url="#Corba Server in Java">Corba Server in Java</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Corba Client in Java">Corba Client in Java</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Jini Service">Jini Service</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Jini Server and Client">Jini Server and Client</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Building the Example">Building the Example</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Running the Example">Running the Example</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#CORBA Implementations">CORBA Implementations</ulink>
  </tocentry>
  </toclevel2>

</tocentry>
<tocentry>
  <ulink url="#Room Booking Example">Room Booking Example</ulink>
  <toclevel2>
  <tocentry>
    <ulink url="#CORBA Objects">CORBA Objects</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Multiple Objects">Multiple Objects</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Exceptions">Exceptions</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Interfaces for Single Thin Proxy">Interfaces for Single Thin Proxy</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#RoomBookingBridge Implementation">RoomBookingBridge Implementation</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Other Classes">Other Classes</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Building the Example2">Building the Example</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Running the Example2">Running the Example</ulink>
  </tocentry>
  </toclevel2>


</tocentry>
<tocentry>
  <ulink url="#Migrating a CORBA Client to Jini">Migrating a CORBA Client to Jini</ulink>
</tocentry>
<tocentry>
  <ulink url="#Jini Service as a CORBA Object">Jini Service as a CORBA Object</ulink>
</tocentry>
<tocentry>
  <ulink url="#Summary">Summary</ulink>
</tocentry>
</toclevel1>
</tocchap>

<abstract>
<para>

</para>
</abstract>

<sect1>
<title id="CORBA">
CORBA
</title>

<para>
CORBA is also an infrastructure for distributed systems. It is targeted at a
slightly different ``space'' to Jini, and has some minor and major differences.
<orderedlist>
<listitem>
  It allows specification of objects which can be distributed. The concentration
  is on <emphasis>distributed objects</emphasis> rather than on
  <emphasis>distributed services</emphasis>
</listitem>
<listitem>
  It is language-independent, using an Interface Definition Language (IDL) for
  specification of interfaces
</listitem>
<listitem>
  CORBA objects can be implemented in a number of languages, including C, C++,
  SmallTalk and Java
</listitem>
<listitem>
  Current versions of CORBA pass remote object references, rather than complete
  object instances. Each CORBA object lives within a server, and the object can only
  act within this server. This is more restricted than Jini, where an object
  can have instance data and class files sent to a remote location and execute
  there. This limitation in CORBA may change in future with ``pass by value''
  parameters to methods
</listitem>
</orderedlist>
</para>

<para>
IDL is a language that allows the programmer to specify the interfaces of a
distributed object system. The syntax is similar to C++, but does not include
any implementation-level constructs. So it allows definitions of data types
(such as structures and unions), constants, enumerated types, exceptions
and interfaces. Within interfaces it allows declaration of attributes and
operations (methods). The complete IDL specification can be found on the
Object Management Group (OMG) site
<ulink url="http://www.omg.org">http://www.omg.org</ulink>.
</para>

<para>
The book ``Java Programming with CORBA'' by Andreas Vogel and Keith Duddy
(<ulink url="http://www.wiley.com/compbooks/vogel">http://www.wiley.com/compbooks/vogel</ulink>)
contains an example of a room booking service specified in CORBA IDL and
implemented in Java. This defines interfaces for <code>Meeting</code>, a
factory to produce them, <code>MeetingFactory</code> and a <code>Room</code>.
A room may have a number of meetings in slots (hourly throughout the day),
and there are support constants, enumerations and typedefs to support this.
In addition, exceptions may be thrown under various error conditions.
The IDL that follows differs slightly from that given in the book, in that
definitions of some data types that occur within interfaces have been
``lifted'' to a more global level, since the mapping from IDL to 
Java has changed slightly for elements nested within interfaces 
since that book was written.
<programlisting>
<?program "corba/RoomBooking.idl"?>
</programlisting>
</para>

</sect1>

<sect1>
<title id="CORBA to Java Mapping">
CORBA to Java Mapping
</title>

<para>
CORBA has bindings to a number of languages. The most recent addition is Java,
and this binding is still under active development (that is, the core is basically
settled, but some parts are still changing). This binding must cover all elements
of IDL. A horribly brief summary is:
<dl>
<dt>
Module
</dt>
  <dd>
  A module is translated to a java package. All elements within the module
  becomes classes or interfaces within the package
  </dd>

<dt>
Basic types
</dt>
  <dd>
  Most of the basic types map in a straightforward manner: a CORBA <code>int</code>
  becomes a Java <code>int</code>, a CORBA <code>string</code> becomes a Java
  <code>java.lang.String</code>, and so on. Some are a little tricky, such as 
  the unsigned types which have no Java equivalent.
  </dd>

<dt>
Constant
</dt>
  <dd>
  Constants within a CORBA IDL interface are mapped to constants within the
  corresponding Java interface. Constants which are ``global'' have no direct
  equivalent in Java, and so are mapped to Java interfaces with a single field
  which is the value.
  </dd>

<dt>
Enum
</dt>
  <dd>
  Enumerated types have no direct Java equivalent, and so are mapped into a
  Java interface with the enumeration as a set of integer constants.
  </dd>

<dt>
Struct
</dt>
  <dd>
  A CORBA IDL structure is implemented as a Java class with instance variables
  for all fields.
  </dd>

<dt>
Interface
</dt>
  <dd>
  A CORBA IDL interface translates into a Java interface.
  </dd>

<dt>
Exception
</dt>
  <dd>
  A CORBA IDL exception maps to a final Java class.
  </dd>
</dl>
This mapping does not conform to naming conventions such as those established for
Java Beans. For example, the IDL declaration <code>readonly string purpose</code>
becomes the Java accessor method <code>String purpose()</code> rather than 
<code>String getPurpose()</code>. Where Java  code is generated, the generated
names will be used. But in ``ordinary'' methods, I shall use the more accepted
naming forms.

</para>

</sect1>

<sect1>
<title id="Jini Proxies">
Jini Proxies
</title>
<para>
A Jini service exports a proxy object that acts within the client, on behalf
of the service. On the service provider side there may be service backend
objects, completing the service implementation.
The proxy may be ``fat'' or ``thin'', depending on circumstances.
In the chapter on MindStorms, the proxy has to be thin, since all it does
is pass on requests to the service backend, which is linked to the hardware device.
The service cannot move since it has to talk to a particular serial port, so the
proxy is thin. (The proxy may have an extensive user interface, but the Jini
community seems to feel that any user interface should be in <code>Entry</code>
objects rather than in the proxy itself.) Proxy objects created as RMI proxies are
similarly thin, just passing on method calls to the service backend, implemented
as remote objects.
</para>

<para>
CORBA services can be delivered to any accessible client. 
Each service is limited to the server on which it is running, so they are
essentially immobile. They can be <emphasis>found</emphasis> by a variety
of methods, such as a CORBA naming or trading service. These search methods can be run
by any client, anywhere. A search will return a reference to a remote object,
which is essentially a thin proxy to the CORBA service. Similarly, if a CORBA
method call creates and returns an object, then it will return a remote reference
to that object which will continue to exist on the server where it was created.
(The new CORBA standards will allow objects to be returned by 
<emphasis>value</emphasis>. This is not yet commonplace, and will probably be
restricted to a few languages such as C++ and Java.)
</para>

<para>
The simplest way to make a CORBA object available to a Jini federation is
to build a Jini <emphasis>service</emphasis> that is at the same time a
CORBA <emphasis>client</emphasis>. The service acts as a <emphasis>bridge</emphasis>
between the two protocols. Really, this is just the same as MindStorms - anything
that requires talking a different protocol (hardware or software) will require a bridge
between the two.
</para>

<para>
Most CORBA implementations use IIOP - that is, they are TCP based. The current
Jini implementation is also TCP based. So there is a confluence of transport
methods, which normally would not occur. A bridge would usually be fixed
to a particular piece of hardware, but here it is not necessary due to
this confluence.
</para>

<para>A Jini service has a lot of flexibility in implementation,
and can choose to place logic in the proxy, in the backend, or any where else
for that matter! The combination of Jini flexibility and IIOP allows a larger
variety of implementation possibilities than can be done with fixed pieces
of hardware such as MindStorms. For example
<orderedlist>
<listitem>
  The Jini proxy can invoke the CORBA naming service lookup to locate the CORBA
  service, and then makes calls directly
  on the CORBA service from the client. 
  This is a ``fat'' proxy model in which the proxy contains
  all of the service implementation. There is no need for a service backend,
  and the service provider just exports the service object as proxy and then
  keeps the leases for the lookup services alive
</listitem>
<listitem>
  The Jini proxy can be an RMI stub, passing on all method calls to a  
  backend service running as an RMI remote object in the service provider.
  This is a ``thin'' proxy with ``fat'' backend, where all service implementation
  is done on the backend. The backend uses the CORBA naming service lookup
  to find the CORBA service and
  then makes calls on this CORBA service from the backend
</listitem>
</orderedlist>

<!--
A Jini proxy
need not report back to its server since it can negotiate directly with the
CORBA service over the TCP network. In many instances it can be a ``fat'' proxy
containing all of the service implementation.
This is similar in concept to the fat proxy in the chapter on Service Choices: 
there the fat
proxy used HTTP to talk to a service within another protocol, but this can 
also be done with the CORBA protocols.
</para>

<para>
A ``thin'' proxy passes on requests to service backend objects running
in the service provider.
A proxy may need to be thin in some cases such as when it is used by an applet:
security restrictions may mean that it cannot talk to any host but only to the
one the applet came from. In such a case the service would have to perform all CORBA
client activities back on its ``home'' server, using backend objects.
-->
</para>

</sect1>

<sect1>
<title id="Simple Example">
Simple Example
</title>

<para>
The CORBA IDL tutorial at
<ulink url="http://java.sun.com/products/jdk/1.2/docs/guide/idl/">
http://java.sun.com/products/jdk/1.2/docs/guide/idl/
</ulink>
gives a ``hello world'' example. This is defined by the IDL
<programlisting>
<?program "corba/Hello.idl"?>
</programlisting>
This can be compiled into Java using a compiler such as Sun's
<code>idltojava</code> (or other Corba 2.2 compliant compiler).
This results in a package <code>corba.HelloApp</code> containing a number of
classes and interfaces. <code>Hello</code> is an interface which is used
by a CORBA client (in Java).
<programlisting>
<?program "corba/HelloApp/Hello.java"?>
</programlisting>
</para>

<sect2>
<title id="Corba Server in Java">
Corba Server in Java
</title>

<para>
A server for the hello IDL can be written in any language with a CORBA
binding, such as C++. Rather than get diverted into other languages,
though, we shall stick to a Java implementation. However, this language
choice is not forced on us by CORBA.
</para>

<para>
The server must create an object that implements the <code>Hello</code>
interface. This is done by creating a <emphasis>servant</emphasis> that
inherits from the <code>_HelloImplBase</code>, and then registering
it with the CORBA ORB (Object Request Broker - the CORBA ``backplane'').
The server must also find a name server and register the name and the
implementation. The servant implements the <code>Hello</code> interface.
The server can just sleep to continue existence after registering
the servant.
<programlisting>
<?program "corba/CorbaHelloServer.java"?>
</programlisting>

</para>
</sect2>

<sect2>
<title id="Corba Client in Java">
Corba Client in Java
</title>

<para>
A standalone client finds a proxy implementing the <code>Hello</code>
interface by methods such as looking up a CORBA name server. The name server
returns a  <code>org.omg.CORBA.Object</code> which is cast to the interface type by
the <code>HelloHelper</code> method <code>narrow()</code> (the Java cast
method is not used).
This proxy object can then be used to call methods back in the CORBA server
<programlisting>
<?program "corba/CorbaHelloClient.java"?>
</programlisting>
</para>
</sect2>

<sect2>
<title id="Jini Service">
Jini Service
</title>

<para>
In order to make the CORBA object accessible to the Jini world, it must be
turned into a Jini service. At the same time it must remain in a CORBA server,
so that it can be used by ordinary CORBA clients. So we do nothing to the
CORBA server. Instead, we need to build a Jini service that will act as a
CORBA <emphasis>client</emphasis>. This service will then be able to deliver
the CORBA service to Jini clients.
</para>

<para>
The Jini service can be implemented as a fat proxy delivered to a Jini client.
The Jini service implementation is moved from Jini server to Jini client as 
the service object. 
Once in the client it is responsible for locating the CORBA service using the CORBA
naming service, and then translates client calls on the Jini service directly
into calls on the CORBA service.
The processes
that run in this, with their associated Jini and CORBA objects, are shown in
figure <xref linkend="hello"/>.
<figure id="hello">
<graphic fileref="images/FatCorbaHello.gif" align="center"> </graphic>
<title>CORBA and Jini services</title>
</figure>
</para>

<para>
The Java interface for this service is quite simple, and basically just copies
the interface for the CORBA service, as
<programlisting>
<?program "corba/JavaHello.java"?>
</programlisting>
The method <code>sayHello()</code> for the CORBA IDL returns a <code>string</code>.
In the Java binding this becomes an ordinary Java <code>String</code>, and the
Jini service can just use this type. The next example will show a more complex
case where CORBA objects may get returned. Note that as a ``fat'' service,
any implementation will get moved across to a Jini client and will run there.
So the service only needs to implement <code>Serializable</code>, and its methods do
not need to throw <code>Remote</code> exceptions since they will run locally
in the client.
</para>

<para>
The implementation of this Jini interface will basically act as a CORBA client.
Its <code>sayHello()</code> method 
will contact the CORBA naming service, find a reference to the CORBA
<code>Hello</code> object and call <emphasis>its</emphasis> <code>sayHello()</code>
method. The Jini service can just return the string it gets from the CORBA service.
<programlisting>
<?program "corba/JavaHelloImpl.java"?>
</programlisting>
</para>


</sect2>

<sect2>
<title id="Jini Server and Client">
Jini Server and Client
</title>
<para>
The Jini server which exports the service doesn't contain anything new
compared to the other service providers we have discussed. It creates
a new <code>JavaHelloImpl</code> object and exports it using e.g.
a <code>JoinManager</code>
<programlisting>
joinMgr = new JoinManager(new JavaHelloImpl(argv), ...)
</programlisting>

</para>

<para>
Similarly, the Jini client doesn't contain anything new, except to catch CORBA
exceptions. After lookup discovery, the code is
<programlisting>
            try {
                hello = (JavaHello) registrar.lookup(template);
            } catch(java.rmi.RemoteException e) {
                e.printStackTrace();
                System.exit(2);
            }
            if (hello == null) {
                System.out.println("hello null");
                return;
            }
            String msg;
            try {
                msg = hello.sayHello();
                System.out.println(msg);
            } catch(Exception e) {
                // we may get a CORBA runtime error
                System.err.println(e.toString());
            }
</programlisting>

</para>


</sect2>

<sect2>
<title id="Building the Example">
Building the Example
</title>
<para>

The major additional step is to build the Java classes from the IDL specification.
There are a number of CORBA IDL to Java compilers. One of these
is the Sun compiler <code>idltojava</code> which is available from
<code>java.sun.com</code>. This (or another compiler) needs to be run on the
IDL file to produce the Java files in the package <code>corba.HelloApp</code>.
These are standard Java files, and can be compiled using your normal Java
compiler. They may need some CORBA files in the classpath if required by your
vendor's implementation of CORBA. Files produced by <code>idltojava</code> do
not need any extra classes.
</para>

<para>
The Jini server, service and client are also normal Java files, and can be compiled
like earlier Jini files, with the classpath set to include the Jini libraries.
</para>

</sect2>

<sect2>
<title id="Running the Example">
Running the Example
</title>
<para>
There are a large number of elements and processes that must be set running to
get this running satisfactorily

<orderedlist>
<listitem>
  A CORBA name server must be set running. In the JDK 1.2 distribution is a server,
  <code>tnameserv</code>. By default this runs on TCP port 900. Under Unix access
  to this port is restricted to system supervisors. It can be set running on this
  port by a supervisor, or started during boot time. An ordinary user will need
  to use the option <code>-ORBInitialPort port</code> to run it on a port above 1024.
  For example,
<programlisting>
tnameserv -ORBInitialPort 1055
</programlisting>
  All CORBA services and clients should also use this port number
</listitem>
<listitem>
  The Java version of the CORBA service can then be started by
  <programlisting>
java corba.CorbaHelloServer -ORBInitialPort 1055
  </programlisting>
</listitem>
<listitem>
  Typical Jini support services will need to be running, such as a Jini lookup service,
  the RMI daemon <code>rmid</code>, and HTTP servers to move class definitions
  around
</listitem>
<listitem>
  The Jini service can be started by
  <programlisting>
java corba.JavaHelloServer -ORBInitialPort 1055
  </programlisting>
</listitem>
<listitem>
  Finally, the Jini client can be run by
  <programlisting>
java client.TestCorbaHello -ORBInitialPort 1055
  </programlisting>
</listitem>

</orderedlist>
</para>

</sect2>

<sect2>
<title id="CORBA Implementations">
CORBA Implementations
</title>

<para>
There are interesting issues about what is needed in Java to support CORBA.
The example discussed above uses the CORBA API's that are part of the standard OMG binding
of CORBA to Java. The packages rooted in <code>org.omg</code> are in major distributions
of JDK 1.2, such as the Sun SDK. The example should compile okay with most Java 1.2
compilers with these OMG classes.
</para>

<para>
Sun's JDK 1.2 runtime includes a CORBA ORB, and the example will run as is using
this ORB.
However, there are many implementations of CORBA ORB's, and they do not always
behave in quite the same way. This can affect compilation and runtime aspects.
The actual CORBA ORB used is determined at runtime, based on properties.
If a particular ORB is not specified, then it defaults to the Sun supplied ORB
(using Sun's SDK). To use another ORB, such as the Orbacus ORB, the following
needs to be inserted <emphasis>before</emphasis> the call to <code>ORB.init()</code>:
<programlisting>
        java.util.Properties props = System.getProperties();
        props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORB");
        props.put("org.omg.CORBA.ORBSingletonClass",
                  "com.ooc.CORBA.ORBSingleton");
        System.setProperties(props);
</programlisting>
Similar code is required for the ORBS from IONA and other vendors.
</para>

<para>
This could affect the runtime behaviour of the client: if the proxy expects
to use a particular ORB apart from the default, 
then the class files for that ORB must be available
to the client or be downloadable across the network. Alternatively, the proxy
could be written to use the default Sun ORB,  and then may need to make
inter-ORB calls between the Sun ORB and the actual ORB used by the CORBA
service. Such issues take us beyond the scope of this chapter, though!
</para>

</sect2>
</sect1>



<sect1>
<title id="Room Booking Example">
Room Booking Example
</title>

<para>
The IDL for a room booking problem was briefly discussed in an earlier section.
This has a few more complexities over the previous example.
The problem is to have a set of rooms, and for each room a set of bookings
that can be made on that room. The bookings may be made on the hour, from
9am till 4pm (this only covers the bookings for one day). Bookings once made
may be cancelled. A room can be queried for the set of bookings it has: it 
returns an array of meetings, which are <code>null</code> if no booking has
been made, or a non-null meeting which has details of the participants and
the purpose of the meeting.
</para>

<para>
The additional features of this example are
<orderedlist>
<listitem>
  Each room is implemented as a separate CORBA object. There is also a ``meeting
  factory'' which produces more objects. This is a system with multiple CORBA
  objects residing on many CORBA servers. There are several possibilities
  for dealing with multiple objects
</listitem>
<listitem>
  Some of the methods return CORBA objects. These may need to be exposed to clients.
  This is not a problem if the client is a CORBA client, but here we will have
  Jini clients
</listitem>
<listitem>
  Some of the methods throw user-defined exceptions, in addition to CORBA-defined
  exceptions. Both of these need to be handled appropriately
</listitem>
</orderedlist>
</para>

<sect2>
<title  id="CORBA Objects">
CORBA Objects
</title>

<para>
CORBA defines a set of ``primitive'' types such as integers of various sizes,
chars, <emphasis>etc</emphasis>. The language bindings specify the primitive
types they turn into for each language. For example, the CORBA wide
character <code>wchar</code> becomes a Java Unicode <code>char</code>.
Things are different for non-primitive objects, though.
</para>

<para>
The IDL for the room booking defines CORBA interfaces for <code>Meeting</code>,
<code>MeetingFactory</code> and <code>Room</code>. The implementation of these
can be in any suitable language, and need not be in Java. The Java binding will
convert these into Java interfaces. A CORBA client written in Java will get objects
that implement these interfaces, but these will essentially be just references to
remote CORBA objects. Two things are certain about these references:
<orderedlist>
<listitem>
  CORBA interfaces generate Java interfaces such as <code>Hello</code>.
  These inherit from <code>org.omg.CORBA.portable.IDLEntity</code>,
  which implements <code>Serializable</code>.
  So the references can be moved around like Jini objects. But they lose their link to
  the CORBA ORB that created them, and may end up in a different ``namespace''
  where the reference makes no sense. So CORBA references cannot be usefully
  moved around.
  The closest one can come at present is to convert them to
  ``string-ified'' form and move that around. This may change when CORBA pass-by-value
  objects become common. Note that the serialization method that gives a string
  representation of a CORBA object is not the same as the Java one: the CORBA method
  serializes the remote reference, the Java method serializes the object's instance
  data
</listitem>
<listitem>
  They do not subclass from <code>UnicastRemoteObject</code> or 
  <code>Activatable</code>. The Java runtime will not use an RMI stub for them
</listitem>
</orderedlist>
</para>

<para>
If a Jini client gets local references to these objects, and keeps them local,
then it can use them <emphasis>via</emphasis> their Java interfaces. If they
need to be moved around the network, then appropriate ``mobile'' classes will
need to be defined and the information copied across to them from the local
objects. For example, the CORBA <code>Meeting</code> interface generates the
Java interface
<programlisting>
<?program "corba/RoomBooking/Meeting.java"?>
</programlisting>
To make the <emphasis>information</emphasis> from a CORBA <code>Meeting</code> available as 
a mobile Jini object, we would need an interface
<programlisting>
<?program "corba/common/JavaMeeting.java"?>
</programlisting>
The first two methods allow information about a meeting to be accessible to applications
that do not want to contact the CORBA service, and the third allows a CORBA object
reference to be reconstructed within a new ORB.
A suitable implementation is
<programlisting>
<?program "corba/RoomBookingImpl/JavaMeetingImpl.java"?>
</programlisting>
</para>

</sect2>

<sect2>
<title id="Multiple Objects">
Multiple Objects
</title>
<para>
The implementation of the room booking problem in the Vogel and Duddy book
runs each room as a separate CORBA object, each with its own server.
A meeting factory creates meeting objects which are kept within the factory server, 
and passed around by reference.
So for a distributed application with ten rooms, 
there will be eleven CORBA servers running.
</para>

<para>
There are several possible ways of bringing this set of objects into the
Jini world so that they are accessible to a Jini client, including
<orderedlist>
<listitem>
  A Jini server may exist for each CORBA server
  <orderedlist>
  <listitem>
    Each Jini server may export fat proxies, which build CORBA references
    in the same Jini client
  </listitem>
  <listitem>
    Each Jini server may export a thin proxy, with a CORBA reference held in
    each of these servers
  </listitem>
  </orderedlist>
</listitem>
<listitem>
  A single Jini server may be built for the federation of <emphasis>all</emphasis>
  the CORBA objects
  <orderedlist>
  <listitem>
    The single Jini server exports a fat proxy, which builds CORBA references in the
    Jini client
  </listitem>
  <listitem>
    The single Jini server exports a thin proxy, with all CORBA references within
    this single server
  </listitem>
  </orderedlist>

</listitem>
</orderedlist>
The first of these essentially isolates each CORBA service into its own Jini service.
This may be appropriate in an open-ended system where they may be a large set of
CORBA services, only some of which are needed by any application. 
The second possibility deals with 
the case where services come logically grouped together, such that one cannot
exist without the other, even though they may be distributed geographically.
Intermediate schemes exist, where some CORBA services have their own Jini
service, while others are grouped into a single Jini service. For example,
rooms may be grouped into buildings and cannot exist without these buildings,
whereas a client may only want to know about a subset of buildings, say those
in New York.

</para>

<sect3>
<title>
Many fat proxies
</title>
<para>
We can have one Jini server for each of the CORBA servers. The Jini servers 
can be running on the same machines as the CORBA ones, but there is no
necessity from either Jini or the CORBA to do so. On the other hand,
if a client is running as an applet,
then applet security restrictions may force all the Jini servers to
run on a single machine, the same one as an applet's HTTP server.
</para>

<para>
The Jini proxy objects exported by each Jini server may be fat ones, which connect
directly to the CORBA server. Thus each proxy becomes a CORBA client, as was dealt with
in the ``hello world'' example. Within the Jini client, we do not just have
one proxy, but many proxies. Because they are all running within the same address
space, they can share CORBA references - there is no need to package a CORBA
reference as a portable Jini object. 
In addition, the Jini client can just use all of these CORBA references
directly, as instance objects of interfaces.
Diagramatically, this appears in figure <xref linkend="manyfatproxies"/>.
<figure id="manyfatproxies">
<graphic fileref="images/ManyFatProxies.gif" align="center"> </graphic>
<title>CORBA and Jini services for fat proxies</title>
</figure>
</para>

<para>
The CORBA servers are all accessed from within the Jini client. This may rule out
this arrangement if the client is an applet, and the servers are on
different machines.
</para>

</sect3>

<sect3>
<title>
Many thin proxies
</title>
<para>
The proxies exported can be thin, such as RMI stubs. In this case each Jini server
is acting as a CORBA client. This is given in figure <xref linkend="manythinproxies"/>.
<figure id="manythinproxies">
<graphic fileref="images/ManyThinProxies.gif" align="center"> </graphic>
<title>CORBA and Jini services for thin proxies</title>
</figure>
</para>

<para>
If all the Jini servers are collocated on the same machine, then this becomes a
possible architecture suitable for applets. The downside of this approach
is that all the CORBA references are within different JVMs. In order to move
the reference for a meeting from the Jini meeting factory to one of the Jini
rooms, it may be necessary to wrap it in a portable Jini object, as discussed
above. The Jini client will also need to get information about the CORBA objects,
which can be gained from these portable Jini objects.
</para>
</sect3>

<sect3>
<title>
Single fat proxy
</title>
<para>
An alternative to Jini servers for each CORBA server is to have a single Jini server
into the CORBA federation. This can be a feasible alternative when the set of
CORBA objects form a complete system or module, and it makes sense to treat them
as a unit. There are then the choices again of where to locate the CORBA
references, either in the Jini server or in a proxy. Placing them in a fat proxy
is shown in figure <xref linkend="singlefatproxy"/>
<figure id="singlefatproxy">
<graphic fileref="images/SingleFatProxy.gif" align="center"> </graphic>
<title>CORBA and Jini services for single fat proxy</title>
</figure>

</para>
</sect3>

<sect3>
<title>
Single thin proxy
</title>
<para>
Placing all the CORBA references on the server side of a Jini service means that
a Jini client only needs to make one network connection to the service.
This is shown in figure <xref linkend="singlethinproxy"/>.
it is probably the best option from a security viewpoint of a Jini client.
<figure id="singlethinproxy">
<graphic fileref="images/SingleThinProxy.gif" align="center"> </graphic>
<title>CORBA and Jini services for single thin proxy</title>
</figure>

</para>
</sect3>

<!--
 in bringing this set of objects into the Jini world.
One is to
have a Jini service for <emphasis>each</emphasis> CORBA server:

<graphic fileref="images/CorbaMultiple1.gif" align="center"> </graphic>

This approach has advantages if each CORBA service is relatively
stand-alone, where various mixtures of objects could be used by different
clients. It has disadvantages if CORBA objects need to be moved from one
CORBA service to another, using the Jini services as intermediaries.
In that case, the CORBA objects would most likely need to be serialized
into strings (and back again) 
using the <code>ORB</code> methods <code>string_to_object()</code>
and <code>object_to_string()</code>. Such movement would be required in this
case, to get <code>Meeting</code> objects from the factory to a room.
</para>

<para>
The other extreme is to have a single Jini service act as a front-end service
to all of these CORBA objects.

<graphic fileref="images/CorbaMultiple2.gif" align="center"> </graphic>

This has advantages in this case in that it does not need to export CORBA
objects, but can instead export a ``suitable'' reference to them.
</para>

<para>
This single-service technique has disadvantages, though. It requires a comprehensive
interface that will cover any client needs for the CORBA objects. It also needs to
make visible suitable forms of the CORBA objects, like the <code>JavaMeeting</code>
interface above, and keep mapping tables between the CORBA and Jini objects.
</para>
-->

</sect2>

<sect2>
<title id="Exceptions">
Exceptions
</title>
<para>
CORBA methods can throw exceptions of two types: system exceptions and user
exceptions. System exceptions subclass from <code>RuntimeException</code>,
and so are <emphasis>unchecked</emphasis>.
These do not need to have explicit <code>try...catch</code> clauses around them.
If an exception is thrown, it will be caught by the Java runtime, and generally
halt the process with an error message.
This would result in a CORBA client dying, which would generally be undesirable.
Many of these system exceptions will be caused by the distributed
nature of CORBA objects, and probably should be caught explicitly.
If they cannot be handled directly, then to bring them
into line with the Jini world, they can be wrapped as ``nested exceptions'' within
a <code>Remote</code> exception and thrown again.
</para>

<para>
User exceptions are declared in the IDL for the CORBA interfaces and methods.
These exceptions are <emphasis>checked</emphasis>, and need to be explicitly
caught (or re-thrown) by Java methods. If a user exception is thrown, this will
be because of some semantic error within one of the objects, and will be
unrelated to any networking or remote issues. They should be treated as they are,
without wrapping them in <code>Remote</code> exceptions.
</para>

</sect2>

<sect2>
<title id="Interfaces for Single Thin Proxy">
Interfaces for Single Thin Proxy
</title>
<para>
This and the following sections consider issues in building a single thin proxy
for a federation of CORBA objects. 
The Vogel and Duddy book gives a CORBA client to interact with the CORBA federation,
and this is used as the basis for the Jini services and clients.
</para>

<para>
Using a thin proxy means that all CORBA-related
calls will be placed in the service object, and made available to Jini clients
only by means of portable Jini versions of the CORBA objects. These portable
objects are defined by the interfaces
<programlisting>
<?program "corba/common/JavaRoom.java"?>
</programlisting>
and
<programlisting>
<?program "corba/common/JavaMeeting.java"?>
</programlisting>
</para>

<para>
The bridge interface between the CORBA federation and the Jini clients has to
provide methods for making changes to objects within the CORBA federation, and
to obtain information from them. For the room booking system this requires the
ability to book and cancel meetings within rooms, and also the ability to
view the current state of the system. Viewing is accomplished by three methods:
updating the current state, and getting the list of rooms and of bookings
for a room.
<programlisting>
<?program "corba/common/RoomBookingBridge.java"?>
</programlisting>
There is a slight legacy in this that comes from the original ``monoblock'' CORBA client.
In there, because the GUI interface elements and the CORBA references were all
in the one client, simple shareable structures such as arrays of rooms
and arrays of meetings were used. Meetings and rooms could be indentified simply
by their index into the appropriate array. In splitting the client apart
into multiple (and remote) classes this is not
really a good idea anymore as it assumes a commonality of implementation 
across objects which may not occur. It doesn't seem worthwhile being too
fussy about that here, though.
</para>

</sect2>

<sect2>
<title id="RoomBookingBridge Implementation">
RoomBookingBridge Implementation
</title>
<para>
The room booking Jini bridge has to perform all CORBA activities, and to wrap these
up as portable Jini objects. A major part of this is locating the CORBA services,
which here are the meeting factory and all of the rooms. We do not want to get too
involved in these issues here. The meeting factory can be found in essentially
the same way as the hello server was earlier, by looking up its name.
Finding the rooms is harder as these are not known in advance. Essentially, the
equivalent of a ``directory'' has to be set up on the name server, which is
known as a ``naming context''. Rooms are registered within this naming context
by their servers, and the client gets this context and then does a search
for its contents. The Jini component of this object is that it subclasses from
<code>UnicastRemoteObject</code>, and implements a 
<code>RemoteRoomBookingBridge</code> which is a remote version of
<code>RoomBookingBridge</code>. It is also worthwhile noting how CORBA exceptions
are caught and wrapped in <code>Remote</code> exceptions.
<programlisting>
<?program "corba/RoomBookingImpl/RoomBookingBridgeImpl.java"?>
</programlisting>
</para>

</sect2>

<sect2>
<title id="Other Classes">
Other Classes
</title>
<para>
The Java classes and servers implementing the CORBA objects are mainly unchanged from
the implementations given in the Vogel and Duddy book. They can continue to act
as CORBA servers to the original clients. I replaced the ``easy naming'' naming service 
by a later one with the slightly more complex standard mechanism for creating
contexts and placing names within this context. This can use the <code>tnameserv</code>
CORBA naming server, for example.
</para>

<para>
The Vogel and Duddy room booking client was messed around a little bit, but its
essential structure remained unchanged. The GUI elements, for example, were
not altered. All CORBA-related code was removed from the client
and placed into the bridge classes.
</para>

<para>
The Vogel and Duddy code samples can all be downloaded from a public Web site
(<ulink url="http://www.wiley.com/compbooks/vogel">http://www.wiley.com/compbooks/vogel</ulink>),
and come with no author attribution or copyright claim. The client is also
quite lengthy since it has plenty of GUI inside. So I won't complete the
code listing here.
The code for all my classes, and the modified code of the Vogel and Duddy classes,
is given in the subdirectory <code>corba</code> of the <code>programs.zip</code>
file.
</para>
</sect2>

<sect2>
<title id="Building the Example2">
Building the Example
</title>
<para>
The IDL interface <code>RoomBooking.idl</code> needs to be compiled to Java
by a suitable ``IDL to Java'' compiler such as Sun's <code>idltojava</code>.
This produces classes in the package <code>corba.RoomBooking</code>.
These can all be compiled using the standard Java classes and any CORBA classes
needed.
</para>

<para>
The Jini server, service and client are also normal Java files, 
and can be compiled like earlier Jini files, with the classpath
set to include the Jini libraries. 
</para>

</sect2>

<sect2>
<title id="Running the Example2">
Running the Example
</title>
<para>
There are a large number of elements and processes that must be set running to
get this running satisfactorily

<orderedlist>
<listitem>
  A CORBA name server must be set running, as in the earlier problem.
  For example,
<programlisting>
tnameserv -ORBInitialPort 1055
</programlisting>
  All CORBA services and clients should also use this port number
</listitem>
<listitem>
  A CORBA server should be started for each room, with the first parameter being
  the ``name'' of the room, as in
  <programlisting>
java corba.RoomBookingImpl.RoomServer "freds room" -ORBInitialPort 1055
  </programlisting>
</listitem>
<listitem>
  A CORBA server should be started for the meeting factory
  <programlisting>
java corba.RoomBookingImpl.MeetingFactoryServer -ORBInitialPort 1055
  </programlisting>
</listitem>
<listitem>
  Typical Jini support services will need to be running, such as a lookup service,
  the RMI daemon <code>rmid</code>, and HTTP servers to move class definitions
  around
</listitem>
<listitem>
  The Jini service can be started by
  <programlisting>
java corba.RoomBookingImpl.RoomBookingBridgeServer -ORBInitialPort 1055
  </programlisting>
</listitem>
<listitem>
  Finally, the Jini client can be run by
  <programlisting>
java corba.RoomBookingImpl.RoomBookingClientApplication -ORBInitialPort 1055
  </programlisting>
</listitem>

</orderedlist>
</para>

</sect2>

</sect1>

<sect1>
<title id="Migrating a CORBA Client to Jini">
Migrating a CORBA Client to Jini
</title>
<para>
Both of the examples in this chapter started life as pure CORBA systems
written by other authors,
with CORBA objects delivered by servers to a CORBA client. The clients were
both migrated to Jini clients of a Jini service acting as a front-end to CORBA objects, 
in a series of steps. For those in a similar
situation, it may be worthwhile to spell out the steps I went through in doing this
for the room booking problem.
<orderedlist>
<listitem>
  The original client was a single ``monoblock'' client, mixing GUI elements, CORBA
  calls and glue to hold it all together. The first step was to decide on the architectural
  constraint: one Jini service, or many. 
</listitem>
<listitem>
  A single Jini service was chosen (for no other reason than it looked to offer more
  complexities). This implied that all CORBA related calls had to be collected into
  a single object, the <code>RoomBookingBridgeImpl</code>. At this stage, the 
  <code>RoomBookingBridge</code> <emphasis>interface</emphasis> was not defined:
  that came after the implementation was completed (ok, I hang my head in shame,
  but I was trying to adapt existing code rather than starting from scratch).
  At this time, the client was still running as a pure CORBA client - no Jini
  mechanisms had been introduced.
</listitem>
<listitem>
  Once all the CORBA related code was isolated into one class, another architectural
  decision had to be made, as to whether this was to function as a fat or thin proxy.
  The decision to make it thin in this case was again based on interest rather than
  functional reasons.
</listitem>
<listitem>
  The GUI elements left behind in the client needed to access information from the
  CORBA objects. In the thin proxy model, this meant that portable Jini objects
  had to be built to carry information out of the CORBA world. This led to the
  interfaces such as <code>JavaRoom</code> and the implementations as
  <code>JavaRoomImpl</code>. The GUI code in the client had no need to directly
  modify fields in these objects, so they ended up as ``readonly''
  versions of their CORBA sources.
  (If a fat proxy had been used, this step of creating portable Jini objects
  would not have been necessary.)
</listitem>
<listitem>
  The client was modified to use these portable Jini objects, and the 
  <code>RoomBookingBridgeImpl</code> was changed to return these from its methods.
  Again, this was all still done within the CORBA world, and no Jini
  services were yet involved. This looked like a good time to define the
  <code>RoomBookingBridge</code> interface, when everything had settled down.
</listitem>
<listitem>
  Finally, the <code>RoomBookingBridgeImpl</code> was turned into a 
  <code>UnicastRemoteObject</code> and placed into a Jini server.
  The client was changed to <emphasis>lookup</emphasis> a <code>RoomBookingBridge</code>
  service rather than <emphasis>create</emphasis> a <code>RoomBookingBridgeImpl</code> object.
</listitem>
</orderedlist>
</para>

<para>
At the end of this, I had an implementation of a Jini service, with a thin RMI
proxy. The CORBA objects and servers had not been changed at all. The original
CORBA client had been split into two, with the Jini service implementing all
of the CORBA lookups. These were exposed to the client through a set of
``facades'' that gave it the information it needed.
</para>

<para>
The client was still responsible for all of the GUI aspects, and so was acting
as a ``knowledgeable'' client. If needed, these GUI elements could be placed
into <code>Entry</code> objects, and also exported as part of the service.
</para>

</sect1>

<sect1>
<title id="Jini Service as a CORBA Object">
Jini Service as a CORBA Service
</title>
<para>
We have looked at making CORBA objects into Jini services. Is it possible to go
the other way, and make a Jini service appear as a CORBA object in a CORBA
federation? Well, it should be. Just as there is a mapping from CORBA IDL to
Java, there is also a mapping of a suitable subset of Java into CORBA IDL.
So a Jini service interface can be written as a CORBA interface. A Jini client
could then be written as the implementation of a CORBA serve to this IDL.
</para>

<para>
At present, with a paucity of Jini services, it does not seem worthwhile yet
to explore this in detail. This may change in the future, though.
</para>

</sect1>

<sect1>
<title id="Summary">
Summary
</title>
<para>
CORBA is a separate distributed system to Jini. However, it is quite straightforward
to build bridges between the two systems, and there are a number of different possible
architectures. This makes it possible for CORBA services to be used by Jini clients.
</para>

</sect1>


&copyright;
</chapter>
