Random Generator

 

 

 

Foreword

Resources

Code Listings

Foil Sets

Assignments

Solutions

External Resources

SiteMap

Search

Home

Java-CORBA Applications

The Development Process for writing a CORBA based application comprises of the following steps. These steps that have been outlined are typical of most CORBA applications. But there could be deviations from this general rule.

  1. Define IDL
  2. Generating client stub and server skeleton using IDL compiler
  3. Object implementation (server).
  4. Client implementation
  5. Register Server with an ORB daemon
  6. Run client by contacting an ORB daemon


 
Defining the IDL

IDL is a specialized language for defining interfaces, and this is what facilitates the notion of interacting objects, so central to CORBA. The IDL is the means by which objects tell their potential clients what operations are available and how they should be invoked. The IDL definition defines types of objects, their attributes, the methods they export and the method parameters.,


module cis600 {
  module util {
    exception InvalidOperationException {
      string message;
    };
    interface RandomGen {
      long nextInt(
        in long arg0
      );
      long nextIntInRange(
        in long arg0,
        in long arg1
      )
      raises(
        ::cis600::util::InvalidOperationException
      );
    };
  };
};

   


 
Generating Client Stubs and Server Skeletons

This is usually done by using the idl2java pre-processor. This automatic generation of stubs frees the developer from having to write those stubs, and frees them from the dependencies of a particular ORB implementation. Compile all these java files.


>%idl2java filter.idl


 
Anatomy Of the Files Generated

RandomGen.java : This maps the random.idl to the corresponding Java Interface. RandomGenHelper.java : This provides the bind method, which is used by clients to locate objects of the RandomGen class. This also contains mappings for IDL out parameters. (Java natively supports only in parameters).
RandomGenHolder.java: Support for out and inout parameter passing modes requires the use of additional "holder" classes. These classes are available for all of the basic IDL datatypes in the org.omg.CORBA package and are generated for all named user defined types except those defined by typedefs.
RandomGenOperations.java: This has a list of all the operations that the RandomGen class performs.
_RandomGenImplBase.java: Class which Java implementations extend for actual Object implementatiion.
_st_RandomGen.java: This implements the client-side stub for the RandomGen Object. This is the class which provides for marshalling of functions.
_tie_RandomGen.java


 
Object Implementation Server The ORB uses this information to locate active objects or to request activation of objects on a particular server. This server is primarily responsible for

Initializing the ORB
Create a new instance of the ObjectImpl
Export the newly created object to the ORB
Wait for incoming requests

package cis600.impl;

import java.io.*;
import org.omg.CosNaming.*;


public class randomServer {

  public static void main(String[] args) { 
    try {
      /* Initialize the ORB.*/
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
      
      /* Create the RandomGenerator object. */
      cis600.util.RandomGen _randomGenerator =
	new RandomGenImpl("Randomizer");
      
      /* Export the newly create object. */
      orb.connect(_randomGenerator);
      
      /* Get a reference to the Naming Service */
      org.omg.CORBA.Object nameServiceObj = 
	orb.resolve_initial_references("NameService");       
      if (nameServiceObj == null) {
	System.out.println("Name Service Object = null");
	return;
      }
      
      org.omg.CosNaming.NamingContext nameService =
	org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj);
      if (nameService == null) {
	System.out.println("nameService = null");
	return;
      }
      
      /* Bind the RandomGenerator Object in the Naming Service */
      NameComponent[] randomGeneratorName = 
      { new NameComponent("Utilities", "Randomizer") };
      nameService.rebind(randomGeneratorName, _randomGenerator);
      
      System.out.println( _randomGenerator + " is ready.");
    } catch(Exception e) {
      System.out.println("Exception " + e);
    }     
    
    try {
      Thread.currentThread().join();
    }
    catch(InterruptedException e) {
      System.out.println(e);
    }
  }
}
 


 
The Object Implementation

This is the class that inherits the functionality of both the CORBA and Java object models. The task is basically to implement the RandomGen Interface.


package cis600.impl;

import cis600.util.*;
import java.util.Random;


public class RandomGenImpl extends cis600.util._RandomGenImplBase {
  /** Construct a persistently named object. */
  public RandomGenImpl(java.lang.String name) {
    super(name);
  }

  /** Construct a transient object. */
  public RandomGenImpl() {
    super();
  }

   /**
   * Generates an int value between 1 and the given limit.
   * @param hi The upper bound.
   * @return An integer value.
   * @see java.util.Random#nextInt
   **/
  public int nextInt( int hi ) {
    return ((int) Math.abs(Math.random() * ( hi + 1 )) );
  }

  /**
   * Generates an int value between the given limits.
   * @param lo The lower bound.
   * @param hi The upper bound.
   * @return An integer value.
   * @throws InvalidOperationException Invalid Operation due to limits
   * @see java.util.Random#nextInt
   **/
  public int nextIntInRange( int lo, int hi ) 
       throws InvalidOperationException {
     if ( lo > hi )
       throw new InvalidOperationException("invalid range:"+ lo + " > " + hi );
     return ((int) Math.abs(Math.random() * ( hi - lo + 1 )) ) + lo;
  }
}
 


 
Writing a client to access the ObjectImplementation


