SDSU CS 596: Client-Server Programming
Spring Semester, 1997
Doc 32, Corba

To Lecture Notes Index
San Diego State University -- This page last updated May 8, 1997

Contents of Doc 32, Corba


Corba slide # 1
...Orb Structure slide # 3
...Orb Vendors slide # 4
...Interface Definition Language slide # 6
......Data Types slide # 7
......Attributes and Operations slide # 9
......Inheritance slide # 12
......Name Scopes slide # 12
...A Simple Example slide # 13
...The Tie Mechanism slide # 21
...The CORBA Module slide # 27
......Object slide # 27
......ORB slide # 28
......BOA slide # 28
...CORBA Services slide # 29

References
Object Management Group (OMG) http://www.omg.org

Client/Server Programming with Java and CORBA, Orfali and Harkey, John Wiley & Sons, Inc., 1997

Java Programming with CORBA, Vogel and Duddy, John Wiley & Sons, Inc., 1997

Note much of the material in this lecture follows very closely the material from the two texts listed above.


Doc 32, Corba Slide # 1

Corba

Common Object Request Broker Architecture

CORBA provides peer-to-peer distributed computing between objects

Client - the role of making a request of some other object in the distributed program

Server - the role of providing an implementation of a object that a client uses

Client and server roles can be found in the same program



Transparencies

Location transparency - A remote object appears the same as a local object

An Object Request Broker (ORB) is used to locate objects

Language transparency - remote object do not have to be implemented in the same language (Java, C++, Smalltalk) as local objects

An Interface Definition Language (IDL) is used to define the interface to each object in a language independent way

Doc 32, Corba Slide # 2

Client-Server Interaction




Doc 32, Corba Slide # 3

Orb Structure

Dynamic Invocation Interface (DII) A way to call remote methods with out IDL stubs.

IDL Stubs/Skeleton - client/server code generated to allow static invocation of remote object methods

ORB Interface - Offers various services to clients and servers

Object Adapter - Adapter interfaces for different implementations of ORB Core. The Basic Object Adapter (BOA) is currently the only adapter, but others are possible


Doc 32, Corba Slide # 4

Orb Vendors


Sun - Joe and NEO

NEO includes a NEO ORB, connections to databases, OLE Window applications, development tools, administration tools

Joe is 100% Java ORB from Sun

Joe 1.0 and NEO 1.0 used NEO ORB and Door protocols to communicate

Joe 2.0 and Neo 2.0 also support IIOP (Internet Inter-ORB Protocol)

IIOP is part of CORBA 2.0 to insure that different vender ORBs can talk to each other

Joe 1.0 can be down loaded for free at: http://www.sun.com/sunsoft/neo/joe/index.html

Iona - Orbix

OrbixWeb V2 is lightweight ORB that can be shipped over the internet

Orbix is the leading CORBA vender


Doc 32, Corba Slide # 5

Visigenic - Visibroker (Black Widow)

VisiBroker for Java does both Client and Server side objects

Will be part of Netscape browsers and servers

It is available for a 30 day free trial at:

http://www.visigenic.com/


A list of Free ORBs

See http://adams.patriot.net/~tvalesky/freecorba.html for a list of free ORBs


Doc 32, Corba Slide # 6

Interface Definition Language (IDL)

Corba objects are defined by an IDL but implemented with an existing programming language

The mapping (binding) from IDL to the language needs to be specified

Currently the bindings are specified by OMG for C, C++, Ada, Smalltalk, Cobol

The IDL to Java bindings were to be finalized March 1997

OMG is working on a Java to IDL bindings (Due end of 1997)


Several companies have systems that perform Java to IDL bindings, this provides RMI development

Develop Java code (with some restrictions) and automatically convert to Corba


Doc 32, Corba Slide # 7
Corba IDL Types

Data Types


Basic Types
TypeDescription
(unsigned) short16-bit integer
(unsigned) long32-bit integer
float16-bit IEEE float
double32-bit IEEE float
charISO Latin-1 character
booleanboolean type (TRUE, FALSE)
stringvariable length string
octet8-bit uninterpreted type
enumenumerated type with named integer values
anycan be any type


