Sunday, May 30, 2010

Workshop 14 : Java & CORBA


Central to a CORBA system is the Object Request Broker, which implements the request to remote objects.  Language neutrality is achieved through the use of an interface definition language (IDL) - to define the methods an object provides to the ORB.  Language mappings are used to convert the IDL file into language specific class files.  CORBA offers many sophisticated features.


Setting up a CORBA System in Java SDK 1.4
1.             Write the IDL for the objects.
2.             Use IDL compile tool to generate stubs and skeletons.
3.             Write the class that implements the interfaces of the IDL file.
4.             Write a server to connect objects to the ORB; then leave the server running.
5.             Write the client code to access the remote CORBA object via the ORB using a name server to find it.
6.             Invoke the methods using the remote object's stub.


The IDL file for HelloWorld – A Java implementation

module itc594{

struct Person{
string firstName;
string lastName;
short age;
string address;
};

struct Time{
string time;
};

struct Name{
string name;
};

typedef sequence< Person > PersonSeq;

interface HelloWorld{
string sayHello(in string inName);
Time whatsTheTime(in string country);
Person whoAreYou();
PersonSeq whoIsThere();
void addPerson(in Person aPerson);
};
};


IDL compilers are for certain languages.  For example:  Java SDK 1.4 comes with idlj.bat which creates all the CORBA support files necessary.  The IDL types are mapped to their Java equivalents.  For example:  a struct type maps to a java data structure object.  A sequence maps to an array of structs.
Creating the Object Implementation
Two approaches are suggested, either:

1.             Inheritance by extend the POA class; or
2.             Delegation using a TIE mechanism.  This is used when we want the object to extend something else to save our hierarchy tree.


Creating the CORBA server – Connecting objects to the ORB

The steps taken in getting HelloWorldServer up and running are:

Step 1)   Compile the IDL file.
C:\idlj -falltie HelloWorld.idl

Step 2)   Implement HelloWorldOperations.Java and add concrete methods.

Step 3)   Create a server class with a main method:

Make an ORB.
Create an object.
Obtain the root POA.
      Use the HelloWorldPOATie class to delegate to the object implementation.
Add it to the name service.
Keep the ORB running.

The Object Implementation code

A sample of the method implementation for the HelloWorldImpl class.  Note the use of the Person struct from the IDL.  Person becomes a basic object type after IDL compilation.



public Person whoAreYou(){
  return (Person)people.get(0);
}
public Person[] whoIsThere(){
   Person[] peopleArray = new Person[people.size()];
   for(int index =0; index<people.size(); index++){
     peopleArray[index] = (Person) people.get(index);
   }
   return peopleArray;
}
public void addPerson(Person aPerson){
   people.add(aPerson);
}
The server code

try{
  // create the ORB!
  org.omg.CORBA.ORB orb =  org.omg.CORBA.ORB.init(args, null);
  HelloWorldImpl helloWorldImpl = new HelloWorldImpl("Barry White");

  POA rootPOA = POAHelper.
    narrow(orb.resolve_initial_references("RootPOA"));
  rootPOA.the_POAManager().activate();
  HelloWorldPOATie tie = new HelloWorldPOATie(helloWorldImpl, 
  rootPOA);
  HelloWorld helloWorldRef = tie._this(orb);

  // create a nameSpace for the HelloWorld Object
  NamingContext root_context = NamingContextHelper.narrow(
  orb.resolve_initial_references("NameService"));
    
  NameComponent[] helloName1 =
    { new NameComponent( "helloWorld", "" ) };
  root_context.rebind( helloName1, helloWorldRef );
  Thread.currentThread().join();
}
catch (Exception e) {
  e.printStackTrace();
}

