Module 3
Remote Method Invocation(RMI),
CORBA, IDL, RMI-IIOP & JAR
Thomas Mathew
Assistant Professor
Department of Computer Applications
MACFAST
Remote Method Invocation (RMI)
RMI is an object-oriented Remote Procedure Call (RPC) technique.
It allows us to invoke methods on an object that exists in a
different address space (may exist on the same computer or even
on a different computer connected to the source)
Communication between clients and server in RMI is done using
sockets – therefore message from the client is not a direct method
invocation rather it is a stream of data that must be interpreted by
the server before it can invoke method on the target object.
RMI allows programmers to develop distributed Java programs
with the same syntax and semantics used for non-distributed
programs.
It is used to create a distributed object model that fits the Java
programming language and the local object model concepts which
extends the safety and robustness of the Java architecture to the
distributed computing world.
RMI Components
There are 3 entities in an RMI application, they are:
Server program
Client program
Object registry
Server:
This program creates a remote object to be used for method
invocation which implements a Java RMI interface.
Soon after its creation the object is exported and registered with a
separate application , the “object registry” (or simply registry).
Client:
The client program consults the object registry to get a reference
(handle) to a remote object with a specified name thereby it can
invoke methods on the remote object
All communication (using sockets) between the client and the
server are handled by RMI and is absolutely hidden to the client
and server applications.
RMI Components
Object Registry:
It represents a table of objects.
Each entry of the table maps the object name to its proxy (stub)
The server registers the stub by a name to the object registry – once
registered, it is available for others’ use
Clients can now get a reference (handle) to the remote object
(actually stub) from this registry and can invoke methods on it.
RMI – Basic Steps
The steps involved in creating RMI applications are:
1. Define the remote interface
2. Implement the remote interface
3. Create, export and register a remote object in the server
program
4. Get a reference of the remote object in the client program
5. Compile the Java source files
6. Run the application
RMI – Basic Steps
Defining Remote Interface:
This interface has methods that the server wishes to publish.
The remote must be public and has to extend (either directly or
indirectly) the interface java.rmi.Remote – marker interface with
no methods
The implementation of this interface is just to indicate that its
methods may be invoked remotely and those methods has to
throws java.rmi.RemoteException
Eg.
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
void printMsg() throws RemoteException;
}
RMI – Basic Steps
Implement the remote interface:
Write a concrete class implementing one or more such remote
interfaces which may also contain other interfaces that can be
invoked locally with implementation of all its methods
Callers are not expected to be aware of the underlying
implementation.
Eg.
public class ImplExample implements Hello {
public void printMsg() {
System.out.println("This is an example RMI program");
}
}
RMI – Basic Steps
Implement the server:
import java.rmi.registry.Registry;
The server
import program should implement the remote interface or
java.rmi.registry.LocateRegistry;
extendjava.rmi.RemoteException;
import the implementation class and also it should create a remote
object and
import bind it to the RMIregistry.
java.rmi.server.UnicastRemoteObject;
First itclass
public need to create
Server a remote
extends object by instantiating
ImplExample { the
implementation
public Server() {}class
Next,
publicexport the remote
static void object args[])
main(String using the
{ method exportObject() of
a class
try { named “UnicastRemoteObject” which belongs to the
package java.rmi.server
ImplExample obj = new ImplExample();
Hello stub
Followed = (Hello) UnicastRemoteObject.exportObject(obj,
by accessing RMI registry using the getRegistry() 0);
Registry
method of registry = LocateRegistry.getRegistry();
the “LocateRegistry” class which belongs to the
registry.bind("Hello",
package java.rmi.registry stub);
System.err.println("Server
Finally, bind the remote object ready");
created to the registry using the
} catch
bind() (Exception
method of thee)class
{ named “Registry” – by passing a string
System.err.println("Server
representing the bind name and exception:
the object" + e.toString());
exported, as
e.printStackTrace(); } }}
parameters.
RMI – Basic Steps
Implement the client:
import
A clientjava.rmi.registry.LocateRegistry;
application that fetches this remote object and invokes
import
required java.rmi.registry.Registry;
methods on it.
public class Client
First, create a client{ class from where we intend to invoke the
privateobject.
remote Client() {}
public static void main(String[] args) {
Next, get the RMI registry using the getRegistry() method of the
try {
“LocateRegistry” class which belongs to the package
Registry registry = LocateRegistry.getRegistry(null);
java.rmi.registry
Hello stub = (Hello) registry.lookup("Hello");
Followed by, fetching
stub.printMsg(); //the object from the registry using
System.out.println("Remote the
method
method lookup() of the class Registry that belongs to the package
invoked");
java.rmi.registry – by passing the bind name of stub
Downcast the object which is returned by the lookup() method
which is of(Exception
} catch type remote e) {to intended type specified at beginning
System.err.println("Client
Finally, invoke the required method exception:
using" the
+ e.toString());
obtained remote
objecte.printStackTrace();
}
}
RMI – Basic Steps
Compile:
All source files including interfaces and other subsidiary classes
are compiled using default compiler , javac
Compile the Remote interface, the implementation class, the
server, the client program.
To do this activity we should know two terms:
Stub
Skeleton
Run Application :
First start an object registry using the application – rmiregistry
and then start server followed finally by the starting of the
client program
RMI – Basic Steps – Stub & Skeleton
Stub:
It is an object, acts as a gateway for the client side - all the
outgoing requests are routed through it.
It resides at the client side and represents the remote object.
When the caller invokes method on the stub object, it does the
following tasks:
1. It initiates a connection with remote Virtual Machine
(JVM),
2. It writes and transmits (marshals) the parameters to the
remote Virtual Machine (JVM) – in the standard format
3. It waits for the result
4. It reads (unmarshals) the return value or exception
5. It finally, returns the value to the caller.
The stub knows all information (IP address, port) of the
skeleton.
RMI – Basic Steps – Stub & Skeleton
Skeleton:
The skeleton is an object, acts as a gateway for the server side
object - all the incoming requests are routed through it.
When the skeleton receives the incoming request, it does the
following tasks:
1. It reads the parameter for the remote method
2. It invokes the method on the actual remote object, and
3. It writes and transmits (marshals) the result to the caller.
A Calculator RMI Program
Scenario:
Here a server program creates and exports a simple remote
object (say, calculator) which provides one method.
This method takes two integers as arguments and returns
import java.rmi.*;
their sum.
public
Ainterface Calculator
client program gets extends Remote
a reference to the{ //interface is public
remote object
public int add(intand
(calculator) a, int b) throws
invokes this RemoteException;
method on the remote object to
} calculate the sum of two integers.
Step 1: Write an interface (calculator):
Here, the interface is an abstract description of the methods
that may be invoked on an object supporting that interface.
It is only providing abstract description (signature) of
methods without any implementation - name of a method, its
return type, (number, order and type of) arguments
Any object, whose class implements this interface, is a remote
object whose methods can be invoked from a different JVM.
A Calculator RMI Program
Step 2: Write a class that implements this interface:
This java.rmi.*;
import program publicizes that it have created an object that is
capable
public classofSimpleCalculator
providing a set of important services.
implements Calculator {
public int add(int
Anybody a, int
who are b) {
interested can get these services by calling
System.out.println("Received:
the corresponding methods"on + athis
+ "and"
object+and
b); the necessary
int information
result = a + b;
(name of the method, argument list and return
System.out.println("Sent: " + result);
type) to invoke these methods is given in the interface
return
The result;
implementation is provided in another class and it must
} declare that it implements at least one remote interface.
}
An implementation class extends either java. rmi. server.
UnicastRemoteObject or javax.rmi.PortableRemoteObject class – as
extending is not a good idea (multiple inheritance not
supported) – it is better to export instances of these
implementation classes explicitly – (exportObject() method)
It is possible to define methods not specified in the remote
interface in the implementation class – those methods will be local.
A Calculator RMI Program
Step 3: Writing an RMI Server:
This is a simple Java application program (say, CalculatorServer.
java) containing the main() method
This program does 3 things:
1. Creates an instance of implementation class:
SimpleCalculator calculator = new SimpleCalculator();
2. Exports it so that the object can receive method invocation
from remote client:
• Our object and is not capable of handling method invocation
requests that come from a remote program - it has to be
exported (making it capable of receiving invocations of its methods
from remote clients) – to a proxy object – the skeleton
Calculator stub = (Calculator) UnicastRemoteObject. exportObject
(calculator, 0);
• We have to export the object explicitly using static
exportObject() method of the UnicastRemoteObject (or
PortableRemoteObject) class
A Calculator RMI Program
Step 3: Writing an RMI Server:
• exportObject() method creates and installs a proxy for the
calculator object at the server end passing the calculator
object to the proxy (called Skeleton)
• This proxy (Skeleton) - creates a TCP ServerSocket object
and listens for the incoming connection requests on the TCP
port specified by the second argument.
• Whenever a request for method call (in the packed format)
comes to this skeleton, it unpacks the request to obtain the
method name and arguments to be used for this method
• It then packs (called marshalling) the result and sends it
back to the caller.
3. Registers the object to a registry so that remote client can get
remote reference to this object
• The method exportObject() creates and returns another
proxy(Stub) for this object and uploads to the object registry
A Calculator RMI Program
Step 3: Writing an RMI Server:
• The stub knows the port the skeleton listens on as well as
the IP address of the computer.
• The object registry essentially provides this stub object on
request.
• The exportObject() method also creates and loads class files
for stub at runtime (if one not found) – eliminating rmic
compiler - type of this stub must be Calculator, not the
SimpleCalculator
• name of the stub class is determined by concatenating the
binary name of the remote object’s class with the suffix
"_Stub".
• Object’s server-side proxy (skeleton) is now ready to accept
the incoming method invocation request.
• Object’s stub is also generated and can communicate with
A Calculator RMI Program
Step 3: Writing an RMI Server:
• To
import register the stub generated by exportObject() method
java.rmi.*;
importwith the object registry, a reference to object registry is
java.rmi.registry.*;
importneeded
java.rmi.server.*;
public classclass
• The CalculatorServer {
java.rmi.registry.LocateRegistry can create/use
public an
static void main(String
existing args[]) {rmiregistry application of
registry by running
try { JVM
SimpleCalculator cal ==new
Registry registry SimpleCalculator();
LocateRegistry.getRegistry(); - default port
Calculator stub =
is 1099
(Calculator)UnicastRemoteObject.exportObject(cal,0);
• The stub is registered with this object registry
Registry registry = LocateRegistry.getRegistry();
String String
name =name = "calculator";
"calculator";
registry.rebind(name,
registry.rebind(name, stub);stub);
System.out.println("Calculator server ready...");
• The rebind() method essentially binds a specified stub and a
}catch (Exception
name. e) { e.printStackTrace(); }
}}
A Calculator RMI Program
Step 4: Writing an RMI Client:
• Itjava.rmi.*;
import is the program that invokes add() method on the object
importcreated and exported by the server.
java.rmi.registry.*;
• First
public classfor that it has to obtain
CalculatorClient { a reference to the remote object
public from
staticthe
voidobject registry.args[]) {
main(String
try { Registry registry = LocateRegistry.getRegistry(args[0])
String name
• The = "calculator";
getRegistry() method consults the remote registry
Registry registry
(using = LocateRegistry.getRegistry(args[0]);
socket) and essentially returns a local proxy registry
Calculator cal = (Calculator)registry.lookup(name);
• Once the client gets a reference to the remote registry, it
int x = 4, y = 3;
uses the lookup() method on this registry to get a reference
int result = cal.add(x,y);
to the remote calculator object
System.out.println("Sent: " + x +" and "+y);
String name = "calculator";
System.out.print("Received("+x+"+"+y+"=): " + result);
Calculator cal
}catch (Exception e) ={ e.printStackTrace();
(Calculator)registry.lookup(name);
}
} • Next, we invoke the add() method on the remote object
} int x = 4, y = 3; int result = cal.add(x,y);
A Calculator RMI Program
Step 5: Compiling the programs:
Compiling Server
• Open a terminal and go to the directory which contains the
three files - Calculator.java, SimpleCalculator.java and
CalculatorServer.java.
• Compile using javac *.java
• In turn it generates the class files Calculator.class,
SimpleCalculator.class and CalculatorServer.class
Compiling Client
• Copy & paste Calculator.class from server directory to client
directory followed by generating CalculatorClient.class
A Calculator RMI Program
Step 5: Compiling the programs:
Generating Stub classes:
• Java 5.0 and later releases add support for the dynamic
generation of stub classes at runtime, eliminating the need
to use the Java RMI stub compiler, rmic, to pregenerate stub
classes for remote objects.
Step 6: Running the programs:
• Open a terminal, go to the server directory and type the
following command:
start rmiregistry
• java CalculatorServer
• java CalculatorClient serverIP
RMI – Activation Model
Object Activation:
It is a mechanism to invoke methods on remote objects,
even if they are not in memory by automatically faulting
the object into memory so that it can service method calls.
RMI system does not create an instance unless a method
invocation request comes – lazy activator – no instance of a
remote object is created by the server program in advance
Instead, information about remote object implementation
(its class file name, location from which the class can be
loaded, data to be used on its invocation) is provided to an
application called rmid.
RMI – Activation Model
Object Activation:
rmid is a tool which starts the activation system daemon
that allows objects to be registered and activated in a
virtual machine
A stub of the remote object which is essential for RMI is
obtained from this rmid and bound to the registry so that
clients can get a remote reference from this registry.
When, method invocation request comes, rmid checks the
existences of the underlying object:
If the object does not exist, a new instance is created with
the help of information provided during the registration
procedure and puts it in active state.
The process of transforming a passive object into an active
object is known as Object activation.
RMI – Activation Model
Faulting Remote Reference (FRR)
It is the mechanism through which RMI implements lazy
activation
A stub of a remote object created from rmid contains a faulting
remote reference which consists of:
An activation identifier for the remote object
Transient reference referring to the active remote object
The activation identifier contains enough information for
activating the object
The transient reference is the actual live reference to the active
remote object – initially it will be “null”, says object not active
(passive)
When the first method invocation request comes, faulting
reference checks the live reference > identifies that the object is
in passive state > initiates an activation protocol to make it
active by setting the transient reference to the same
RMI – Activation Model
Activation Protocol:
This protocol specifies how to activate an activable passive
object
It works using 4 components : Faulting Remote Reference,
Activator, Activator Group and the “to be activated “object
Activator:
It creates activation groups and supervises the activation
process.
It keeps a database of all activation identifier information
necessary to activate objects.
It also forwards requests for object activation (along with the
necessary information) to the correct activation group inside a
remote JVM – manages Java virtual machines, and starts it
whenever it requires
RMI – Activation Model
Activation Protocol:
Activation Group:
This component activates the object with the specified
activation information and returns the activated object back to
the activator – and makes it part of the group
As faulting reference calls the activator, it consults the object’s
activation descriptor that has – group identifier for the specified
object with its JVM info, underlying class name of the remote
object, URL path from which its class definition can be loaded
Activator forwards the activation request to the group (if it
already exists) the object belongs else creates a new activation
group and then forwards the activation request to that group
Activation group reads the activation information from the
object’s activation descriptor, loads the class for the object and
instantiates the object using a special two argument constructor
– (ActivationID id, MarshalledObject data) .
RMI – Activation Model
Activation Protocol:
Activation Group:
After activating the object, the activation group passes a
marshalled object reference back to the activator.
The activator now records the live reference and activation
identifier pair and returns the live (active) reference to the
faulting reference and modify the same.
The faulting reference of the stub finally forwards method
invocations via the live reference directly to the remote object.
RMI – Custom Socket
Underlying socket communication used by Java’s default RMI
implementation is not secured - Java Remote Method Protocol
(JRMP)
Java RMI applications can be modified to make remote
invocations over secure SSL connections
Java RMI framework allows to export a remote object
specifying custom socket factories that create sockets of desired
type for underlying network communication.
Java RMI uses java.rmi.server.RMIClientSocketFactory
instance and a java.rmi.server.RMIServerSocketFactory
instance for the same
RMIServerSocketFactory is used to control how incoming
connections are listened for and accepted as well as the type of
sockets to use for incoming connections.
RMIClientSocketFactory may be used to control how
connections are established and type of socket to use
RMI – Custom Socket
import java.rmi.*;
RMI system provides two classes SslRMIClientSocketFactory
import java.rmi.registry.*;
and SslRMIServerSocketFactory (in javax.rmi.ssl package) that
import java.rmi.server.*;
implement RMIClientSocketFactory and
import javax.rmi.ssl.*;
RMIServerSocketFactory over the SSL/TLS protocols
public class SSLCalculatorServer {
respectively.
public static void main(String args[]) {
Follow
try { the procedures related to SSL oriented socket compilation
SimpleCalculator cal = new SimpleCalculator();
Calculator stub =
(Calculator)UnicastRemoteObject.exportObject(cal,0, new
SslRMIClientSocketFactory(), new
SslRMIServerSocketFactory());
Registry registry = LocateRegistry.getRegistry();
String name = "calculator";
registry.rebind(name, stub);
System.out.println("Calculator server ready...");
Distributed Architecture
Here components are presented on different platforms and
several components can cooperate with one another over a
communication network in order to achieve a specific objective
or goal
Information processing is not confined to a single machine
rather it is distributed over several independent computers.
Middleware is an infrastructure that appropriately supports the
development and execution of distributed applications – It acts as
a buffer between the applications and the network.
Distributed > Component based
Several Architectures are there to support distributed
architecture:
Client-Server Architecture
Multi-Tier Architecture (n-tier Architecture)
Broker Architectural Style - communication between registered
servers and clients
Service-Oriented Architecture (SOA)
Component-Based Architecture
Focuses on the decomposition of the design into individual
functional or logical components that represent well-defined
communication interfaces containing methods, events, and
properties.
A software component is a code that implements a set of well-
defined interfaces – manageable, discrete chunk of logic.
Components are not entire applications—they cannot run alone.
Distributed > Component based
Component-Based Architecture
A component encapsulates functionality and behaviors of a
software element into a reusable and self-deployable binary unit
– focus is on component reusability
A component is a software object, intended to interact with other
components, encapsulating certain functionality or a set of
functionalities.
It has an obviously defined interface and conforms to a
recommended behavior common to all components within an
architecture.
A well-defined component architecture supplies the standards
necessary for different vendors to write the components,
component containers, and tools.
The component vendor must publish the contract (or rules) for
calling the component, and the client code must adhere to these
rules.
J2EE - Java 2 Platform, Enterprise Edition
Java’s attempt to provide a platform-independent, portable,
multiuser, secure, and standard enterprise-class platform for
server-side deployments written in the Java language
J2EE specifies the rules of engagement that people must agree on
when writing enterprise software – ultimately vendors implement
them on their J2EE-compliant products – supports cross-platform
development
It is a collection of APIs that can be used to build large scale,
distributed, component based, multi-tier applications and mostly
includes: JavaMail
Java Servlets Java Transaction Service (JTS)
JavaServer Pages (JSP) Java Transaction API (JTA)
Enterprise JavaBeans (EJB) J2EE Connector Architecture
Java Message Service (JMS) CORBA
Java Database Connectivity (JDBC) RMI, RMI -IIOP
Java Naming and Directory Interface (JNDI)
J2EE - Java 2 Platform, Enterprise Edition
Broker Architectural Style
It is a middleware architecture used in distributed computing to
coordinate and enable the communication between registered
servers and clients.
Client and the server do not interact with each other directly -
Object communication takes place through a middleware system
called an Object Request Broker (ORB) – using their respective
proxies
Object Request Broker (ORB)
It is a library that enables low-level communication between
CORBA compliant applications written in different programming
languages.
An Object Request Broker or ORB is a facilitator for objects on the
network to communicate working as intermediaries between
distributed objects.
ORBs are responsible for finding objects to service method calls,
handling parameter passing, and returning results.
Broker Architectural Style
Object Request Broker (ORB)
There are numerous CORBA ORBs available the market – Iona’s
OrbixWeb, Inprise’s VisiBroker, and IBM’s ComponentBroker
Each vendor offers various qualities of service that differentiates
each.
An ORB uses the CORBA Interface Repository to find out how to
locate and communicate with a requested component
Communication between ORBs takes place using a TCP/IP-based
protocol called Internet InterOrb Protocol (IIOP)
CORBA - Common Object Request Broker Architecture
Common Object Request Broker Architecture
The CORBA is specified and controlled by Object Management
Group (OMG), which is a consortium of more than 700 companies
that work together to create standards for object computing.
It is a specification that describes how heterogeneous objects can
interoperate which were created/accessed using virtually any
programming language and also could exist on any platform
CORBA is an ideal platform for code written in different languages
to cooperate also works well with enterprise beans
It entices middle level programming based on component objects
Programmers don’t need to master entire CORBA – they can
concentrate on its variety set of services ; needed for situations
Both in CORBA and Java RMI, clients are unaware of object
implementation details; clients are concerned only with the
interfaces linked with those object implementations
CORBA provides location transparency over its distributed objects
using object references - automatically tracks its implementation(obj)
CORBA - Common Object Request Broker Architecture
Components:
CORBA Object:
It is a virtual entity that does not exist on its own until a client
application refers to that object and requests a method on that
object
The reference to the CORBA object is called an object reference.
The object reference is the only means by which a CORBA object
can be addressed and manipulated
Object References in CORBA:
It is an identifier for a particular object implementation in
CORBA.
It uniquely identifies and tracks the object implementation that it
represents (behind-the-scenes)
ORB vendors use them internally in their ORBs to identify
objects.
CORBA - Common Object Request Broker Architecture
Components:
Object Adapters
When an object is accessed, the object adapter is responsible for
mapping an object reference onto an object implementation
(behind-scenes)
It is responsible for activating (or initializes it into memory)
/deactivating the object so it can service the client request - it
gives clients the illusion that server-side objects are always up
and running
CORBA calls it as Portable Object Adapter (POA) and it defines a
set of common services from which other object adapters can be
derived
Different POA subobjects can have different policies for
activating and deactivating objects also different behaviors
CORBA - Common Object Request Broker Architecture
Components:
Repositories
They are services that stores information and can be queried for – like
databases
Two important repositories:
Interface Repository – is a repository in which interface definitions
are stored permanently
Implementation Repository – stores the code that implements the
logic defined by the interfaces
IDL Interface
It is used to define the interfaces of objects in CORBA
Naming Service:
CORBA Naming Service (or COS Naming) is a CORBA service that
allows us to look up CORBA objects by name – provided by ORB
It is used to identify the locations of objects across the network by a
human-readable string.
CORBA naming service is used by Clients to locate CORBA objects and
Servers to advertise specific CORBA objects
CORBA - Common Object Request Broker Architecture
OMG – IDL
It is a language that CORBA uses to define the interfaces between
clients and the objects they call – language neutral environment
Each object implementation must have corresponding IDL that
defines the interface for that object implementation.
Here we can write our IDL interface once and then define
corresponding object implementations in any language that
CORBA supports
IDL is also platform-neutral, allowing clients and object
implementations to be deployed in different platforms.
It allows us to write a distributed application with the illusion
that it’s all written in one language.
It is only a descriptive language that describes the interfaces to
our objects – can’t be executable
It just maps to specific languages that defines object
implementations (internally) using an IDL compiler
CORBA - Common Object Request Broker Architecture
OMG – IDL
A source file containing interface specifications written in OMG
IDL must have an “.idl” extension.
CORBA - Common Object Request Broker Architecture
OMG – IDL
An interface in IDL look like the following:
module CalculatorApp {
interface Calculator {
long add(in long a, in long b); }; };
A CORBA module is a container for related interfaces and
declarations – similar to package in Java
The IDL compiler translates a module to a package statement in
the Java code – in turn
A CORBA interface is similar to Java interface that describes the
service of an object.
Java IDL – Java can define its IDL interfaces using an API
included in its own packages defined to support CORBA
specifications - org.omg.CORBA, org.omg.CosNaming, org.
omg.PortableServer, org.omg.PortableInterceptor and
org.omg.DynamicAny.
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Basic steps needed to develop a distributed application using Java
IDL are:
1. Write an interface using IDL
2. Mapping IDL interface to Java
3. Implementing the interface
4. Writing the server
5. Writing the client
Consider our Calculator scenario:-
Step 1: Write an interface using IDL:
module CalculatorApp {
interface Calculator {
long add(in long a, in long b); }; };
We can store the file as Calculator.idl
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Step 2: Mapping IDL interface to Java
package CalculatorApp;
Here IDL interface has to be translated to Java code using Java’s
public interface CalculatorOperations
idlj compiler.
{
Thisaddwill
package
int generate
a, int b);a set of Java files based on option(s) passed to
CalculatorApp;
(int
it.
}public interface
// interface Calculator extends CalculatorOperations,
CalculatorOperations (Java Interface)
org.omg.CORBA.Object,
idlj –fall Calculator.idl
org.omg.CORBA.portable.IDLEntity
This generates six files:
{ 1. CalculatorOperations.java
} //
2. interface Calculator (CORBA Interface)
Calculator.java
3. CalculatorPOA.java – server-side skeleton class
4. _CalculatorStub.java – client-side stub
5. CalculatorHelper.java – has narrow() method which casts a
CORBA object reference to its proper type – CORBA streams
6. CalculatorHolder.java – has operations to delegate in/out
IDL parameters to the methods in the Helper class
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Step 3: Implementing the interface
To implement the interface, we write a Java class called a servant
It inherits servant base class - CORBA type-specific interface
between the ORB and the servant :-
It unmarshals incoming request,
invokes servant methods,
marshals results,
instructs the ORB to send the result back to the client ORB.
import CalculatorApp.*;
class SimpleCalculator extends CalculatorPOA {
public int add(int x, int y) {
System.out.println("Received: " + a + " and " + b);
int result = a + b;
System.out.println("Sent: " + result);
return result; }} //Stores as SimpleCalculator.java -Implementation class
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Step 4: Writing the server
Here we create a servant instance and export it to the ORB so
that the other application can invoke methods on the servant
In Java, Object Request Broker (ORB) is represented by
org.omg.CORBA.ORB class - we create an instance of ORB by
calling its static init() method
ORB orb = ORB.init(args, null);
Next we need a Portable Object Adapter (POA) initialized with
reference to the parent “RootPOA” and activating it as associative
POAManager
POA rootpoa = POAHelper. narrow(orb.resolve_initial_references
(“RootPOA"));
rootpoa.the_POAManager().activate();
Now rootpoa is able to start processing requests
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Step 4: Writing the server
We then create an instance of the servant class which performs
the actual operation
SimpleCalculator cal = new SimpleCalculator();
This object has to be registered (activated) with the POA which
results in the creation of an Interoperable Object Reference
(IOR).
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(cal);
Here ref acts as IOR and is used by clients for method
invocation
The server has to bind this IOR to the naming service from
where the client will come to know and get the IOR.
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Binding IOR to NamingService
import org.omg.CosNaming.*;
import
To doorg.omg.CosNaming.NamingContextPackage.*;
this first we need to get the root context instance of the
import org.omg.CORBA.*;
name
import server
org.omg.PortableServer.*;
org.omg.CORBA.Object
public class CalculatorServer {objRef = orb.resolve_initial_references
public static void main(String args[]) {
try{ ("NameService");
Thisorbgeneric
ORB object null);
= ORB.init(args, has to be converted to create a naming
context
POA object
rootpoa of NamingContext type using its corresponding
= POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();
helper class cal = new SimpleCalculator();
SimpleCalculator
NamingContextExt
org.omg.CORBA.Object ncRef = NamingContextExtHelper.
ref = rootpoa.servant_to_reference(cal);
narrow(objRef);
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
Thisname
String is used to register IOR by a specified name as an array of
= "Calculator";
NameComponent
NameComponent path[] = ncRef.to_name( name );
ncRef.rebind(path, ref);
String name = "Calculator";
System.out.println("CalculatorServer ready and waiting ...");
NameComponent path[] = ncRef.to_name( name );
orb.run();
} Registration
catch (Exception of
e) {the IOR completes by calling rebind method
e.printStackTrace();}}}
ncRef.rebind(path, ref); - finally we runs the ORB using orb.run();
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Step 5: Writing the client
Here also we need to create and initialize an instance of ORB:
ORB orb = ORB.init(args, null);
To invoke a method on the remote servant, client first needs to
have an IOR corresponding to that servant
The IOR may be obtained from the naming service by providing
the name of the servant
First we need to get the root context instance of the name server
org.omg.CORBA.Object objRef = orb.resolve_initial_references
("NameService");
This generic object has to be converted to create a naming
context object of NamingContext type using its corresponding
helper class
NamingContextExt ncRef =NamingContextExtHelper.narrow(objRef);
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Step 5: Writing the client
import CalculatorApp.*;
The client
import then obtains the IOR of the calculator servant
org.omg.CosNaming.*;
String
import name = "Calculator";
org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
org.omg.CORBA.Object
public class CalculatorClient { ref = ncRef.resolve_str(name);
public static void main(String args[]) {
This IOR is then converted to our Calculator type using
try{
narrow()
ORB method ofnull);
orb = ORB.init(args, CalculatorHelper
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
Calculator calcncRef
NamingContextExt = CalculatorHelper.narrow(ref);
= NamingContextExtHelper.narrow(objRef);
Nextname
String we =perform the method invocation by utilizing the
"Calculator";
org.omg.CORBA.Object ref = ncRef.resolve_str(name);
obtained instance of the servant class
System.out.println(ref);
int x =2,calc
Calculator y == CalculatorHelper.narrow(ref);
3;
int x =2, y = 3;
int result = calc.add(x,
System.out.println("Sent :" + x +y);
" and " + y);
int result = calc.add(x, y);
System.out.println("Received : " + result);
} catch (Exception e) {
e.printStackTrace();}}}
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Compiling Applications
Create a directory (say server) and place all server-related
files :
Calculator.idl, SimpleCalculator.java and CalculatorServer.java
Compile IDL file:
idlj –fall Calculator.idl
Compile all the server-related files:
javac *.java
Create a directory (client), probably on a different computer
and place all client-related files:
Calculator.idl and CalculatorClient.java
Compile the IDL file:
idlj –fall Calculator.idl
Compile all the client-related files:
javac *.java
CORBA - Common Object Request Broker Architecture
DEVELOPING CORBA APPLICATIONS
Running Application
To run the application, a name service is required.
This name service is used by server to bind reference to the servant
that implementing the interface and also is accessed by client for
method invocation
Java has two applications tnameserv, a transient naming service, and
orbd, - a daemon process containing - Bootstrap Service, a Transient
Naming Service, a Persistent Naming Service, and a Server Manager
We can use either of these to start name service
orbd -ORBInitialPort 6789 or tnameserv -ORBInitialPort 6789
//(default:900)
Start the server:
java CalculatorServer -ORBInitialHost 172.16.4.248 ORBInitialPort 6789
Start client (in another computer):
java CalculatorClient -ORBInitialHost 172.16.4.248 -ORBInitialPort 6789
RMI -IIOP
RMI applications typically use Java Remote Method Protocol
(JRMP) for underlying communication where CORBA has IIOP
For the same java provides RMI-IIOP, that combines the best
features of RMI with the best features of CORBA.
IIOP is a much more robust protocol than JRMP
RMI-IIOP utilizes the Java CORBA Object Request Broker (ORB).
There is no separate IDL or mapping to learn – as entire
programming were written in Java
Java IDL is currently the only ORB that can be used with RMI-IIOP
because it implements both specifications
JNDI has a CORBA Naming Service provider, called the COS
Naming service provider.
The rmic compiler may be used to generate the necessary code for
connecting Java applications to others via IIOP (rmic –iiop)
RMI-IIOP provides interoperability with other CORBA objects
implemented in different languages, provided that all the remote
interfaces are originally defined as Java RMI interfaces.
Java ARchive (JAR)
It is a file that bundles multiple files into a single one
A JAR file usually contains the class files and auxiliary resources.
JAR files use ZIP file format so that we can compress/decompress
files.
JAR files has bundle of files, a set of files can be transferred over
the network using single request/response pair that takes less
time.
We can optionally seal packages stored in JAR files to enforce
version consistency
JAR files can be digitally signed with a special privilege – so that it
allows end users to allow/disallow the privilege by checking the
signature and the author’s digital certificate.
We can extend the functionality to the Java core platform using
JAR files with its packaging for extension features
The tool jar also has command-line options to check the available
options, run the command without any option
Java ARchive (JAR)
Creating a JAR file
To create a JAR file use c option:
jar cf jarFile files(s) ...Here f specifies the output JAR
filename
Eg. jar cf sample.jar d1.java k.class
To see what files are being added, we can optionally use v
option:
jar cvf shapes.jar Point.class Circle.class
We can also specify the name of directories whose contents
are to be packaged:
jar -cvf all.jar shapes/ comp/
We can instruct jar to change the directory temporarily
during execution using -C option:
jar cvf test.jar -C comp HDD.class
To avoid ZIP compression, we can use 0 option:
jar cvf0 Circle.jar Circle.class
Java ARchive (JAR)
Viewing Contents of a JAR file:
The t option is used to list table of contents of a JAR file as
follows:
jar tf jar-file
Eg. jar tf shapes.jar
‘t’ option merely displays the content of a JAR file; it does not
extract the content.
Extracting the Content:
General syntax to extract the contents of a JAR file is:
jar xf jar-file
Eg. jar xvf shapes.jar (v option is used to see the files being
extracted)
A space-separated list of the files - to be extracted from the
archive.
jar -xvf shapes.jar Point.class
Java ARchive (JAR)
Updating a JAR file:
To add more files or to update the content of some files
already in an existing archive, we use ‘u’ option.
jar uvf shapes.jar Rectangle.class
There is no provision to remove a file from a JAR
Manifest File
The content of the JAR looks like this:
META-INF/
META-INF/MANIFEST.MF
Point.class
Circle.class
Rectangle.class
Here there is a special file called “manifest file” that contains
‘meta’ information about the other files that are packaged in
the archive and always has the pathname META-
INF/MANIFEST. MF