CS865 – Distributed Software Development
|
Distributed Objects
|
Message Passing versus
Distributed Objects
·
The
message-passing paradigm is a natural model for
distributed computing, in the sense that it mimics inter-human
communications.
·
It
is an appropriate paradigm for network services where processes interact with
each other through the exchanges of messages.
·
However,
the abstraction provided by this paradigm does not meet the needs of the complexity
of sophisticated network applications.
n
Message passing requires the participating processes
to be tightly-coupled: throughout their interaction,
the processes must be in direct communication with each other.
n
If communication is lost between the processes (due
to failures in the communication link, in the systems, or in one of the
processes), the collaboration fails.
n
The message-passing paradigm is data-oriented.
n
Each message contains data marshalled
in a mutually agreed upon format, and is interpreted as a request or response
according to the protocol.
n
The receiving of each message triggers an action in
the receiving process.
n
It is inadequate for complex applications involving
a large mix of requests and responses.
n
In such an application, the task of interpreting the
messages can become overwhelming.
The distributed object paradigm
n
provides abstractions beyond those of the message-passing model.
n
In
object-oriented programming, objects are used to represent an entity
significant to an application.
n
Each
object encapsulates:
n
the state or data of the entity: in Java, such
data is contained in the instance variables of each object;
n
the operations of the entity, through which the
state of the entity can be accessed or updated.
Local Objects vs. Distributed Objects
n
Local objects are those whose methods can only be
invoked by a local process, a process that runs on the same computer on which the object
exists.
n
A
distributed object is one whose
methods can be invoked by a remote process, a process running on a computer connected via a network to
the computer on which the object exists.
The Distributed Object Paradigm
·
In
a distributed object paradigm, network resources are represented by distributed
objects.
·
To
request service from a network resource, a process invokes one of its
operations or methods, passing data as parameters to the method.
·
The
method is executed on the remote host, and the response is sent back to the
requesting process as a return value.

Message-passing paradigm => data-oriented,
Distributed objects paradigm => action-oriented:
·
the focus is on the invocation of the operations, while the data passed
takes on a secondary role.
·
Although
less intuitive to human-beings, the distributed-object paradigm is more natural
to object-oriented software development.
The Distributed
Objects Paradigm
An
Archetypal Distributed Objects System

Distributed Object System - 1
n
A
distributed object is provided, or exported, by a process, here called the object server.
n
A
facility, here called an object registry, must be present in the system architecture for the
distributed object to be registered.
n
To
access a distributed object, a process –an object client – looks up the object registry for
a reference to the object.
n
This
reference is used by the object client to make calls to the methods.
Distributed Object System - 2
n
Logically,
the object client makes a call directly to a remote method.
n
In
reality, the call is handled by a
software component, called a client proxy, which interacts which
the software on the client host that provides the runtime support for the
distributed object system.
n
The
runtime support is responsible for the interprocess
communication needed to transmit the call to the remote host, including the
marshalling of the argument data that needs to be transmitted to the remote
object.
Distributed Object System - 3
n
A
similar architecture is required on the server
side,
n
runtime support for the distributed object system handles the
receiving of messages and the unmarshalling of data,
and forwards the call to a software component called the server proxy.
n
The
server proxy interfaces with the distributed object to invoke the method call
locally, passing in the unmarshalled data for the
arguments.
n
The
method call results in the performance of some tasks on the server host.
n
The
outcome of the execution of the method, including the marshalled
data for the return value, is forwarded by the server proxy to the client
proxy, via the runtime support and network support on both sides.
Distributed Object
Systems/Protocols
The
distributed object paradigm has been widely adopted in distributed
applications, for which a large number of mechanisms based on the paradigm are
available.
Among
the most well known of such mechanisms are:
~ Java Remote Method Invocation
(RMI),
~ the Common Object Request Broker Architecture (CORBA) systems,
~ the Distributed Component Object Model (DCOM),
~ mechanisms that
support the Simple Object Access Protocol (SOAP).
Of
these, the most straightforward is the
Java RMI
From Remote Procedure Call to Remote Method Invocation
Remote Procedure Calls (RPC) - 1
n
Remote
Method Invocation has its origin in a paradigm called Remote Procedure Call
n
Remote
procedure call model:
n
A procedure call is made by one process to
another, with data passed as arguments.
n
Upon
receiving a call:
1. the actions encoded in the procedure
are executed,
2. the caller is notified of the
completion of the call,
3. a return value, if any, is
transmitted from the callee to the caller.