The Client Code
try{
  ORB orb = ORB.init(args, null);
  // Resolve the NameService to find the object
  NamingContext nameService = NamingContextHelper
    .narrow(orb.resolve_initial_references("NameService"));
 
  // resolve the Object Reference in Naming
  NameComponent[] helloName = { new NameComponent( "helloWorld", "" ) };
  HelloWorld helloWorldImpl = HelloWorldHelper.
     narrow(nameService.resolve(helloName));

  //call a method on the Stub
  System.out.println(“Say Hello Object: " + helloWorldImpl.sayHello());
}
Catch(Exception e){
  e.printStackTrace();
}

Now to get it all running…and a well-earned rest!

1.             Compile all classes!
2.             Start the Java ORB bootstrap name service
c:\start tnameserv -ORBInitialHost localhost -ORBInitialPort 900
3.             Start the server and tell it where the ORB is running
C:\start java HelloWorldServer -ORBInitialHost localhost
-ORBInitialPort 900
4.             Start the Client and tell it where the ORB is running also
C:\java HelloWorldClient -ORBInitialHost localhost
-ORBInitialPort 900


Workshop 13 : Java Remote Method Invocation


Using RMI in Java uses the Java Virtual Machine (JVM) to share objects through facilities for activating and managing object instances, and is also used with Enterprise Java Beans technology.  RMI allows classes to be downloaded from HTTP servers and can be used as an alternative to CORBA or DCOM.


 
HelloWorld in RMI
Why you would consider doing the Hello World program in RMI or CORBA is almost beyond belief, until you recognise that it is a good way for us to see a sample application.

Table 1:  The HelloWorld application as a Remote Method Invocation.

HelloWorldImpl <>
Implements the methods of the interface
Extends UnicastRemoteObject
HelloWorld <>
The interface is what the Client will see, methods.  Declared here are the ones the client sees
Extends java.rmi.Remote
java.rmi.Remote
Extending this tells the JVM that the object will be available to the RMI mechanism

UnicastRemoteObject
Provides methods that allow an object to be available to incoming calls (export)

The simple steps to exporting a remote object – the server

1.             Compile the interface with the RMIC tool.
2.             Create and bind an object to the rmiregistry


try{
  HelloWorld yoWorld = new HelloWorldImpl();
  Naming.rebind(exportName, yoWorld);
}catch(Exception e){
 e.printStackTrace();
}

3.            Create a client that looks up the object and then invokes its methods.


try {
  String exportName = "//localhost/yoHello";
  HelloWorld world = (HelloWorld) Naming.lookup(exportName);
  System.out.println(world.sayHello("bob smith"));
}catch(Exception e){
  e.printStackTrace();
}

Starting and running HelloWorld on the local machine

1.             Start the rmiregistry
C:\rmiregistry

2.             Start the server
C:\start java -Djava.security.policy=java.policy HelloWorldImpl

3.             Start the client
C:\java -Djava.security.policy=java.policy FindWorld

FindHello.java

import java.rmi.*;
import java.rmi.server.*;
import java.io.*;


public class FindHello{

public static void main(String[] args) {
System.out.println(System.getSecurityManager());
try {
String exportName = "//localhost/yoHello";
HelloWorld world = (HelloWorld)
Naming.lookup(exportName);
System.out.println(world.sayHello("bob smith"));
}catch(Exception e){
e.printStackTrace();
}
}// main
}// class

HelloWorld.java

import java.rmi.*;
public interface HelloWorld extends Remote{
public String sayHello(String yourName) throws RemoteException;

}

HelloWorldImpl.java

import java.rmi.*;
import java.rmi.server.*;
import java.util.Date;

public class HelloWorldImpl extends UnicastRemoteObject
implements HelloWorld{

public HelloWorldImpl() throws RemoteException{
super();
}

public String sayHello(String yourName){
return "Hello "+yourName+" the Time on this machine is "+
new Date().toString();
}

public static void main(String[] args) throws Exception{

System.out.println(System.getSecurityManager());


String exportName = "//localhost/yoHello";
try{
HelloWorld yoWorld = new HelloWorldImpl();
Naming.rebind(exportName, yoWorld);
}catch(Exception e){
e.printStackTrace();
}
}// main


}// class


Java.policy

grant {
    permission java.net.SocketPermission "*:1091",
        "connect,accept";
    permission java.net.SocketPermission "*:80", "connect";
};


Topic 6 : Distributed Objects - RMI & CORBA

Why use distributed objects?  The reason is quite transparent!

Programmers must generally resort to primitive, object-disoriented communication techniques, such as sockets, to build distributed applications. However distributed object technology extends the benefits of object-oriented technology across process and machine boundaries to encompass entire networks. This means that remote objects now appear to programmers as if they were local objects (that is, simple programming-language objects in the same process).  This effect is called location transparency.

A transparency occurs when some mechanism causes an obstacle to disappear. This is a software abstraction that allows programmers to cross a computing boundary without having to be aware of the boundary at all, or without performing an explicit transformation.  The object's programming interface is identical in all cases.

Distributed objects glossary

This topic is full of acronyms so a short glossary of terms may be useful.

Client:  In the world of distributed objects, a slight change is made to the standard client definition for this topic.  A distributed object client can be any computing context that invokes operations on the object (sends it a message, invokes a
method etc.).

CORBA:  An acronym for Common Object Request Broker Architecture, as set by the OMG. See http://www.omg.org.  In the CORBA model, the ORB provides location transparency.

Location transparency:  This occurs when an object's client invokes the object's methods in a natural manner, regardless of where the object resides on the network.

Interface:  The boundary layer that separates a consumer of an object's service (a client) from the supplier of the object's service (an object implementation).

IDL:  Interface Description Language is an abstract interface description
language used to create an IDL file.  This is used to map abstract descriptions and to generate the stubs, skeletons, and servants that are actually used when programming.

OMG:  The Object Management Group is the technical group that defines a lot of specifications for technologies such as CORBA and UML.  At http://www.omg.org 'The Object Management Group (OMG) is an open membership, not-for-profit consortium that produces and maintains computer industry specifications for interoperable enterprise applications.'

ORB:  The Object Request Broker is the central technical component, or foundation, on which the other OMG specifications are built.  An ORB is any mechanism that mediates between an object and one of its clients, on different computers, using some kind of network communication.  The ORB can provide various types of transparency such as programming language transparency, platform transparency and representation transparency.

RMI:  Remote Method Invocation.

RPC:  Remote Procedure Method.

UML:  Unified modelling Language for OO design.

Components and distributed objects

Distributed objects technology raises the level of abstraction for distributed application design and development.  A component is a standardised and interchangeable software module that is executable, has a unique identifier and has a well-known interface.  Components are important in modern software development because complex programs and applications can be constructed for small, previously developed parts.  Component-based design and construction (JavaBeans) provides similar benefits to complex software products.  Component developers can deliver their product as a ready-to-use executable function (CORBA and COM+).  It is important to distinguish the differences between CORBA as an OMG specification for use with Java, Python and C++, and the layered RMI architecture in Java, and ActiveX controls with Microsoft's DCOM.

Developers of a software package simply plug in the component into the existing software.  Interoperability among hardware and software components requires well-defined and widely adopted standards. Software components require similar standards for connections and services.  Components located on different machines running different operating systems requires a standard network protocol.  Recent work in this area is with using XML with SOAP – Simple Object Access Protocol.

ORB programming

ORB programming in Java or Python or C++ etc. all focus on the object's interface.  The interface defines what a client can know about an object and how a client may interact with it.  A neat feature is that low-level details (network protocols, programming language idiosyncrasies, physical data organisation) on one side of the boundary are hidden from the other side.  (So it can be a paradox to describe interfaces as 'hiding' things and providing 'transparencies'.)

As you will see in the Web services notion of contractual agreement later in this course, an interface may also be a contract between an object's client and implementation; and is called a servant.

The servant agrees on the information that will be exchanged in a given operation - a contract to interact between client and object for proper behaviour.  CORBA interfaces may be composed from other interfaces through inheritance.  This is called IDL programming.  The Interface Description Language is used to develop an IDL file that can be used to map abstract descriptions and to generate the stubs, skeletons, and servants that are actually used when programming.  Transformation into equivalent constructs in a concrete programming language is useful; the way in which these transformations are made for a particular language is called a mapping for that language.  IDL language mappings exist for Java, C, C++, Smalltalk, and Python.

In Java language mapping, as an example, a stub takes the form of a Java interface - which is the Java equivalent of the IDL interface from which it was generated.  Stubs are used by clients to invoke operations on target CORBA objects.

Reading the notion of a stub, here is some more information.

Using stubs

Stubs are used by clients to invoke operations on target CORBA objects.  In Java language mapping, a stub takes the form of a Java interface, which is the Java equivalent of the IDL interface from which it was generated.  An instance of the stub type is used indirectly by a client of a remote object (a consumer of the remote object's service) to invoke operations on the object.

A stub is often called a proxy or surrogate, as it is not the CORBA object itself; it is a Java object that represents the CORBA object and is partly responsible for invoking requests made on itself, to the real target object.

As you can see, CORBA applications can be quite involved, expensive and mostly used by large corporations for developing distributed objects applications for small-to-medium enterprises.  The boundaries get fuzzy when a client of one CORBA object may be the server for other objects, and programs are sharing each others' objects in a variety of client/server roles as peers!

Servants

Servants are a CORBA interface (package of code) used to build object implementations.  It is in a concrete programming language that provides the real behaviour of the object type.  A servant is an interface with methods that correspond to the operations in the IDL interface; programmers construct an implementation by deriving a new type from the servant interface, then provide method implementations for the methods inherited from the servant interface.  CORBA determines matching servants and stubs from a common interface mapped to the IDL interface, thereby making certain that a given stub/servant pair have identical interfaces.

Skeletons in the closet?

Skeletons are responsible for unpacking the parameters of the request sent by a stub and delivering them to a servant to implement the CORBA operation.  They are used to delegate CORBA requests to servants.  When the operation is finished, the skeleton must package any results into a reply to send back to the stub.

RMI and CORBA case study:  On the road to distributed systems

Tim Austin discussed Java applications with RMI, CORBA and SOAP, and provided the source code for the HelloWorld RMI and HelloWorld CORBA examples as a case study for this Study Guide.

NOTE:  You can download a copy of the source code used by Tim in this RMI
and CORBA Case Study at:

Why bother with distributed systems?
Provision of a new level of automation across business intranets saves money and allows:

·                distributed users to work with the same application;
·                distributed data sources to be used with the same application; and
·                computation to best be matched with machine resources.
What are distributed component architectures all about?
Distributed Component Architectures are designed to allow many machines to work together to form a distributed application.  The use of components can allow an organisation to wrap existing 'legacy' applications in forming a new application, using object-oriented principals to make the system operate over a network – therefore reaping the benefits of the OO approach.  Like a heavyweight boxing tournament, the contenders are:

·                Common Object Request Broker Architecture (CORBA)
·                Microsoft Distributed Component Object Model (DCOM)
·                Sun's Java Remote Method Invocation (RMI)
·                Simple Object Access Protocol (SOAP) The newest challenger!