Doc 32, Corba Slide # 8
Constructed Types

Structure
- record with named members

struct struct_type_name {
     type1     member_name1;
     type2     member_name2;
};

struct studentRecord {
     string     name;
     float          gradePoint;
     boolean     isGraduateStudent;
}
     

Discriminated Union - a type that takes on one of several possible types depending on a discriminator of scalar types

union union_type_name switch(discriminator_type) {
     case value1: type1 member_name1;
     case value2: type2 member_name2;
     default : type3 member_name3;
}

Array - indexed list of fixed length

typedef array_type_name1 member_type1(20);
typedef array_type_name2 member_type2(10)(31);

typedef classList studentRecord(25);

Doc 32, Corba Slide # 9
Sequence - indexed list of variable length which can have an upperbound

typedef bounded_type_name sequence <memberType, 20>
typedef unbounded_type_name sequence <memberType2>

Exception

exception exception_name{
     type1 member_name1;
     type2 member_name2;
};

Attributes and Operations


Actions that can be requested of a Corba object

Attribute - way to specify pair of operations to get/set a value

readonly attributes are get only

attribute type message_name;
readonly attribute type message_name;

Example -
attribute long sum;

translates to (methods in an interface):

     public void sum(int sum) throws CORBA.SystemException;
     public int sum() throws CORBA.SystemException;

The name of the method depends on the language
Doc 32, Corba Slide # 10
Operation - have name, a return type, a list of parameters, a raises clause, and a context clause

interface TheaterBooking {
     enum seating_section {floor, gallery, balcony, noseBleed};
     struct date {
          short day;
          short month;
     };

     exception no_seats {
          sequence <seating_section> seats_still_available_in;
     };

     exception no_performance { };

     typedef short reservation_code;

     reservation_code make_booking(
          in date performance,
          in seating_section position,
          out float price)
     raises (no_performance, no_seats)
     context( ROW_PREF );
};

raises - list exceptions

context - a list of string names, which if exist on client end are sent to the server


Doc 32, Corba Slide # 11
Parameters types
in - argument is passed from client to server
out - argument is returned from server to client
inout - in and out, can be changed by server

Issue 1

The server and client are in different name spaces (machines)

in parameters must be sent from client to server

If the parameter is an object, it and all its data members must be sent

Issue 2

Java does not directly support out or inout parameters!

Solution is to wrap the parameters in an object

The wrapper objects are passed back and forth


Doc 32, Corba Slide # 12

Inheritance


Corba's IDL has multiple inheritance

But the IDL only defines the interface, so this maps to Java interfaces

interface TheaterService : TheaterBooking {

     readonly attribute date next_performance;

     short number_free(
          in date performace,
          in seating_section position)
     raises (no_perfromance)
}

Name Scopes


modules define a name scope, like Java's package