The Steps involved are detailed below:

Obtaining the Initial Naming Context: The client obtains a reference to the initial naming context by invoking the org.omg.CORBA.ORB's resolve_initial_references.

     org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(this, null);
     org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService");
     org.omg.CosNaming.NamingContext nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj);

     
Creating the Composite name: Since we are looking for Scheduler, we need to first create the compound name "Utilities", "Randomizer".

     NameComponent[] collabName = 
	     { new NameComponent("Utilities", "Randomizer")};
       
Locate the Object with this Name: Inoke resolve on the NamingContext to obtain the object reference associated with the name created in the earlier step. Since the Name Service returns generic CORBA objects, it is necessary to narrow the generic object to a more derived class.

     cis600.util.RandomGen _randomGen= 
          cis600.util.RandomGenHelper.narrow(nameService.resolve(collabName));
  

Setting up the Demo for your desktop


 
Pre-requisites

A CORBA-compliant Java Object Request Broker.
The CORBA Naming service.
The JDK 1.1.X Virtual Machine.



 
Starting the servers

Starting the Active Object Server, the default port it binds to is 14000 (ports less than 1024 require administrative priveleges).
% osagent

Starting the Gatekeeper which acts as a HTTP-tunneler for Callbacks through firewalls, the default port it runs on is 15000
% gatekeeper


Starting the Naming Service, with the nameContext Root as NJM. To use the Name Service, at least one Naming Factory must be started. The Factory object lives within a server process, and is used to create NamingContext objects. When the default Factory server is started, it creates no NamingContexts. When it is asked to create NamingContexts, all such NamingContext objects created by a given Factory are located within the same process as that Factory.

%java -DORBservices=CosNaming -DSVCnameroot=NJM -DJDKrenameBug com.visigenic.vbroker.services.CosNaming.ExtFactory NJM namingLog

The first step to creating a namespace is starting at least one Factory server. Here we start up a single Factory server process. The Factory will be given the logical name "NJM". In addition, the name of a log file is specified (in this case, the locally created "namingLog" file will be used). This log will contain information allowing the Name Service to be shut down and then reDOWNLOADd upon restart to its state prior to shutdown. Here we have used the idea of connecting Contexts that live within distinct Name Servers, the rootContext in this case is NJM. Now that a Context has been created, we can "publish" an Object's reference within that Context. Anyone can access this published object if they have both:
a reference to the NamingContext in which it is published.
the name within that NamingContext with which the Object's reference was originally bound.



Starting the main Object Server: The ORBservices System Property tells the ORB you wish your program to use the Name Service. The SVCnameroot parameter tells the ORB which root naming context should be returned by resolve_initial_references.. Now that a Context has been created, we can "publish" an Object's reference within that Context. Anyone can access this published object if they have both: a reference to the NamingContext in which it is published. the name within that NamingContext with which the Object's reference was originally bound.
%java -DORBservices=CosNaming -DSVCnameroot=NJM cis600.impl.randomServer



 
Applet-Tags for CORBA Clients.

The HTML file, for the CORBA-client applet. When using Communicator, you have two choices on how to program your applets. You may use the ORB embedded in Communicator (which matches VisiBroker for Java 2.5), or you may download the VisiBroker for Java 3.0 ORB on top of the existing version in Communicator. You should download the VisiBroker for Java 3.0 ORB if you are using features new to VisiBroker 3.0 such as interceptors, event handlers, or SSL.
To use the ORB runtime that comes with Communicator, you must run your servers and the GateKeeper in backward compatibility mode and add the following param tag to your applet tag in your HTML file.

<param name=USE_ORB_LOCATOR value=true>

To use VisiBroker for Java 3.0 instead of Communicator's version of VisiBroker, add the following param tag to your applet tag in your HTML file. No special flags are required for the GateKeeper or servers.

<param name=org.omg.CORBA.ORBClass

value=com.visigenic.vbroker.orb.ORB>

If the WebServer is running on default port 80 and the gatekeeper is running on port 15000, you would need to add the following tag.

<param name=ORBgatekeeperIOR value=http://osprey7.npac.syr.edu:15000/gatekeeper.ior>


<applet codebase="..\" 
       code=cis600.client.ClientApplet.class width=400 height=350>
<param name=org.omg.CORBA.ORBClass
       value=com.visigenic.vbroker.orb.ORB>
<param name=ORBservices value=CosNaming>
<param name=ORBgatekeeperIOR
       value=http://osprey7.npac.syr.edu:15000/gatekeeper.ior>
<param name=SVCnameroot value=NJM>
</applet> 
  



 
The Applets. In this context we examine two applet written to access the same Object server

Calculate a Random Number
This applet generates a random number within the range provided by lowerRange and Higher range. This applet demostrates the distributed exception, built into the RandomGen class we have designed, when the range provided is not acceptable to the Distributed Object viz. lowerRange > higherRange. The Timer Button allows you to calculate the Average Ping Invocation. It generates 1000 invocations to the RandomServer Object residing on osprey7.npac.syr.edu
Plot the values as a Pie-chart and Histogram
This applet generates continous accesses to the remote Object and plots it as a pie-function as well as a histogram.