Local Procedure Call and Remote Procedure Call

Remote Procedure Calls (RPC) - 2
n
Since
its introduction in the early 1980s, the Remote Procedure Call model has been
widely in use in network applications.
n
There
are two prevalent APIs for this paradigm.
n
the Open
Network Computing Remote Procedure Call, evolved from the RPC API originated from Sun Microsystems in the early
1980s.
n
The other
well-known API is the Open
Group Distributed Computing Environment (DCE) RPC.
n
Both
APIs provide a tool, rpcgen, for transforming remote procedure
calls to local procedure calls to the stub.
Java Remote Method
Invocation
Remote Method
Invocation
n
Remote
Method Invocation (RMI) is an object-oriented implementation of the Remote
Procedure Call model.
n
It
is an API for Java programs only.
n
Using
RMI, an object server exports a remote object and registers it with a directory
service.
n
The
object provides remote methods, which can be invoked in client programs.
n
Syntactically:
1. A remote object is declared with a remote interface, an
extension of the Java interface.
2. The remote interface is implemented by the object
server.
3. An object client
accesses the object by invoking
the remote methods associated with
the objects using syntax provided for remote method invocations.
The Java RMI
Architecture

Object Registry
n
The
RMI API allows a number of directory services to be used[ for registering a distributed
object.
n
A
simple directory service called the RMI registry, rmiregistry, which is provided with the Java
Software Development Kit
n
The
RMI Registry is a service whose server, when active, runs on the object
server’s host machine, by convention and by default on the TCP port
1099.
The interaction between
the stub and the skeleton
A
time-event diagram describing the interaction between the stub and the
skeleton:

The API for the Java RMI
n
The
Remote Interface
n
The
Server-side Software
n
The Remote
Interface Implementation
n
Stub and
Skeleton Generations
n
The Object
Server
n
The
Client-side Software
The Remote Interface -
1
n
A
Java
interface is a class
that serves as a template for other classes:
n
it contains declarations or signatures of methods[1] whose implementations are to be
supplied by classes that implements the interface.
n
A
java remote
interface is an
interface that inherits from the Java Remote class, which allows
the interface to be implemented using RMI syntax.
n
Other
than the Remote extension and the Remote exception that must be specified with each
method signature, a remote interface has the same syntax as a regular or local
Java interface.
A sample remote interface
// file: SomeInterface.java
// to be
implemented by a Java RMI server class.
import
java.rmi.*
public
interface SomeInterface extends Remote {
// signature of first remote method
public String
someMethod1( )
throws java.rmi.RemoteException;
// signature of second remote method
public int someMethod2( float ) throws java.rmi.RemoteException;
// signature of other remote methods may
follow
} // end interface
|
A sample remote interface - 2
n
The
java.rmi.Remote Exception must be listed in
the throw clause of each method
signature.
n
This
exception is raised when errors occur during the processing of a remote method
call, and the exception is required to be caught in the method caller’s
program.
n
Causes
of such exceptions include exceptions that may occur during interprocess
communications, such as access failures and connection failures, as well as
problems unique to remote method invocations, including errors resulting from
the object, the stub, or the skeleton not being found.
The Server-side
Software
q An object server is an object that provides the
methods of and the interface to a distributed object.
q Each object server must
n
implement each of the remote methods specified in the
interface,
n
register an object which contains the implementation with a
directory service.
q It is recommended that the two parts
be provided as separate classes.
The Remote Interface Implementation
q A class
which implements the remote interface should be provided.
q The
syntax is similar to a class that implements a local interface.
import java.rmi.*;
import java.rmi.server.*;
/**
* This class implements the remote interface
SomeInterface.
*/
public class SomeImpl
extends UnicastRemoteObject
implements SomeInterface {
public SomeImpl()
throws RemoteException {
super( );
}
public String
someMethod1( ) throws RemoteException {
// code to be supplied
}
public int someMethod2( ) throws RemoteException
{
// code to be supplied
}
} // end class
|
UML diagram for the SomeImpl class

Stub and Skeleton Generations
q In RMI, each distributed object
requires a proxy each for the object server and the object client, knowns as the object’s skeleton and stub respectively.
q These proxies are generated from the
implementation of a remote interface using a tool provided with the Java SDK:
the
RMI compiler rmic.
rmic <class name of the remote
interface implementation>
For example:
rmic SomeImpl
q
As
a result of the compilation, two proxy files will be generated, each prefixed
with the implementation class name:
SomeImpl_skel.class
SomeImpl_stub.class.
The stub file for the object
n
The
stub file for the object, as well as the remote interface file, must be shared
with each object client – these file are required for the client program to
compile.
n
A
copy of each file may be provided to the object client by hand.
n
In
addition, the Java RMI has a feature called “stub downloading” which allows a
stub file to be obtained by a client dynamically.
The Object Server
q
The
object
server class is a class
whose code instantiates and exports an object of the remote interface
implementation.
A template for the object server class.
import java.rmi.*;
……
public class SomeServer {
public static void main(String args[])
{
try{
// code for port number value to be
supplied
SomeImpl exportedObj = new SomeImpl();
startRegistry(RMIPortNum);
// register
the object under the name “some”
registryURL = "rmi://localhost:" + portNum
+ "/some";
Naming.rebind(registryURL, exportedObj);
System.out.println("Some Server ready.");
}// end try
} // end main
//
This method starts a RMI registry on the local host,
if it
//
does not already exists at the specified port number.
private static void startRegistry(int RMIPortNum)
throws RemoteException{
try {
Registry registry=
LocateRegistry.getRegistry(RMIPortNum);
registry.list(
);
// The above call will throw an exception
// if the registry does not already
exist
}
catch (RemoteException ex) {
// No valid registry at that port.
System.out.println(
"RMI registry cannot be located
at port " + RMIPortNum);
Registry registry=
LocateRegistry.createRegistry(RMIPortNum);
System.out.println(
"RMI registry created at port
" + RMIPortNum);
}
}
// end startRegistry
|
The Object Server - 3
n
In
our object
server template, the code for exporting an object is as follows:
// register
the object under the name “some”
registryURL = "rmi://localhost:" + portNum + "/some";
Naming.rebind(registryURL, exportedObj);
|
n
The
Naming class provides methods for storing and obtaining
references from the registry.
n
In
particular, the rebind method allow an object reference to be stored in the
registry with a URL in the form of
rmi://<host name>:<port number>/<reference
name>
n
The
rebind method will overwrite any reference in the registry bound
with the given reference name.
n
If
the overwriting is not desirable, there is also a bind method.
n
The
host name should be the name of the server, or simply “localhost”.
n
The
reference name is a name of your choice, and should be unique in the registry.
The RMI Registry
n
A server exports an object
by registering it by a symbolic name with a server known as the RMI registry.
// Create an object of the Interface
SomeInterfacel
obj = new SomeInterface(“Server1”);
// Register
the object; rebind will overwirte existing
// registration by
same name – bind( ) will not.
Naming.rebind(“Server1”, obj);
|
n
A server, called the RMI
Registry, is required to run on the host of the server which exports remote
objects.
n
The RMIRegistry
is a server located at port 1099 by default
n
It can be invoked
dynamically in the server class:
import java.rmi.registry.LocateRegistry;
…
LocateRegistry.createRegistry ( 1099 );…
|
The RMI Registry - 2
n
Alternatively,
an RMI registry can be activated by hand using the rmiregistry utility :
rmiregistry <port
number>
where
the port number is a TCP port number.
n
If
no port number is specified, port number 1099 is assumed.
n
The
registry will run continuously until it is shut down (via CTRL-C, for example)
The Object Server - 5
n
When
an object server is executed, the exporting of the distributed object causes
the server process to begin to listen and wait for clients to connect and
request the service of the object.
n
An
RMI object server is a concurrent server: each request from an object client is
serviced using a separate thread of the server.
n
Note
that if a client process invokes multiple remote method calls, these calls will
be executed concurrently unless provisions are made in the client process to
synchronize the calls.
The Client-side Software - 1
nThe program for the client class is like any other Java
class.
nThe syntax needed for RMI involves
n
locating the RMI Registry in the server host,
and
n
looking up the remote reference for the server object; the
reference can then be cast to the remote interface class and the remote methods
invoked.
The Client-side Software - 2
import java.rmi.*;
….
public class SomeClient
{
public static void main(String args[])
{
try {
String registryURL
=
"rmi://localhost:" + portNum + "/some";
SomeInterface h =
(SomeInterface)Naming.lookup(registryURL);
// invoke
the remote method(s)
String
message = h.method1();
System.out.println(message);
// method2
can be invoked similarly
} // end try
catch (Exception e) {
System.out.println("Exception in SomeClient:
" + e);
}
} //end main
// Definition for
other methods of the class, if any.
}//end class
|
Looking up the remote
object
The lookup method of the Naming
class is used to retrieve the object reference, if any, previously stored in
the registry by the object server. Note
that the retrieved reference must be cast to the remote interface (not its implementation)
class.
String registryURL =
"rmi://localhost:" + portNum
+ "/some";
SomeInterface h =
(SomeInterface)Naming.lookup(registryURL);
|
Invoking the Remote
Method
The remote interface reference can be used to invoke any of the methods in the remote
interface, as in the example:
String
message = h.method1();
System.out.println(message);
n
Note
that the syntax for the invocation of the remote methods is the same as for
local methods.
n
It
is a common mistake to cast the object retrieved from the registry to the
interface implementation class or the server object class .
n
Instead
it should be cast as the interface
class.
Steps for building an
RMI application
Algorithm for
developing the server-side software
1.
Open
a directory for all the files to be generated for this application.
2.
Specify
the remote-server interface in SomeInterface.java. Compile it until
there is no more syntax error.
3.
Implement
the interface in SomeImpl.java
Compile
it until there is no more syntax error.
4.
Use
the RMI compiler rmic to process the
implementation class and generate the stub file and skelton file for the remote object:
rmic SomeImpl
The files generated can be found in the
directory as SomeImpl_Skel.class and SomeImpl_Stub.class.
Steps 3 and 4
must be repeated each time that a change is made to the interface
implementation.
5. Create the
object server program SomeServer.java.
Compile it until there is no more syntax error.
6. Activate the
object server
java SomeServer
Algorithm for
developing the client-side software
1.
Open a directory for all the files to
be generated for this application.
2.
Obtain a copy of the remote interface
class file. Alternatively, obtain a copy
of the source file for the remote interface, and compile it using javac
to generate the interface class file.
3.
Obtain a copy of the stub file for the
implementation of the interface:
SomeImpl_Stub.class.
4.
Develop the client program SomeClient.java,
and compile it to generate the client class.
5.
Activate the client.
java SomeClient
Placement of files for a RMI application

Testing and Debugging
an RMI Application
1) Build a template for a minimal RMI
program.
a) Start with a remote interface with a
single signature, its implementation using a stub, a server program which
exports the object, and a client program which invokes the remote method.
b) Test the template programs on one
host until the remote method can be made successfully.
2) Add one signature at a time to the
interface.
With each addition,
modify the client program to invoke the added method.
3) Fill in the definition of each
remote method, one at a time.
Test and thoroughly debug each newly added method before
proceeding with the next one.
4) After all remote methods have been
thoroughly tested,
develop the client application using an incremental
approach.
With each increment, test and debug the programs.
Comparison of the RMI
and the socket APIs
nThe remote method invocation API is an efficient tool for
building network applications.
nIt can be used in lieu of the socket API in a network
application.
nSome of the tradeoffs between the RMI API and the socket API
are as follows:
n
The socket API
is closely related to the operating system, and hence has less execution
overhead.
n
For applications
which require high performance, this may be a consideration.
n
The RMI API
provides the abstraction which eases the task of software development.
n
Programs
developed with a higher level of abstraction are more comprehensible and hence
easier to debug.
The HelloWorld Sample
Diagrams
for the Hello application

Source files for the Hello application