module Botony {
     interface Leaf {
          readonly attribute float size;
          void grow( in float amoutOfSun);
}

module SearchTree {
     interface Leaf {
          attribute any value;
}

::SearchTree::Leaf
::Botony::Leaf

Doc 32, Corba Slide # 13

A Simple Example

Using Visigenic's Visibroker

Will implement a simple counter object

It keeps a count which can be increased and accessed

This example is from Client/Server Programming with Java and CORBA


Step 1) Create and Compile an IDL file

// count.idl file

module Counter
{
  interface Count
  { attribute long sum;
    long increment();
  };
}; 

Unixprompt-> idl2java -T count.idl -no_comments
Creating: Counter
Creating: Counter/Count.java
Creating: Counter/Count_var.java
Creating: Counter/_st_Count.java
Creating: Counter/_sk_Count.java
Creating: Counter/CountOperations.java
Creating: Counter/_tie_Count.java
Creating: Counter/_example_Count.java


Doc 32, Corba Slide # 14
What is all this stuff?

Counter/Count.java

A Java interface for the Counter example

package Counter;
public interface Count extends CORBA.Object {
  public void sum(int sum) throws CORBA.SystemException;
  public int sum() throws CORBA.SystemException;
  public int increment() throws CORBA.SystemException;
}


Doc 32, Corba Slide # 15
_st_Count.java, _sk_Count.java

The stub (client) and skeleton (server) code

package Counter;
public class _st_Count extends pomoco.CORBA.Stub implements Counter.Count {
  public _st_Count() {
  }
  public String[] _getRepIds() {
    return _repIds;
  }
  static {
    pomoco.CORBA.Global.addMapping(
      "IDL:Counter/Count:1.0",
      "Counter::Count",
      new Counter._st_Count().getClass()
    );
  }
  public static String[] _repIds = {
    "IDL:Counter/Count:1.0"
  };
  public int increment() throws CORBA.SystemException {
    CORBA.IOStream _stream = this._create_request("increment", true);
    _invoke(_stream, true);
    int _result;
    _result = _stream.read_int();
    return _result;
  }
  public void sum(int sum) throws CORBA.SystemException {
    CORBA.IOStream _stream = this._create_request("_set_sum", true);
    _stream.write_int(sum);
    _invoke(_stream, true);
  }
  public int sum() throws CORBA.SystemException {
    CORBA.IOStream _stream = this._create_request("_get_sum", true);
    _invoke(_stream, true);
    int _result;
    _result = _stream.read_int();
    return _result;
  }
}


Doc 32, Corba Slide # 16

_example_Count.java
An example skeleton for the Count object

package Counter;
public class _example_Count extends Counter._sk_Count {
  public _example_Count(java.lang.String name) {
    super(name);
  }
  public _example_Count() {
    super();
  }
  public int increment() throws CORBA.SystemException {
    // implement operation...
  }
  public void sum(int sum) throws CORBA.SystemException {
    // implement attribute writer...
  }
  public int sum() throws CORBA.SystemException {
    // implement attribute reader...
  }
}

Doc 32, Corba Slide # 17
Step 2) Implement the Counter, Server, and Client

package Counter;
// CountImpl.java: The Count Implementation
class CountImpl extends Counter._sk_Count implements
Counter.Count
{
  private int sum;

  // Constructor
  CountImpl(String name)
  { super(name);
    System.out.println("Count Object Created");
    sum = 0;
  }
  // get sum
  public  int sum() throws CORBA.SystemException
  { return sum;
  }

  // set sum
  public  void sum(int val) throws CORBA.SystemException
  { sum = val;
  }

  // increment method
  public int increment() throws CORBA.SystemException
  { sum++;
    return sum;
  }
}



Doc 32, Corba Slide # 18
Implement a Server

package Counter;
// CountServer.java: The Count Server main program

class CountServer
{ static public void main(String[] args)
  { try
    { // Initialize the ORB.
      CORBA.ORB orb = CORBA.ORB.init();

      // Initialize the basic object adapter (BOA).
      CORBA.BOA boa = orb.BOA_init();

      // Create the Count object.
      CountImpl count = new CountImpl("My Count");

      // Export to the ORB newly created object.
      boa.obj_is_ready(count);

      // Ready to service requests.
      boa.impl_is_ready();
      }
      catch(CORBA.SystemException e)
      { System.err.println(e);
      }
   }
}

Doc 32, Corba Slide # 19
Implement a Client

package Counter;
// CountClient.java  Static Client, VisiBroker for Java

class CountClient
{ public static void main(String args[])
  { try
    { // Initialize the ORB
     CORBA.ORB orb = CORBA.ORB.init();

      // Bind to the Count Object
     Count counter =Count_var.bind("My Count");

      // Set sum to initial value of 0
     counter.sum((int)0);

     System.out.println("Incrementing");
      for (int i = 0 ; i < 1000 ; i++ )
      { counter.increment();
      }

     System.out.println("Sum = " + counter.sum());
    } catch(CORBA.SystemException e)
    { System.err.println("System Exception");
      System.err.println(e);
    }
  }
}


