View
27
Download
0
Category
Preview:
DESCRIPTION
Algorithm Programming 2 89-211 Distributed Programming in Java. Bar-Ilan University 2004-2005 תשס"ה by Moshe Fresko. RMI : Remote Method Invocation. - PowerPoint PPT Presentation
Citation preview
Algorithm Programming 289-211Distributed Programming in Java
Bar-Ilan University תשס"ה 2004-2005
by Moshe Fresko
RMI : Remote Method Invocation RPC : Remote Procedure Call. Intended to call methods
remotely by passing parameters and getting results. The call can be done to programs written in any language and in any environment.
RMI : Allows to write distributed objects in Java, in a simple and direct manner.
Advantageous of RMI: In RPC only certain Data Types can be passed as parameters. In
RMI Parameters and Return Value of a Method call can be Java Objects.
Mobile Behavior: RMI can pass objects between Server and Client, that can be known only to one side.
For security Java’s built in security mechanisms are used. Existing/Legacy System Connections.
JNI: Java’s Native Method Interface JDBC: Java Data Base Connection
Distributed Garbage Collection. RMI is multi-threaded.
RMI RMI applications: Server Application + Client
Application Server: Creates remote objects, makes them accessible,
and waits for the clients to invoke methods Client: Gets remote references, and invokes methods on
them. RMI provide mechanism for Client and Server to
communicate and pass information back and forth.
Distributed Object Application Locate remote objects Communicate with remote object Load class bytecodes for objects that are passed around
Remote Interfaces and Objects
Remote Objects: Objects that have methods that can be called across VMs.
Remote Interface: An interface definition for the methods to be called remotely.
A Remote Interface Extends the interface java.rmi.Remote Each method declares java.rmi.RemoteException in its
throws definition A Remote Object is treated differently from
regular Objects It passes a Stub instead of the real Object
Note: Stub is the “Remote Proxy” Design Pattern of RMI Stub acts as the local representative of the remote
reference A stub implements the same Remote interfaces as the
real Object
Creating Distributed Applications
1. Design and Implement the Components • Define the Remote Interfaces• Implement the Remote objects’ classes• Implement the Clients
2. Compile Sources and Generate Stubs• javac compiler for compiling source files• rmic compiler to create stubs for the remote objects
3. Make classes network accessible• To make remote interfaces, stubs, and other
classes, accessible via a Web Server4. Start the applications
• Running RMI remote object registry, the server, and the client
Designing a Remote Interface
// Compute.javapackage compute ;import java.rmi.* ;public interface Compute extends Remote {
Object executeTask(Task t) throws RemoteException ;}
// Task.javapackage compute ;import java.io.Serializable ;public interface Task extends Serializable {
Object execute() ;}
ClientComputeEngine(Server)Return result
Submit task
Implementing Remote Interface Implementation Class
Declares the Remote Interface Defines the Constructor for the remote
Object Provides implementation for each remote
method of the Interface Remote Object creation and install
Create and install a Security Manager Create one or more instances of Remote
object Register at least one of the Remote objects
with the RMI remote registry
Compute Engine example
package engine ;import java.rmi.* ;import java.rmi.server.* ;import compute.* ;public class ComputeEngine extends UnicastRemoteObject implements
Compute { public ComputeEngine() throws RemoteException { super() ; } public Object executeTask(Task t) { return t.execute() ; } public static void main(String[] args) { if (System.getSecurityManager()==null) System.setSecurityManager(new RMISecurityManager()) ; String name="//host/Compute" ; try { Compute engine = new ComputeEngine() ; Naming.rebind(name,engine) ; System.out.println("ComputeEngine bound") ; } catch (Exception e) { System.err.println("ComputeEngine exception: "+e.getMessage()) ; e.printStackTrace() ; } } }
Declare the Remote Interface
public class ComputeEngine extends UnicastRemoteObject implements Compute
UnicaseRemoteObject Supplies implementation for some Object methods
( equals, hashCode, toString ) Includes constructors and static methods used to
“export” a remote object and so make the remote object available to receive incoming calls from Client
Instead of UnicastRemoteObject java.rmi.activation.Activatable can be used. It can be used to construct remote objects that can execute on demand.
Remote object can be exported explicitly by calling either UnicastRemoteObject.exportObject or Acrivatable.exportObject
Compute Engine Define the Constructor
public ComputeEngine() throws RemoteException
{ super() ; }
Provide implementation for each remote method public Object executeTask(Task t)
{ return t.execute() ; }
Passing Objects in RMI Arguments or Return Values can be almost any
type, including … Primitive Data Types
Passed by Copy Local Objects (if they are Serializable)
Passed by Copy using serialization Changes done will not affect the original Object
Remote Objects Passed by reference. A remote object reference is a
stub, which is a client side proxy that implements the complete set of remote interfaces that the remote object implements.
Only Remote Interface methods are available to the Client.
Changes done will affect the Original Object
Creating a Security Manager Security Manager determines if the Downloaded code
has access to the local file system, or can perform any other privileged operations
If there is no Security Manager, RMI will not download classes for objects received as parameters, return values, or exceptions, from places other than the local class path.
RMISecurityManager enforces a similar security policy as the applets.
if (System.getSecurityManager()==null) { System.setSecurityManager ( new RMISecurityManager() ) ;}
Make the Remote Object Available
Compute engine = new ComputeEngine() ; UnicastRemoteObject ctor exports the newly
created object to the RMI runtime. RMI registry: (Remote object name service)
A particular Remote Object for finding references to Remote Objects.
java.rmi.Naming interface is used as an API for binding, or registering, and looking up remote objects in the registry.
String name=“//host/Compute” ;try { … Naming.rebind(name,engine) ; } catch …
Binding with Naming.rebind()
Naming.rebind(name,engine) : Takes two parameters. First one is a URL-formatted unique name for the object. Second one a reference to the remote object itself.
name=“//host/Compute” host: The Name or IP-address of the Server Machine.
(Default is localhost). It may include a port number. (Default is 1099). For
example: “//host:8080/objectname” A stub for the “engine” object is created in the server. The
Remote Implementation Objects never leave the VM where they are created.
For security reasons, “bind”, “unbind”, “rebind” can be called only to the registry running in the same host. “lookup” can be called from any host.
No thread is needed to keep the Server up, since as long as a remote Object is referenced either by registry or a client, RMI system takes care of keeping it up.
Client Program
Client ProgramComputePi
rmi registry
ClientEngineServer
Nam
ing.
rebi
ndNaming.lookup
comp.execute task
Client: ComputePi
// ComputePi.javapackage client ;import java.rmi.* ;import java.math.* ;import compute.* ;
public class ComputePi { public static void main(String[] args) { if (System.getSecurityManager()==null) System.setSecurityManager(new RMISecurityManager()) ; try { String name="//"+args[0]+"/Compute" ; Compute comp = (Compute) Naming.lookup(name) ; Pi task = new Pi(Integer.parseInt(args[1])) ; BigDecimal pi = (BigDecimal) (comp.executeTask(task)) ; System.out.println(pi) ; } catch (Exception e) { System.err.println("ComputePi exception: "+e.getMessage()) ; e.printStackTrace() ; } } }
Client: Pi
// Pi.java ;package client ;import java.math.* ;import compute.* ;public class Pi implements Task { // Constants used in Pi computation private static final BigDecimal ZERO = BigDecimal.valueOf(0) ; private static final BigDecimal ONE = BigDecimal.valueOf(1) ; private static final BigDecimal FOUR = BigDecimal.valueOf(4) ; // Rounding mode to use during Pi Computation private static final int roundingMode= BigDecimal.ROUND_HALF_EVEN ; private int digits ; // Digits of precision after the decimal Point public Pi(int digits) // Ctor gets the precision { this.digits=digits ; } public Object execute() // Calculates Pi in method of Task interface { return computePi(digits) ; } // Compute the value of Pi // Machin's formula : pi/4 = 4*arctan(1/5)-arctan(1/239) public static BigDecimal computePi(int digits) { int scale = digits+5 ; BigDecimal arctan1_5 = arctan(5,scale) ; BigDecimal arctan1_239 = arctan(239,scale) ; BigDecimal pi = arctan1_5.multiply(FOUR).subtract(arctan1_239).multiply(FOUR) ; return pi.setScale(digits,roundingMode) ; }
// … Continues in the next page
Client: Pi
// Compute the arctan // arctan(x)=x-(x^3)/3+(x^5)/5-(x^7)/7+... public static BigDecimal arctan(int inverseX, int scale) { BigDecimal term ; BigDecimal invX = BigDecimal.valueOf(inverseX) ; BigDecimal invX2 = BigDecimal.valueOf(inverseX*inverseX) ; BigDecimal numer = ONE.divide(invX,scale,roundingMode) ; BigDecimal result = numer ; int i=1 ; do { numer = numer.divide(invX2,scale,roundingMode) ; int denom = 2*i+1 ; term = numer.divide(BigDecimal.valueOf(denom),scale,roundingMode) ; if ((i%2)!=0) result = result.subtract(term) ; else result = result.add(term) ; i++ ; } while (term.compareTo(ZERO)!=0) ; return result ; }}
Compiling the Program We have:
Package or DirectoryFile Names Includescompute Compute.java interfacecompute Task.java interfaceengine ComputeEngine.java server appl.client ComputePi.java client appl.client Pi.java client appl.
Scenario Developer will build a Jar file of Compute and Task
interfaces Developer will write implementation of Compute interface
and put a Service on a machine. Clients will use the Compute and Task interfaces to
develop a task and a Client program that uses this Service
Compiling the Program
Build the JAR Files for Interfaces javac compute\Compute.java
javac compute\Task.javajar cf compute.jar compute\*.class
Note: These compiled files must be put into a public folder that a Web server can access via HTTP-URL protocol
Build the Server Classes javac engine\ComputeEngine.java
rmic –d . engine.ComputeEngine rmic creates files :
ComputeEngine_Stub.classComputeEngine_Skel.class
These files also need to be placed in a Web Server accessible folder.
Compiling the Client javac client\ComputePi.java
javac client\Pi.java The Pi.class must be placed in a Web Server accessible folder.
Running the Program Write a General Policy File for
Connect or accept connections on unprivileged ports on any host (port>1024)
Connect to port 80 (HTTP) File: java.policy
grant { permission java.net.SocketPermission "*:1024-65535", "connect,accept"; permission java.net.SocketPermission "*:80", "connect";};
Start registry on the Server In Command Prompt write: rmiregistry By default it starts on port 1099 It runs in the background, and doesn’t produce any output
Running the Program To run the Server
java –Djava.rmi.server.codebase=file:/E:\Trials\JavaRMI\Count –Djava.rmi.server.hostname=localhost –Djava.security.policy=java.policy engine.ComputeEngine
To run the Client java –Djava.rmi.server.codebase=file:/E:\Trials\
JavaRMI\Count –Djava.security.policy=java.policy client.ComputePi localhost 40
Output: 3.1415926535897932384626433832795028841972
Running the Program
Client’s Host: LocalHost Server’s Host: LocalHost
Web ServerWeb Server
rmi registry
ComputePi ComputeEngine
Com
pute
Engi
ne_S
tub
Com
pute
Task
Pi
ComputeEngine_Stub
Recommended