Doc 32, Corba Slide # 20
Step 3) Running the System

a) Compile client, server, and Count classes with javac

b) Make sure the ORB is running:

     UnixPrompt-> osagent &

c) Run the server

     java Counter.CountServer

d) Run the client

     java Counter.CountClient


Doc 32, Corba Slide # 21
Not So Fast Buster - What if
my Implementation needs to inherit other classes?


package Counter;
// CountImpl.java: The Count Implementation
class CountImpl extends Counter._sk_Count implements
Counter.Count

package Counter;
public interface Count extends CORBA.Object {

There are time when one Java object may need to implement multiple IDL interfaces

The above method would require it to inherit multiple _sk_ classes

The Tie Mechanism

(Adam -Which Pattern is this?)

The Tie mechanism uses composition (delegation)

We use the CountOperations interface:

package Counter;
public interface CountOperations {
  public int increment() throws CORBA.SystemException;
  public void sum(int sum) throws CORBA.SystemException;
  public int sum() throws CORBA.SystemException;
}


Doc 32, Corba Slide # 22
A New Implementation

package Counter;
// CountImpl.java: The Count Implementation
class CountImpl  implements Counter.CountOperations
{
  private int sum;

  // Constructor
  CountImpl()
  {
    System.out.println("Count Object Created");
    sum = 0;
  }
  // get sum
  public  int sum() throws CORBA.SystemException
  { return sum;
  }

  // set sum
  public  void sum(int val) throws CORBA.SystemException
  { sum = val;
  }

  // increment method
  public int increment() throws CORBA.SystemException
  { sum++;
    return sum;
  }
}


Doc 32, Corba Slide # 23
The Tie class does the Communications
(Mary - help Adam out)

package Counter;
public class _tie_Count extends Counter._sk_Count {

  private Counter.CountOperations _delegate;

  public _tie_Count(Counter.CountOperations delegate,
                          java.lang.String name) {
    super(name);
    this._delegate = delegate;
  }

  public _tie_Count(Counter.CountOperations delegate) {
    this._delegate = delegate;
  }

  public int increment() throws CORBA.SystemException {
    return this._delegate.increment(  );
  }

  public void sum(int sum) throws CORBA.SystemException {
    this._delegate.sum(sum);
  }

  public int sum() throws CORBA.SystemException {
    return this._delegate.sum();
  }
}


Doc 32, Corba Slide # 24
Now the new Server

package Counter;
// CountServer.java: The Count Server main program

class CountServer
{ static public void main(String[] args)
  { try
    { // Initialize the ORB.
      CORBA.ORB orb = CORBA.ORB.init();

      // Initialize the BOA.
      CORBA.BOA boa = orb.BOA_init();

      // Create the Count object.
      CountImpl count = new CountImpl();

      // Create the tie object
      _tie_Count count_Pseudo_Impl = new _tie_Count("My Count");

      // Export to the ORB newly created object.
      boa.obj_is_ready(count_Pseudo_Impl);

      // Ready to service requests.
      boa.impl_is_ready();
      }
      catch(CORBA.SystemException e)
      { System.err.println(e);
      }
   }
}

Doc 32, Corba Slide # 25
The Client does not change
(Andy - Don't be smug, more patterns next week)

Note the client does not use the class CountImpl

package Counter;
// CountClient.java  Static Client, VisiBroker for Java

class CountClient
{ public static void main(String args[])
  { try
    { // Initialize the ORB
     CORBA.ORB orb = CORBA.ORB.init();

      // Bind to the Count Object
     Count counter =Count_var.bind("My Count");

      // Set sum to initial value of 0
     counter.sum((int)0);

     System.out.println("Incrementing");
      for (int i = 0 ; i < 1000 ; i++ )
      { counter.increment();
      }

     System.out.println("Sum = " + counter.sum());
    } catch(CORBA.SystemException e)
    { System.err.println("System Exception");
      System.err.println(e);
    }
  }
}

Doc 32, Corba Slide # 26
The class Count_var

package Counter;
public class Count_var {
  public Counter.Count value;

  public static Counter.Count narrow(CORBA.Object object) throws CORBA.SystemException {
    if(object == null) {
      return null;
    }
    return (Counter.Count) object._toType(Counter._st_Count._repIds[0]);
  }

  public static Counter.Count bind() throws CORBA.SystemException {
    return (Counter.Count) pomoco.CORBA.ORB.instance().locate(Counter._st_Count._repIds[0], null,
null, null);
  }

  public static Counter.Count bind(String name) throws CORBA.SystemException {
    return (Counter.Count) pomoco.CORBA.ORB.instance().locate(Counter._st_Count._repIds[0], name,
null, null);
  }

  public static Counter.Count bind(String name, java.lang.String host) throws CORBA.SystemException {
    return (Counter.Count) pomoco.CORBA.ORB.instance().locate(Counter._st_Count._repIds[0], name,
host, null);
  }

  public static Counter.Count bind(java.lang.String name, java.lang.String host, CORBA.BindOptions
options) throws CORBA.SystemException {
    return (Counter.Count) pomoco.CORBA.ORB.instance().locate(Counter._st_Count._repIds[0], name,
host, options);
  }

  public static CORBA.Any any(Counter.Count object) throws CORBA.SystemException {
    return new CORBA.Any().from_Object(object);
  }

  public static Counter.Count any(CORBA.Any any) throws CORBA.SystemException {
    return Counter.Count_var.narrow(any.to_Object());
  }

  public static CORBA.TypeCode type() throws CORBA.SystemException {
    if(_type == null) {
      _type = CORBA.ORB.init().create_interface_tc(Counter._st_Count._repIds[0], "Count");
     }
     return _type;
  }

  private static CORBA.TypeCode _type;
}


Doc 32, Corba Slide # 27

The CORBA Module


The CORBA module defines various interfaces:

Object
ORB
BOA
Interface Repository

Some commonly used methods in these interfaces

Object


Object duplicate();

void release();

Used to remove a reference to an Object
Other clients may be using this object

boolean is_nil();

InterfaceDef get_interface();

When you get a reference to a type Object, this allows you to find out about the object

InterfaceDef is specified in the Interface Repository

Doc 32, Corba Slide # 28

ORB


BOA_init( inout arg_list argv, in OAid oa_identifier);

Allows the BOA access to command line arguments and select the correct object adapter

string object_to_string( in Object obj );
Object string_to_Object( in string str);

Corba's toString and fromString operations

BOA


impl_is_ready()

Tells BOA that this server is ready to receive requests
deactive_impl()

Tells BOA that this server is nolonger ready to receive requests

obj_is_ready()

Registers object with BOA to be a remote object
deactive_obj()

Unregisters object with BOA to be a remote object

Doc 32, Corba Slide # 29

CORBA Services


Life Cycle Service
Operations for creating, copying, moving objects

Persistence Service
A single interface for storing objects in databases and files

Naming Service
Allows objects to be accessed by name

Objects can be bound to existing naming context including ISO X.500, OSF DCE, Sun's NIS+, Novell's NDS and Internet's LDAP

Event Service
Objects can dynamically register/unregister interest in events

Concurrency Service
Provides locks for transactions and threads

Transaction Service
Two-phase commit process for transactions

Relationship Service
Create dynamic associations between objects that know nothing about each other

Externalization Service
Standard way to get data in/out of objects using stream-like mechanism

Doc 32, Corba Slide # 30

Query Service
A superset of SQL, based on SQL3 and Object Query Language (OQL)

Licensing Service
Allows for charging for use of objects

Properties Service
Associate properties with objects

Time Service
Synchronization in distributed environment
Handles time-triggered events

Security Service
Authentication, access control, confidentiality, etc.

Trader Service
Yellow pages for objects
Objects can publicize services, bid for jobs

Collection Service
Supports common collections

Startup Service

Enables requests to automatically run when an ORB is started